diff options
Diffstat (limited to 'app/api/responders/resource/aggregates.py')
-rw-r--r-- | app/api/responders/resource/aggregates.py | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/app/api/responders/resource/aggregates.py b/app/api/responders/resource/aggregates.py new file mode 100644 index 0000000..36fcfa4 --- /dev/null +++ b/app/api/responders/resource/aggregates.py @@ -0,0 +1,157 @@ +############################################################################### +# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) # +# and others # +# # +# All rights reserved. This program and the accompanying materials # +# are made available under the terms of the Apache License, Version 2.0 # +# which accompanies this distribution, and is available at # +# http://www.apache.org/licenses/LICENSE-2.0 # +############################################################################### +from api.responders.responder_base import ResponderBase +from api.validation.data_validate import DataValidate + + +class Aggregates(ResponderBase): + def __init__(self): + super().__init__() + self.AGGREGATE_TYPES = ["environment", "message", "constant"] + self.AGGREGATES_MAP = { + "environment": self.get_environments_aggregates, + "message": self.get_messages_aggregates, + "constant": self.get_constants_aggregates + } + + def on_get(self, req, resp): + self.log.debug("Getting aggregates information") + + filters = self.parse_query_params(req) + filters_requirements = { + "env_name": self.require(str), + "type": self.require(str, validate=DataValidate.LIST, + requirement=self.AGGREGATE_TYPES, + mandatory=True, + error_messages={"mandatory": + "type must be specified: " + + "environment/" + + " message/" + + "constant"}) + } + self.validate_query_data(filters, filters_requirements) + query = self.build_query(filters) + query_type = query["type"] + if query_type == "environment": + env_name = query.get("env_name") + if not env_name: + self.bad_request("env_name must be specified") + if not self.check_environment_name(env_name): + self.bad_request("unknown environment: " + env_name) + + aggregates = self.AGGREGATES_MAP[query_type](query) + self.set_successful_response(resp, aggregates) + + def build_query(self, filters): + query = {} + env_name = filters.get("env_name") + query_type = filters["type"] + query["type"] = filters["type"] + if query_type == "environment": + if env_name: + query['env_name'] = env_name + return query + return query + + def get_environments_aggregates(self, query): + env_name = query['env_name'] + aggregates = { + "type": query["type"], + "env_name": env_name, + "aggregates": { + "object_types": { + + } + } + } + pipeline = [ + { + '$match': { + 'environment': env_name + } + }, + { + '$group': { + '_id': '$type', + 'total': { + '$sum': 1 + } + } + } + ] + groups = self.aggregate(pipeline, "inventory") + for group in groups: + aggregates['aggregates']['object_types'][group['_id']] = \ + group['total'] + return aggregates + + def get_messages_aggregates(self, query): + aggregates = { + "type": query['type'], + "aggregates": { + "levels": {}, + "environments": {} + } + } + env_pipeline = [ + { + '$group': { + '_id': '$environment', + 'total': { + '$sum': 1 + } + } + } + ] + environments = self.aggregate(env_pipeline, "messages") + for environment in environments: + aggregates['aggregates']['environments'][environment['_id']] = \ + environment['total'] + level_pipeline = [ + { + '$group': { + '_id': '$level', + 'total': { + '$sum': 1 + } + } + } + ] + levels = self.aggregate(level_pipeline, "messages") + for level in levels: + aggregates['aggregates']['levels'][level['_id']] = \ + level['total'] + + return aggregates + + def get_constants_aggregates(self, query): + aggregates = { + "type": query['type'], + "aggregates": { + "names": {} + } + } + pipeline = [ + { + '$project': { + '_id': 0, + 'name': 1, + 'total': { + '$size': '$data' + } + } + } + ] + constants = self.aggregate(pipeline, "constants") + for constant in constants: + aggregates['aggregates']['names'][constant['name']] = \ + constant['total'] + + return aggregates |