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

Side by Side 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, 10 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 unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2016 Google Inc. All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 """metric values provides funcs using to aggregate `MetricValue`.
16
17 :func:`merge` merges two `MetricValue` instances.
18 :func:`update_hash` adds a `MetricValue` to a secure hash
19 :func:`sign` generates a signature for a `MetricValue` using a secure hash
20
21 """
22
23 from __future__ import absolute_import
24
25 import hashlib
26 import logging
27
28 from apitools.base.py import encoding
29
30 from . import distribution, money, signing, timestamp, MetricKind
31 from google.api.gen.servicecontrol_v1_messages import MetricValue
32
33
34 logger = logging.getLogger(__name__)
35
36
37 def create(labels=None, **kw):
38 """Constructs a new metric value.
39
40 This acts as an alternate to MetricValue constructor which
41 simplifies specification of labels. Rather than having to create
42 a MetricValue.Labels instance, all that's necessary to specify the
43 required string.
44
45 Args:
46 labels (dict([string, [string]]):
47 **kw: any other valid keyword args valid in the MetricValue constructor
48
49 Returns
50 :class:`MetricValue`: the created instance
51
52 """
53 if labels is not None:
54 kw['labels'] = encoding.PyValueToMessage(MetricValue.LabelsValue,
55 labels)
56 return MetricValue(**kw)
57
58
59 def merge(metric_kind, prior, latest):
60 """Merges `prior` and `latest`
61
62 Args:
63 metric_kind (:class:`MetricKind`): indicates the kind of metrics
64 being merged
65 prior (:class:`MetricValue`): an prior instance of the metric
66 latest (:class:`MetricValue`: the latest instance of the metric
67 """
68 prior_type, _ = _detect_value(prior)
69 latest_type, _ = _detect_value(latest)
70 if prior_type != latest_type:
71 logger.warn('Metric values are not compatible: %s, %s',
72 prior, latest)
73 raise ValueError('Incompatible delta metric values')
74 if prior_type is None:
75 logger.warn('Bad metric values, types not known for : %s, %s',
76 prior, latest)
77 raise ValueError('Unsupported delta metric types')
78
79 if metric_kind == MetricKind.DELTA:
80 return _merge_delta_metric(prior, latest)
81 else:
82 return _merge_cumulative_or_gauge_metrics(prior, latest)
83
84
85 def update_hash(a_hash, mv):
86 """Adds ``mv`` to ``a_hash``
87
88 Args:
89 a_hash (`Hash`): the secure hash, e.g created by hashlib.md5
90 mv (:class:`MetricValue`): the instance to add to the hash
91
92 """
93 if mv.labels:
94 signing.add_dict_to_hash(a_hash, encoding.MessageToPyValue(mv.labels))
95 money_value = mv.get_assigned_value('moneyValue')
96 if money_value is not None:
97 a_hash.update('\x00')
98 a_hash.update(money_value.currencyCode)
99
100
101 def sign(mv):
102 """Obtains a signature for a `MetricValue`
103
104 Args:
105 mv (:class:`google.api.gen.servicecontrol_v1_messages.MetricValue`): a
106 MetricValue that's part of an operation
107
108 Returns:
109 string: a unique signature for that operation
110 """
111 md5 = hashlib.md5()
112 update_hash(md5, mv)
113 return md5.digest()
114
115
116 def _merge_cumulative_or_gauge_metrics(prior, latest):
117 if timestamp.compare(prior.endTime, latest.endTime) == -1:
118 return latest
119 else:
120 return prior
121
122
123 def _merge_delta_metric(prior, latest):
124 prior_type, prior_value = _detect_value(prior)
125 latest_type, latest_value = _detect_value(latest)
126 _merge_delta_timestamps(prior, latest)
127 updated_value = _combine_delta_values(prior_type, prior_value, latest_value)
128 setattr(latest, latest_type, updated_value)
129 return latest
130
131
132 # This is derived from the oneof choices for the MetricValue message's value
133 # field in google/api/servicecontrol/v1/metric_value.proto, and should be kept
134 # in sync with that
135 _METRIC_VALUE_ONEOF_FIELDS = (
136 'boolValue', 'distributionValue', 'doubleValue', 'int64Value',
137 'moneyValue', 'stringValue')
138
139
140 def _detect_value(metric_value):
141 for f in _METRIC_VALUE_ONEOF_FIELDS:
142 value = metric_value.get_assigned_value(f)
143 if value is not None:
144 return f, value
145 return None, None
146
147
148 def _merge_delta_timestamps(prior, latest):
149 # Update the start time and end time in the latest metric value
150 if (prior.startTime and
151 (latest.startTime is None or
152 timestamp.compare(prior.startTime, latest.startTime) == -1)):
153 latest.startTime = prior.startTime
154
155 if (prior.endTime and
156 (latest.endTime is None or timestamp.compare(
157 latest.endTime, prior.endTime) == -1)):
158 latest.endTime = prior.endTime
159
160 return latest
161
162
163 def _combine_delta_values(value_type, prior, latest):
164 if value_type in ('int64Value', 'doubleValue'):
165 return prior + latest
166 elif value_type == 'moneyValue':
167 return money.add(prior, latest, allow_overflow=True)
168 elif value_type == 'distributionValue':
169 distribution.merge(prior, latest)
170 return latest
171 else:
172 logger.error('Unmergeable metric type %s', value_type)
173 raise ValueError('Could not merge unmergeable metric type')
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698