1 # SPDX-License-Identifier: EPL-1.0
2 ##############################################################################
3 # Copyright (c) 2018 The Linux Foundation and others.
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Eclipse Public License v1.0
7 # which accompanies this distribution, and is available at
8 # http://www.eclipse.org/legal/epl-v10.html
9 ##############################################################################
11 from copy import deepcopy as dc
17 print(json.dumps(x, indent=4, sort_keys=True))
28 'categoryLines': False,
38 'legendPosition': 'right',
40 'addTimeMarker': False
45 def create(self, config):
47 temp['title'] = config['title']
48 temp['type'] = temp['params']['type'] = config['type']
51 temp['params']['categoryAxes'] = [dc(
52 cat.create()) for i in range(config['num_cat_axes'])]
55 temp['params']['valueAxes'] = [dc(val.create(position=i['position'],
58 config['value_axes'].items()]
64 field=config['aggs'][i]['field'],
65 custom_label=config['aggs'][i]['custom_label'],
66 schema=config['aggs'][i]['schema']))
67 for i in range(1, len(config['aggs']) + 1)]
69 temp['params']['seriesParams'] = [seriesParams(i['data_type'],
76 config['seriesParams'].items()]
102 temp = dc(self.content)
103 temp['id'] = 'CategoryAxis-{}'.format(self.counter)
132 def create(self, position='left', title='Value'):
134 temp = dc(self.content)
135 temp['id'] = 'ValueAxis-{}'.format(self.counter)
136 if position == 'left':
137 temp['name'] = 'LeftAxis-{}'.format(self.counter)
138 elif position == 'right':
139 temp['name'] = 'RightAxis-{}'.format(self.counter)
141 # raise ValueError('Not one of left or right')
143 temp['name'] = 'LeftAxis-{}'.format(self.counter)
145 temp['title']['text'] = title
151 def __init__(self, data_type, mode, label, agg_id, value_axis):
160 'valueAxis': 'ValueAxis-{}'.format(value_axis),
161 'drawLinesBetweenPoints': True,
183 def create(self, id, field, custom_label, schema):
184 temp = dc(self.content)
186 temp['params']['field'] = field
187 temp['params']['customLabel'] = custom_label
188 temp['schema'] = schema
189 if schema == 'metric':
192 elif schema == 'segment':
193 temp['type'] = 'terms'
194 temp['params']['size'] = 20 # default
195 temp['params']['order'] = 'asc'
196 temp['params']['orderBy'] = '_term'
200 # generate takes both the template config and project specific config and
201 # parses and organizes as much info available from that and
202 # generates an intermediate format first which
203 # contains all necessary info to deterministically create the visState to
204 # be sent to Kibana. Hence, any error occuring in the visualizaton side
205 # must first be checked by looking at the intermediate format.
207 def generate(dash_config, viz_config):
213 "index_pattern": None,
221 value_axes_format = {
228 seriesParams_format = {
240 "custom_label": None,
246 # all general description must be present in either of the config files
247 for config in [viz_config, dash_config]:
248 general_fields = ['type', 'index_pattern',
249 'num_cat_axes', 'title', 'desc', 'id']
250 for i in general_fields:
252 format[i] = config[i]
253 except KeyError as e:
256 # setting any default values if available
257 mappings = {'value_axes': value_axes_format,
258 'seriesParams': seriesParams_format, 'aggs': aggs_format}
259 for index, container in mappings.items():
261 default_values = viz_config[index]['default']
262 for i in default_values:
263 container['index'][i] = default_values[i]
267 value_axes_counter = 1
268 for m in viz_config['value_axes']:
270 temp = dc(value_axes_format)
271 temp[str(value_axes_counter)] = temp['index']
272 for i in ['position', 'title']:
274 temp[str(value_axes_counter)
275 ][i] = viz_config['value_axes'][m][i]
278 format['value_axes'].update(temp)
279 value_axes_counter += 1
281 seriesParams_fields = ['value_axis',
282 'data_type', 'mode', 'label', 'agg_id']
284 for m in viz_config['seriesParams']:
286 temp = dc(seriesParams_format)
287 temp[m] = temp['index']
288 for i in seriesParams_fields:
290 temp[m][i] = viz_config['seriesParams'][m][i]
293 format['seriesParams'].update(temp)
299 for m in viz_config['aggs']:
301 temp = dc(aggs_format)
302 temp[m] = temp['index']
303 for i in ['field', 'custom_label', 'schema']:
305 temp[m][i] = viz_config['aggs'][m][i]
308 format['aggs'].update(temp)
315 configs.append(viz_config)
320 dash_config['y-axis']['series']
321 configs.append(dash_config['y-axis'])
325 for config in configs:
327 value_axes_counter = 1
328 for key in config['value_axes']:
330 value_axes_temp = dc(value_axes_format)
331 value_axes_temp[str(value_axes_counter)
332 ] = value_axes_temp['index']
334 for index in ['position', 'title']:
337 value_axes_counter)][index] = \
338 config['value_axes'][key][index]
339 except KeyError as e:
341 format['value_axes'].update(value_axes_temp)
342 value_axes_counter += 1
344 except KeyError as e:
348 for key in config['series']:
350 # check if this key is present or not
351 config['series'][key]['not_in_seriesParams']
353 seriesParams_temp = dc(seriesParams_format)
354 seriesParams_temp[key] = seriesParams_temp['index']
355 for index in ['value_axis', 'data_type', 'mode', 'label']:
357 seriesParams_temp[key][index] = \
358 config['series'][key][index]
359 except KeyError as e:
361 seriesParams_temp[key]['agg_id'] = key
362 format['seriesParams'].update(seriesParams_temp)
364 agg_temp = dc(aggs_format)
365 agg_temp[key] = agg_temp['index']
366 for index in ['field', 'schema']:
368 agg_temp[key][index] = config['series'][key][index]
369 except KeyError as e:
371 agg_temp[key]['custom_label'] = \
372 config['series'][key]['label']
373 format['aggs'].update(agg_temp)
374 except KeyError as e:
375 print("required fields are empty!")
377 # to remove the default template index
378 for i in ['value_axes', 'seriesParams', 'aggs']:
380 format[i].pop('index')
382 # print("No default index found")
385 if not config_validator(format):
386 raise ValueError('Missing required field values')
391 generated_visState = vis.create(format)
393 # checking incase there are None values \
394 # in the format indicating missing fields
396 if not config_validator(generated_visState):
397 raise KeyError('required fields are missing values!')
398 return format, generated_visState
401 # Check the generated format if it contains any key with None
402 # as it's value which indicates incomplete information
403 def config_validator(val):
405 for _, i in val.items():
406 if isinstance(i, dict):
407 flag = config_validator(i)
413 if __name__ == '__main__':
414 with open('viz.yaml', 'r') as f:
415 viz_config = yaml.safe_load(f)
417 with open('dashboard.yaml', 'r') as f:
418 dash_config = yaml.safe_load(f)
420 generate(dash_config['dashboard']['viz'][2],
421 viz_config['opendaylight-test-performance'])
422 # generate(dash_config['dashboard']['viz'][3],viz_config['opendaylight-test-performance'])
423 # generate(dash_config['dashboard']['viz'][1],viz_config['opendaylight-test-feature'])