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
27+ import analytics
28+ from utils import cond_execution_time , get_runtime_statistics
29+
2730# dict.iteritems() deprecated in python 3
2831iterval = lambda d : (getattr (d , 'itervalues' , None ) or d .values )()
2932
@@ -44,34 +47,38 @@ def __init__(self, jsonStr=None):
4447 if self .topo :
4548 self ._processMetadata (self .topo )
4649
50+ @get_runtime_statistics (enabled = analytics .runtime_profiling )
4751 def _processMetadata (self , metadata ):
4852 '''
4953 For each component of the highest level (cluster or cluster_node) splits metadata in
5054 sub components, filters and metrics related info maps
5155 '''
52-
56+
5357 for metaStr in metadata :
5458
5559 # sub components dictionary of the highest level component (cluster or cluster_node)
5660 _components = defaultdict (set )
5761 # filters dictionary, per sensor, per (cluster or cluster_node) component
5862 _filters = defaultdict (list )
63+ # ordered dictionary to store filedLabel:fieldName pairs in order as they occur in metaStr
64+ _tags = OrderedDict ()
65+
5966 # name of the (cluster or cluster_node) component
6067 label = metaStr .get ('fieldLabel' )
6168
6269 if label in self .__compTree .keys ():
6370 _components = self .__compTree [label ]['componentsMap' ]
6471 _filters = self .__compTree [label ]['filtersMap' ]
65-
66- self ._parse_topoJSONStr (self .__metricsDef , self .__metricsType , self .__levels , self .__ids , self .__groupKeys , _components , _filters , metaStr )
72+
73+ self ._parse_topoJSONStr (self .__metricsDef , self .__metricsType , self .__levels , self .__ids , self .__groupKeys , _components , _filters , _tags , metaStr )
6774 tree_entry = {}
6875 tree_entry ['componentsMap' ] = _components
6976 tree_entry ['filtersMap' ] = _filters
7077
7178 # comp_tree[label] = tree_entry
7279 self .__compTree [label ] = tree_entry
7380
74- def _parse_topoJSONStr (self , metrics , metricsType , levels , ids , groupKeys , components , filters , metaStr ):
81+ def _parse_topoJSONStr (self , metrics , metricsType , levels , ids , groupKeys , components , filters , _tags , metaStr ):
7582 '''
7683 This function parses the 'node' or 'attribute' object found in the given JSON string (metaStr) in
7784 the componets or metrics dictionary. Also the used metric filters (per sensor) will be stored
@@ -85,12 +92,20 @@ def _parse_topoJSONStr(self, metrics, metricsType, levels, ids, groupKeys, compo
8592
8693 # check if entity is a component
8794 if metaStr ['type' ] == 'node' :
95+ if field_name == "sensor" :
96+ # remove all partialKey tags from _tags dict except parent since we step in the new sensor level metaKey
97+ parent = _tags .popitem (last = False )
98+ _tags .clear ()
99+ _tags .update ([parent ])
100+ else :
101+ _tags [field_name ] = field_value
102+
88103 if field_value not in components [field_name ]:
89104 components [field_name ].add (field_value )
90105 # check if metaStr includes next level metaStr
91106 if 'keys' in metaStr and len (metaStr ['keys' ]) > 0 :
92107 for metaKey in metaStr ['keys' ]:
93- self ._parse_topoJSONStr (metrics , metricsType , levels , ids , groupKeys , components , filters , metaKey )
108+ self ._parse_topoJSONStr (metrics , metricsType , levels , ids , groupKeys , components , filters , _tags , metaKey )
94109
95110 # check if entity is a metric
96111 elif metaStr ['type' ] == 'attribute' :
@@ -107,17 +122,17 @@ def _parse_topoJSONStr(self, metrics, metricsType, levels, ids, groupKeys, compo
107122 if groupKey not in groupKeys :
108123 # parse sensor relevant data f.e. groupKey, filters, levels
109124 groupKeys [groupKey ] = len (groupKeys ) + 1
110- tags = {}
111- levTree = {}
112- for i , compValue in enumerate (partKey ):
113- for compLabel in components :
114- if compValue in components [compLabel ]:
115- levTree [i + 1 ] = compLabel
116- tags [compLabel ] = compValue
117- # if tags not in filters[sensor]:
118- # not needed as groupkeys check will allow this to be reached only once
119- filters [sensor ].append (tags )
125+ group_tags = copy .deepcopy (_tags )
126+
127+ # if not all((value in tags.values()) for value in partKey):
128+ # print("different key values")
129+
130+ filters [sensor ].append (group_tags )
120131 if sensor not in levels :
132+ levTree = {}
133+ for i , tag_key in enumerate (group_tags .keys ()):
134+ levTree [i + 1 ] = tag_key
135+
121136 levels [sensor ] = levTree
122137
123138 # parse key id
0 commit comments