Skip to content

Commit d8667d0

Browse files
committed
refactor topo parser
-backport "Refactor matadata parser" #235 to 7.x branch
1 parent fdad184 commit d8667d0

File tree

1 file changed

+39
-23
lines changed

1 file changed

+39
-23
lines changed

source/queryHandler/Topo.py

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
@author: HWASSMAN
2121
'''
2222

23-
24-
from collections import defaultdict
23+
import copy
24+
from collections import defaultdict, OrderedDict
2525
from typing import Set, List, Dict, DefaultDict
2626

2727
# dict.iteritems() deprecated in python 3
@@ -36,6 +36,7 @@ class Topo(object):
3636
def __init__(self, jsonStr=None):
3737
self.topo = jsonStr
3838
self.__metricsDef = defaultdict(dict) # metrics dictionary, per sensor for all elements in the metadata
39+
self.__metricsType = defaultdict(dict) # metrics types dictionary
3940
self.__levels = defaultdict(dict) # component level priority dictionary, per sensor
4041
self.__ids = {} # fieldIds dictionary
4142
self.__groupKeys = {}
@@ -55,22 +56,24 @@ def _processMetadata(self, metadata):
5556
_components = defaultdict(set)
5657
# filters dictionary, per sensor, per (cluster or cluster_node) component
5758
_filters = defaultdict(list)
59+
# ordered dictionary to store filedLabel:fieldName pairs in order as they occur in metaStr
60+
_tags = OrderedDict()
5861
# name of the (cluster or cluster_node) component
5962
label = metaStr.get('fieldLabel')
6063

6164
if label in self.__compTree.keys():
6265
_components = self.__compTree[label]['componentsMap']
6366
_filters = self.__compTree[label]['filtersMap']
6467

65-
self._parse_topoJSONStr(self.__metricsDef, self.__levels, self.__ids, self.__groupKeys, _components, _filters, metaStr)
68+
self._parse_topoJSONStr(self.__metricsDef, self.__metricsType, self.__levels, self.__ids, self.__groupKeys, _components, _filters, _tags, metaStr)
6669
tree_entry = {}
6770
tree_entry['componentsMap'] = _components
6871
tree_entry['filtersMap'] = _filters
6972

7073
# comp_tree[label] = tree_entry
7174
self.__compTree[label] = tree_entry
7275

73-
def _parse_topoJSONStr(self, metrics, levels, ids, groupKeys, components, filters, metaStr):
76+
def _parse_topoJSONStr(self, metrics, metricsType, levels, ids, groupKeys, components, filters, _tags, metaStr):
7477
'''
7578
This function parses the 'node' or 'attribute' object found in the given JSON string (metaStr) in
7679
the componets or metrics dictionary. Also the used metric filters (per sensor) will be stored
@@ -80,15 +83,24 @@ def _parse_topoJSONStr(self, metrics, levels, ids, groupKeys, components, filter
8083

8184
field_value = metaStr['fieldLabel']
8285
field_name = metaStr['fieldName']
86+
field_type = metaStr['fieldSemantics']
8387

8488
# check if entity is a component
8589
if metaStr['type'] == 'node':
90+
if field_name == "sensor":
91+
# remove all partialKey tags from _tags dict except parent since we step in the new sensor level metaKey
92+
parent = _tags.popitem(last=False)
93+
_tags.clear()
94+
_tags.update([parent])
95+
else:
96+
_tags[field_name] = field_value
97+
8698
if field_value not in components[field_name]:
8799
components[field_name].add(field_value)
88100
# check if metaStr includes next level metaStr
89101
if 'keys' in metaStr and len(metaStr['keys']) > 0:
90102
for metaKey in metaStr['keys']:
91-
self._parse_topoJSONStr(metrics, levels, ids, groupKeys, components, filters, metaKey)
103+
self._parse_topoJSONStr(metrics, metricsType, levels, ids, groupKeys, components, filters, _tags, metaKey)
92104

93105
# check if entity is a metric
94106
elif metaStr['type'] == 'attribute':
@@ -100,21 +112,22 @@ def _parse_topoJSONStr(self, metrics, levels, ids, groupKeys, components, filter
100112

101113
if field_name not in iterval(metrics[sensor]):
102114
metrics[sensor][field_id] = field_name
115+
metricsType[field_name] = field_type
103116

104117
if groupKey not in groupKeys:
105118
# parse sensor relevant data f.e. groupKey, filters, levels
106119
groupKeys[groupKey] = len(groupKeys) + 1
107-
tags = {}
108-
levTree = {}
109-
for i, compValue in enumerate(partKey):
110-
for compLabel in components:
111-
if compValue in components[compLabel]:
112-
levTree[i + 1] = compLabel
113-
tags[compLabel] = compValue
114-
# if tags not in filters[sensor]:
115-
# not needed as groupkeys check will allow this to be reached only once
116-
filters[sensor].append(tags)
120+
group_tags = copy.deepcopy(_tags)
121+
122+
# if not all((value in tags.values()) for value in partKey):
123+
# rint("different key values")
124+
125+
filters[sensor].append(group_tags)
117126
if sensor not in levels:
127+
levTree = {}
128+
for i, tag_key in enumerate(group_tags.keys()):
129+
levTree[i + 1] = tag_key
130+
118131
levels[sensor] = levTree
119132

120133
# parse key id
@@ -177,6 +190,11 @@ def metricsSpec(self):
177190
''' Returns all defined metrics as dictionary of (metric_name : metric_id) items '''
178191
return self.__metricsDef
179192

193+
@property
194+
def metricsType(self):
195+
''' Returns a dictionary of (metric_name : metric_type) items '''
196+
return self.__metricsType
197+
180198
@property
181199
def getAllEnabledMetricsNames(self):
182200
''' Returns list of all found metrics names'''
@@ -201,7 +219,7 @@ def getSensorForMetric(self, searchMetric):
201219
if (searchMetric.find("(") >= 0):
202220
searchMetric = searchMetric[searchMetric.find("(") + 1:-1]
203221
for sensor, metrics in self.__metricsDef.items():
204-
if searchMetric in metrics.values():
222+
if searchMetric in set(metrics.values()):
205223
return sensor
206224
return None
207225

@@ -237,7 +255,7 @@ def getAllFilterMapsForSensor(self, searchSensor):
237255
based on metadata topology returned from zimon "topo".
238256
'''
239257
filtersMaps = []
240-
if searchSensor in self.allFiltersMaps.keys():
258+
if searchSensor in set(self.allFiltersMaps.keys()):
241259
filtersMaps.extend(self.allFiltersMaps[searchSensor])
242260
return filtersMaps
243261

@@ -274,13 +292,11 @@ def getAllFilterKeysForMetric(self, searchMetric):
274292
return keys
275293

276294
def getAllFilterKeysForSensor(self, searchSensor):
277-
keys = []
295+
filter_keys = set()
278296
filtersMap = self.getAllFilterMapsForSensor(searchSensor)
279-
for a in filtersMap:
280-
keys.extend(list(a.keys()))
281-
if len(keys) > 1:
282-
return list(set(keys))
283-
return keys
297+
for filter in filtersMap:
298+
filter_keys.update(filter.keys())
299+
return list(filter_keys)
284300

285301
def getAllFilterKeysForMeasurementsMetrics(self, searchMetrics):
286302
filterKeys = []

0 commit comments

Comments
 (0)