165 lines
5.2 KiB
Python
165 lines
5.2 KiB
Python
# Copyright 2018 Objectif Libre
|
|
#
|
|
# 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.
|
|
#
|
|
import copy
|
|
import functools
|
|
|
|
from influxdb import resultset
|
|
|
|
from cloudkitty.storage.v2.influx import _sanitized_groupby
|
|
from cloudkitty.storage.v2.influx import InfluxClient
|
|
|
|
|
|
class FakeInfluxClient(InfluxClient):
|
|
|
|
total_sample = {
|
|
"statement_id": 0,
|
|
"series": []
|
|
}
|
|
|
|
total_series_sample = {
|
|
"name": "dataframes",
|
|
"tags": {},
|
|
"columns": ["time", "qty", "price"],
|
|
"values": [],
|
|
}
|
|
|
|
def __init__(self, **kwargs):
|
|
super(FakeInfluxClient, self).__init__(autocommit=False)
|
|
|
|
def commit(self):
|
|
pass
|
|
|
|
@staticmethod
|
|
def __filter_func(types, filters, begin, end, elem):
|
|
if elem['time'] < begin or elem['time'] >= end:
|
|
return False
|
|
if types and elem['tags']['type'] not in types:
|
|
return False
|
|
if filters is None:
|
|
return True
|
|
for key in filters.keys():
|
|
if key not in elem['tags'].keys():
|
|
return False
|
|
if elem['tags'][key] != filters[key]:
|
|
return False
|
|
return True
|
|
|
|
def __get_target_serie(self, point, series, groupby):
|
|
target_serie = None
|
|
for serie in series:
|
|
if not groupby:
|
|
target_serie = serie
|
|
break
|
|
valid = True
|
|
for tag in serie['tags'].keys():
|
|
if tag == 'time':
|
|
if point['time'].isoformat() != serie['values'][0][0]:
|
|
valid = False
|
|
break
|
|
else:
|
|
continue
|
|
if tag not in point['tags'].keys() or \
|
|
point['tags'][tag] != serie['tags'][tag]:
|
|
valid = False
|
|
break
|
|
if valid:
|
|
target_serie = serie
|
|
break
|
|
|
|
if target_serie is None:
|
|
target_serie = copy.deepcopy(self.total_series_sample)
|
|
if groupby:
|
|
target_serie['tags'] = {k: point['tags'][k] for k in
|
|
_sanitized_groupby(groupby)}
|
|
else:
|
|
target_serie['tags'] = {}
|
|
target_serie['values'] = [[point['time'].isoformat(), 0, 0]]
|
|
series.append(target_serie)
|
|
return target_serie
|
|
|
|
def get_total(self, types, begin, end, groupby=None, filters=None):
|
|
total = copy.deepcopy(self.total_sample)
|
|
series = []
|
|
|
|
filter_func = functools.partial(
|
|
self.__filter_func, types, filters, begin, end)
|
|
points = filter(filter_func, self._points)
|
|
|
|
for point in points:
|
|
target_serie = self.__get_target_serie(point, series, groupby)
|
|
target_serie['values'][0][1] += point['fields']['qty']
|
|
target_serie['values'][0][2] += point['fields']['price']
|
|
total['series'] = series
|
|
|
|
return resultset.ResultSet(total)
|
|
|
|
def retrieve(self,
|
|
types,
|
|
filters,
|
|
begin, end,
|
|
offset=0, limit=1000, paginate=True):
|
|
output = copy.deepcopy(self.total_sample)
|
|
|
|
filter_func = functools.partial(
|
|
self.__filter_func, types, filters, begin, end)
|
|
points = list(filter(filter_func, self._points))
|
|
|
|
columns = set()
|
|
for point in points:
|
|
columns.update(point['tags'].keys())
|
|
columns.update(point['fields'].keys())
|
|
columns.add('time')
|
|
|
|
series = {
|
|
'name': 'dataframes',
|
|
'columns': list(columns),
|
|
}
|
|
values = []
|
|
|
|
def __get_tag_or_field(point, key):
|
|
if key == 'time':
|
|
return point['time'].isoformat()
|
|
return point['tags'].get(key) or point['fields'].get(key)
|
|
|
|
for point in points:
|
|
values.append([__get_tag_or_field(point, key)
|
|
for key in series['columns']])
|
|
|
|
series['values'] = values
|
|
output['series'] = [series]
|
|
|
|
return len(list(points)), resultset.ResultSet(output)
|
|
|
|
def delete(self, begin, end, filters):
|
|
|
|
def __filter_func(elem):
|
|
|
|
def __time(elem):
|
|
return ((begin and begin > elem['time'])
|
|
or (end and end <= elem['time']))
|
|
|
|
def __filt(elem):
|
|
return all(
|
|
(elem['tags'].get(k, None) == v
|
|
or elem['fields'].get(k, None) == v)
|
|
for k, v in filters.items())
|
|
|
|
return __time(elem) and __filt(elem)
|
|
|
|
self._points = list(filter(__filter_func, self._points))
|
|
|
|
def retention_policy_exists(self, database, policy):
|
|
return True
|