blob: 43bdb39aed2ad33d3728dbb525475920fa327a8c [file] [log] [blame]
#// Copyright (c) 2000-2018 Ericsson Telecom AB //
#// All rights reserved. This program and the accompanying materials are made available under the terms //
#// of the Eclipse Public License v2.0 which accompanies this distribution, and is available at //
#// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html //
#/////////////////////////////////////////////////////////////////////////////////////////////////////////
import json, logging
from fnmatch import fnmatch
from Common.DsRestAPI import DsRestAPI
from Help import DSHELP
class DataSource:
'''The DataSource handler'''
SOURCE_ID = 'DataSource'
def __init__(self, directory):
self._logger = logging.getLogger(__name__)
self._handlers = {}
self._dsRestAPI = DsRestAPI(self._getDataHandler, self._setDataHandler)
def setHandlers(self, handlers):
self._handlers = handlers
def _getDataHandler(self, request, userCredentials):
if request['source'] == self.SOURCE_ID:
return self._handleBuildInGetData(request, userCredentials)
elif request['source'] in self._handlers:
return self._handlers[request['source']]['getDataHandler'](request, userCredentials)
def _setDataHandler(self, request, userCredentials):
if request['source'] == self.SOURCE_ID:
return None
elif request['source'] in self._handlers:
return self._handlers[request['source']]['setDataHandler'](request, userCredentials)
def _handleBuildInGetData(self, request, userCredentials):
element = request['element']
params = request['params']
if element == 'help':
help = {'sources': [{'source': self.SOURCE_ID, 'dataElements': DSHELP}]}
for handlerName in self._handlers:
if handlerName != self.SOURCE_ID:
try:
helpResponse = self._handlers[handlerName]['getDataHandler']({'source': handlerName, 'element': 'help', 'params': []}, userCredentials)
if helpResponse is not None:
handlerHelp = json.loads(helpResponse['node']['val'].decode('hex'))
for sourceHelp in handlerHelp['sources']:
help['sources'].append(sourceHelp)
except:
self._logger.exception('Failed to get help for ' + handlerName)
return {'node': {'val': json.dumps(help).encode('hex'), 'tp': 5}}
elif element == 'Sources':
return {'list': [{'node': {'val': handlerName, 'tp': 10}} for handlerName in self._handlers]}
elif element == 'not' and len(params) == 1:
return {'node': {'val': self._bool2string(params[0]['paramValue'] != 'true'), 'tp': 3}}
elif element == '==' and len(params) == 2:
return {'node': {'val': self._bool2string(params[0]['paramValue'] == params[1]['paramValue']), 'tp': 3}}
elif element == '!=' and len(params) == 2:
return {'node': {'val': self._bool2string(params[0]['paramValue'] != params[1]['paramValue']), 'tp': 3}}
elif element == '>' and len(params) == 2:
return {'node': {'val': self._bool2string(float(params[0]['paramValue']) > float(params[1]['paramValue'])), 'tp': 3}}
elif element == '>=' and len(params) == 2:
return {'node': {'val': self._bool2string(float(params[0]['paramValue']) >= float(params[1]['paramValue'])), 'tp': 3}}
elif element == '<' and len(params) == 2:
return {'node': {'val': self._bool2string(float(params[0]['paramValue']) < float(params[1]['paramValue'])), 'tp': 3}}
elif element == '<=' and len(params) == 2:
return {'node': {'val': self._bool2string(float(params[0]['paramValue']) <= float(params[1]['paramValue'])), 'tp': 3}}
elif element == 'and':
return {'node': {'val': self._bool2string(reduce(lambda x, y: x and y, [self._string2bool(param['paramValue']) for param in params], True)), 'tp': 3}}
elif element == 'or':
return {'node': {'val': self._bool2string(reduce(lambda x, y: x or y, [self._string2bool(param['paramValue']) for param in params], False)), 'tp': 3}}
elif element == 'match' and len(params) == 2:
return {'node': {'val': self._bool2string(fnmatch(params[0]['paramValue'], params[1]['paramValue'])), 'tp': 3}}
elif element == 'not match' and len(params) == 2:
return {'node': {'val': self._bool2string(not fnmatch(params[0]['paramValue'], params[1]['paramValue'])), 'tp': 3}}
elif element == 'sum' and len(params) == 1:
return {'node': {'val': str(sum([float(string) for string in json.loads(params[0]['paramValue'])])), 'tp': 2}}
elif element == 'exists' and len(params) == 1:
return {'node': {'val': self._bool2string(reduce(lambda x, y: x or y, [self._string2bool(string) for string in json.loads(params[0]['paramValue'])], False)), 'tp': 3}}
elif element == 'forAll' and len(params) == 1:
return {'node': {'val': self._bool2string(reduce(lambda x, y: x and y, [self._string2bool(string) for string in json.loads(params[0]['paramValue'])], True)), 'tp': 3}}
elif element == 'dataElementPresent':
origSource, origElement, origParams = self._getRequestPartsFromParams(params)
response = self._getDataHandler({'source': origSource, 'element': origElement, 'params': origParams}, userCredentials)
if response is not None:
return {'node': {'val': 'true', 'tp': 3}}
else:
return {'node': {'val': 'false', 'tp': 3}}
elif element == 'sizeOf':
origSource, origElement, origParams = self._getRequestPartsFromParams(params)
response = self._getDataHandler({'source': origSource, 'element': origElement, 'params': origParams}, userCredentials)
size = 1
if 'list' in response:
size = len(response['list'])
return {'node': {'val': str(size), 'tp': 1}}
def _getRequestPartsFromParams(self, params):
origSource = ''
origElement = ''
origParams = []
i = 0
while i < len(params):
param = params[i]
if param['paramName'] == 'Source':
origSource = param['paramValue']
elif param['paramName'] == 'Element':
origElement = param['paramValue']
elif param['paramName'] == 'ParamName':
i += 1
if i < len(params) and params[i]['paramName'] == 'ParamValue':
origParams.append({'paramName': param['paramValue'], 'paramValue': params[i]['paramValue']})
else:
return {'node': {'val': 'A ParamValue must always follow a ParamName parameter.', 'tp': 4}}
i += 1
return origSource, origElement, origParams
def _bool2string(self, bool):
if bool:
return 'true'
else:
return 'false'
def _string2bool(self, string):
return string == 'true'
def handleMessage(self, method, path, headers, body, userCredentials, response):
response['body'] = json.dumps(self._dsRestAPI.parseRequest(json.loads(body), userCredentials))
response['headers']['Content-Type'] = 'application/json'
def getDataSourceHandlers(self):
return {
self.SOURCE_ID: {
'getDataHandler': self._getDataHandler,
'setDataHandler': self._setDataHandler
}
}
def close(self):
pass