2020@author: HWASSMAN
2121'''
2222
23-
24- from collections import defaultdict
23+ import copy
24+ from collections import defaultdict , OrderedDict
2525from 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