Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(453)

Unified Diff: third_party/google-endpoints/google/api/control/metric_value.py

Issue 2666783008: Add google-endpoints to third_party/. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/google-endpoints/google/api/control/metric_value.py
diff --git a/third_party/google-endpoints/google/api/control/metric_value.py b/third_party/google-endpoints/google/api/control/metric_value.py
new file mode 100644
index 0000000000000000000000000000000000000000..8064fc69cfe627505abcd8ec610dcdfe4b3965a5
--- /dev/null
+++ b/third_party/google-endpoints/google/api/control/metric_value.py
@@ -0,0 +1,173 @@
+# Copyright 2016 Google Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""metric values provides funcs using to aggregate `MetricValue`.
+
+:func:`merge` merges two `MetricValue` instances.
+:func:`update_hash` adds a `MetricValue` to a secure hash
+:func:`sign` generates a signature for a `MetricValue` using a secure hash
+
+"""
+
+from __future__ import absolute_import
+
+import hashlib
+import logging
+
+from apitools.base.py import encoding
+
+from . import distribution, money, signing, timestamp, MetricKind
+from google.api.gen.servicecontrol_v1_messages import MetricValue
+
+
+logger = logging.getLogger(__name__)
+
+
+def create(labels=None, **kw):
+ """Constructs a new metric value.
+
+ This acts as an alternate to MetricValue constructor which
+ simplifies specification of labels. Rather than having to create
+ a MetricValue.Labels instance, all that's necessary to specify the
+ required string.
+
+ Args:
+ labels (dict([string, [string]]):
+ **kw: any other valid keyword args valid in the MetricValue constructor
+
+ Returns
+ :class:`MetricValue`: the created instance
+
+ """
+ if labels is not None:
+ kw['labels'] = encoding.PyValueToMessage(MetricValue.LabelsValue,
+ labels)
+ return MetricValue(**kw)
+
+
+def merge(metric_kind, prior, latest):
+ """Merges `prior` and `latest`
+
+ Args:
+ metric_kind (:class:`MetricKind`): indicates the kind of metrics
+ being merged
+ prior (:class:`MetricValue`): an prior instance of the metric
+ latest (:class:`MetricValue`: the latest instance of the metric
+ """
+ prior_type, _ = _detect_value(prior)
+ latest_type, _ = _detect_value(latest)
+ if prior_type != latest_type:
+ logger.warn('Metric values are not compatible: %s, %s',
+ prior, latest)
+ raise ValueError('Incompatible delta metric values')
+ if prior_type is None:
+ logger.warn('Bad metric values, types not known for : %s, %s',
+ prior, latest)
+ raise ValueError('Unsupported delta metric types')
+
+ if metric_kind == MetricKind.DELTA:
+ return _merge_delta_metric(prior, latest)
+ else:
+ return _merge_cumulative_or_gauge_metrics(prior, latest)
+
+
+def update_hash(a_hash, mv):
+ """Adds ``mv`` to ``a_hash``
+
+ Args:
+ a_hash (`Hash`): the secure hash, e.g created by hashlib.md5
+ mv (:class:`MetricValue`): the instance to add to the hash
+
+ """
+ if mv.labels:
+ signing.add_dict_to_hash(a_hash, encoding.MessageToPyValue(mv.labels))
+ money_value = mv.get_assigned_value('moneyValue')
+ if money_value is not None:
+ a_hash.update('\x00')
+ a_hash.update(money_value.currencyCode)
+
+
+def sign(mv):
+ """Obtains a signature for a `MetricValue`
+
+ Args:
+ mv (:class:`google.api.gen.servicecontrol_v1_messages.MetricValue`): a
+ MetricValue that's part of an operation
+
+ Returns:
+ string: a unique signature for that operation
+ """
+ md5 = hashlib.md5()
+ update_hash(md5, mv)
+ return md5.digest()
+
+
+def _merge_cumulative_or_gauge_metrics(prior, latest):
+ if timestamp.compare(prior.endTime, latest.endTime) == -1:
+ return latest
+ else:
+ return prior
+
+
+def _merge_delta_metric(prior, latest):
+ prior_type, prior_value = _detect_value(prior)
+ latest_type, latest_value = _detect_value(latest)
+ _merge_delta_timestamps(prior, latest)
+ updated_value = _combine_delta_values(prior_type, prior_value, latest_value)
+ setattr(latest, latest_type, updated_value)
+ return latest
+
+
+# This is derived from the oneof choices for the MetricValue message's value
+# field in google/api/servicecontrol/v1/metric_value.proto, and should be kept
+# in sync with that
+_METRIC_VALUE_ONEOF_FIELDS = (
+ 'boolValue', 'distributionValue', 'doubleValue', 'int64Value',
+ 'moneyValue', 'stringValue')
+
+
+def _detect_value(metric_value):
+ for f in _METRIC_VALUE_ONEOF_FIELDS:
+ value = metric_value.get_assigned_value(f)
+ if value is not None:
+ return f, value
+ return None, None
+
+
+def _merge_delta_timestamps(prior, latest):
+ # Update the start time and end time in the latest metric value
+ if (prior.startTime and
+ (latest.startTime is None or
+ timestamp.compare(prior.startTime, latest.startTime) == -1)):
+ latest.startTime = prior.startTime
+
+ if (prior.endTime and
+ (latest.endTime is None or timestamp.compare(
+ latest.endTime, prior.endTime) == -1)):
+ latest.endTime = prior.endTime
+
+ return latest
+
+
+def _combine_delta_values(value_type, prior, latest):
+ if value_type in ('int64Value', 'doubleValue'):
+ return prior + latest
+ elif value_type == 'moneyValue':
+ return money.add(prior, latest, allow_overflow=True)
+ elif value_type == 'distributionValue':
+ distribution.merge(prior, latest)
+ return latest
+ else:
+ logger.error('Unmergeable metric type %s', value_type)
+ raise ValueError('Could not merge unmergeable metric type')

Powered by Google App Engine
This is Rietveld 408576698