From 27addde8bb2eb77132abc1d48332c6b1c04077a4 Mon Sep 17 00:00:00 2001 From: madhawav Date: Tue, 22 Aug 2017 13:15:48 +0530 Subject: [PATCH] Added DASClient Code --- PySiddhi4/das/DASClient.py | 28 + .../EventSimulator/AttributeConfiguration.py | 90 ++ .../EventSimulator/EventSimulatorClient.py | 219 +++++ .../FeedSimulationConfiguration.py | 38 + .../EventSimulator/SimulationProperties.py | 44 + .../das/EventSimulator/SimulationSource.py | 93 ++ .../SingleSimulationConfiguration.py | 22 + PySiddhi4/das/EventSimulator/__init__.py | 0 PySiddhi4/das/ObjectMapping/APIObject.py | 82 ++ PySiddhi4/das/ObjectMapping/FieldMapping.py | 55 ++ PySiddhi4/das/ObjectMapping/__init__.py | 0 .../SiddhiAppManagementClient.py | 140 +++ PySiddhi4/das/SiddhiAppManagement/__init__.py | 0 PySiddhi4/das/__Communication/RestClient.py | 59 ++ PySiddhi4/das/__Communication/__init__.py | 0 PySiddhi4/das/__Util.py | 34 + PySiddhi4/das/__init__.py | 0 Requirements.txt | 3 +- Tests/DASTests/EventSimulatorTests.py | 820 ++++++++++++++++++ Tests/DASTests/Resources/TestSiddhiApp.siddhi | 9 + .../DASTests/Resources/TestSiddhiApp1.siddhi | 9 + Tests/DASTests/Resources/sample.csv | 6 + Tests/DASTests/SiddhiAppManagerTests.py | 138 +++ Tests/DASTests/__init__.py | 0 .../BasicTest.py | 0 .../EventTest.py | 0 .../ExtensionsTest.py | 10 +- .../Resources/Extensions4/pom.xml | 0 .../TestDebugger.py | 0 .../TestOutputStream.py | 0 .../__init__.py | 0 .../log4j.xml | 0 32 files changed, 1892 insertions(+), 7 deletions(-) create mode 100644 PySiddhi4/das/DASClient.py create mode 100644 PySiddhi4/das/EventSimulator/AttributeConfiguration.py create mode 100644 PySiddhi4/das/EventSimulator/EventSimulatorClient.py create mode 100644 PySiddhi4/das/EventSimulator/FeedSimulationConfiguration.py create mode 100644 PySiddhi4/das/EventSimulator/SimulationProperties.py create mode 100644 PySiddhi4/das/EventSimulator/SimulationSource.py create mode 100644 PySiddhi4/das/EventSimulator/SingleSimulationConfiguration.py create mode 100644 PySiddhi4/das/EventSimulator/__init__.py create mode 100644 PySiddhi4/das/ObjectMapping/APIObject.py create mode 100644 PySiddhi4/das/ObjectMapping/FieldMapping.py create mode 100644 PySiddhi4/das/ObjectMapping/__init__.py create mode 100644 PySiddhi4/das/SiddhiAppManagement/SiddhiAppManagementClient.py create mode 100644 PySiddhi4/das/SiddhiAppManagement/__init__.py create mode 100644 PySiddhi4/das/__Communication/RestClient.py create mode 100644 PySiddhi4/das/__Communication/__init__.py create mode 100644 PySiddhi4/das/__Util.py create mode 100644 PySiddhi4/das/__init__.py create mode 100644 Tests/DASTests/EventSimulatorTests.py create mode 100644 Tests/DASTests/Resources/TestSiddhiApp.siddhi create mode 100644 Tests/DASTests/Resources/TestSiddhiApp1.siddhi create mode 100644 Tests/DASTests/Resources/sample.csv create mode 100644 Tests/DASTests/SiddhiAppManagerTests.py create mode 100644 Tests/DASTests/__init__.py rename Tests/{PySiddhi4Tests => SiddhiCoreTests}/BasicTest.py (100%) rename Tests/{PySiddhi4Tests => SiddhiCoreTests}/EventTest.py (100%) rename Tests/{PySiddhi4Tests => SiddhiCoreTests}/ExtensionsTest.py (95%) rename Tests/{ => SiddhiCoreTests}/Resources/Extensions4/pom.xml (100%) rename Tests/{PySiddhi4Tests => SiddhiCoreTests}/TestDebugger.py (100%) rename Tests/{PySiddhi4Tests => SiddhiCoreTests}/TestOutputStream.py (100%) rename Tests/{PySiddhi4Tests => SiddhiCoreTests}/__init__.py (100%) rename Tests/{PySiddhi4Tests => SiddhiCoreTests}/log4j.xml (100%) diff --git a/PySiddhi4/das/DASClient.py b/PySiddhi4/das/DASClient.py new file mode 100644 index 0000000..2e89e2d --- /dev/null +++ b/PySiddhi4/das/DASClient.py @@ -0,0 +1,28 @@ +from PySiddhi4.das.EventSimulator.EventSimulatorClient import EventSimulatorClient +from PySiddhi4.das.SiddhiAppManagement.SiddhiAppManagementClient import SiddhiAppManagementClient + + +class DASClient(object): + ''' + REST Client to work with WSO2 Data Analytics Server 4.0 + ''' + def __init__(self, host_url): + ''' + Instantiate REST Client + :param host_url: host url of DAS4. E.g. http://localhost:9090 + ''' + self.host_url = host_url + + def getSiddhiAppManagementClient(self): + ''' + Obtain client for managing Siddhi Apps + :return: + ''' + return SiddhiAppManagementClient(self.host_url + "/siddhi-apps") + + def getEventSimulatorClient(self): + ''' + Obtain client on event simulator + :return: + ''' + return EventSimulatorClient(self.host_url + "/simulation") diff --git a/PySiddhi4/das/EventSimulator/AttributeConfiguration.py b/PySiddhi4/das/EventSimulator/AttributeConfiguration.py new file mode 100644 index 0000000..4fead0c --- /dev/null +++ b/PySiddhi4/das/EventSimulator/AttributeConfiguration.py @@ -0,0 +1,90 @@ +from enum import Enum + +from PySiddhi4.das.ObjectMapping.APIObject import APIObject, NotSet +from PySiddhi4.das.ObjectMapping.FieldMapping import FieldMapping, ListFieldMapping +from PySiddhi4.das.__Util import decodeField, decodeObject + + +class AttributeConfiguration(APIObject): + ''' + Attribute Configuration API Object, which is an attribute of SimulationSource + ''' + + class Type(Enum): + ''' + Type of Attribute Configuration + ''' + CUSTOM_DATA_BASED = "CUSTOM_DATA_BASED" + PRIMITIVE_BASED = "PRIMITIVE_BASED" + REGEX_BASED = "REGEX_BASED" + PROPERTY_BASED = "PROPERTY_BASED" + + @classmethod + def encode(cls, v): + return v.value + + @classmethod + def decode(cls, v): + return AttributeConfiguration.Type(v) + + class PrimitiveType(Enum): + ''' + Type of primitive data type involved + ''' + LONG = "LONG" + INT = "INT" + STRING = "STRING" + FLOAT = "FLOAT" + DOUBLE = "DOUBLE" + + @classmethod + def encode(cls, v): + return v.value + + @classmethod + def decode(cls, v): + return AttributeConfiguration.Type(v) + + def __init__(self, type, min=NotSet(), max=NotSet(), length=NotSet(), precision=NotSet(), list=NotSet(), + pattern=NotSet(), + primitiveType=NotSet(), property=NotSet()): + ''' + Instantiates Attribute Configuration API Object + :param type: Type of AttributeConfiguration + :param min: + :param max: + :param length: + :param precision: + :param list: + :param pattern: + :param primitiveType: PrimitiveType involved + :param property: + ''' + self._setup( + field_mapping={"type": FieldMapping(AttributeConfiguration.Type.decode, AttributeConfiguration.Type.encode), + "length": FieldMapping(int), + "min": FieldMapping(int), "max": FieldMapping(int), + "precision": FieldMapping(int), "list": ListFieldMapping(str, str, NotSet()), + "pattern": FieldMapping(str), "property": FieldMapping(str), + "primitiveType": FieldMapping(AttributeConfiguration.PrimitiveType.decode, + AttributeConfiguration.PrimitiveType.encode)}) + self.type = type + self.length = length + self.min = min + self.max = max + self.precision = precision + self.list = list + self.pattern = pattern + self.primitiveType = primitiveType + self.property = property + + @classmethod + def parse(cls, jsonObject): + ''' + Converts a Python Class Object (from JSON) to AttributeConfiguration + :param jsonObject: + :return: + ''' + result = AttributeConfiguration(type=decodeField(jsonObject["type"], str)) + result._parse(jsonObject) + return result diff --git a/PySiddhi4/das/EventSimulator/EventSimulatorClient.py b/PySiddhi4/das/EventSimulator/EventSimulatorClient.py new file mode 100644 index 0000000..06af3d5 --- /dev/null +++ b/PySiddhi4/das/EventSimulator/EventSimulatorClient.py @@ -0,0 +1,219 @@ +import json +import logging + +from PySiddhi4.das.__Communication.RestClient import RestClient +from PySiddhi4.das.EventSimulator.FeedSimulationConfiguration import FeedSimulationConfiguration + + +class EventSimulatorClient(RestClient): + ''' + Client used to access DAS Event Simulator End Points + ''' + + def __init__(self, event_simulator_url): + ''' + Instantiates EventSimulatorClient + :param event_simulator_url: url to event_simulator endpoint (e.g. root_url + '/simulation') + ''' + RestClient.__init__(self, event_simulator_url) + + def saveSimulationFeedConfiguration(self, simulationConfiguration): + ''' + Saves a SimulationFeedConfiguration in WSO2 DAS Event Simulator + :param simulationConfiguration: + :return: + ''' + r = self._sendPostRequest("/feed", data=json.dumps(simulationConfiguration.toJSONObject())) + if r.status_code == 201: + return True + elif r.status_code == 409: + raise Exception("EventSimulationConfiguration with same name already exists.") + else: + raise Exception(str(r.status_code) + ": " + r.text) + + def runSimulationFeedConfiguration(self, simulationConfiguration): + ''' + Runs a SimulationFeedConfiguration in WSO2 DAS Event Simulator + :param simulationConfiguration: + :return: + ''' + r = self._sendPostRequest("/feed/" + simulationConfiguration.properties.simulationName + "/?action=run", + data=json.dumps(simulationConfiguration.toJSONObject())) + if r.status_code == 200: + return True + elif r.status_code == 404: + raise Exception("EventSimulationConfiguration with given name does not exist.") + else: + raise Exception(str(r.status_code) + ": " + r.text) + + def pauseSimulationFeedConfiguration(self, simulationName): + ''' + Pauses a SimulationFeedConfiguration in WSO2 DAS Event Simulator + :param simulationName: + :return: + ''' + r = self._sendPostRequest("/feed/" + simulationName + "/?action=pause") + if r.status_code == 200: + return True + elif r.status_code == 404: + raise Exception("EventSimulationConfiguration with given name does not exist.") + else: + raise Exception(str(r.status_code) + ": " + r.text) + + def resumeSimulationFeedConfiguration(self, simulationName): + ''' + Resumes a SimulationFeedConfiguration in WSO2 DAS Event Simulator + :param simulationName: + :return: + ''' + r = self._sendPostRequest("/feed/" + simulationName + "/?action=resume") + if r.status_code == 200: + return True + elif r.status_code == 404: + raise Exception("EventSimulationConfiguration with given name does not exist.") + else: + raise Exception(str(r.status_code) + ": " + r.text) + + def stopSimulationFeedConfiguration(self, simulationName): + ''' + Stops a SimulationFeedConfiguration in WSO2 DAS Event Simulator + :param simulationName: + :return: + ''' + r = self._sendPostRequest("/feed/" + simulationName + "/?action=stop") + if r.status_code == 200: + return True + elif r.status_code == 404: + raise Exception("EventSimulationConfiguration with given name does not exist.") + elif r.status_code == 409: + raise Exception("EventSimulation is already stopped.") + else: + raise Exception(str(r.status_code) + ": " + r.text) + + def editSimulationFeedConfiguration(self, simulationName, simulationConfiguration): + ''' + Edits a SimulationFeedConfiguration in WSO2 DAS Event Simulator + :param simulationName: + :param simulationConfiguration: new simulationNameConfiguration + :return: + ''' + r = self._sendPutRequest("/feed/" + simulationName, data=json.dumps(simulationConfiguration.toJSONObject())) + if r.status_code == 200: + return True + elif r.status_code == 404: + raise Exception("EventSimulationConfiguration with specified name does not exist.") + else: + raise Exception(str(r.status_code) + ": " + r.text) + + def deleteSimulationFeedConfiguration(self, simulationName): + ''' + Deletes a SimulationFeedConfiguration in WSO2 DAS Event Simulator + :param simulationName: + :return: + ''' + r = self._sendDeleteRequest("/feed/" + simulationName) + if r.status_code == 200: + return True + elif r.status_code == 404: + raise Exception("EventSimulationConfiguration with specified name does not exist.") + else: + raise Exception(str(r.status_code) + ": " + r.text) + + def retrieveSimulationFeedConfiguration(self, simulationName): + ''' + Retrieves a SimulationFeedConfiguration from WSO2 DAS Event Simulator + :param simulationName: + :return: + ''' + r = self._sendGetRequest("/feed/" + simulationName) + if r.status_code == 200: + result = r.json() + if result["status"].lower() == "ok": + jsonObject = json.loads(result["message"])["Simulation configuration"] + return FeedSimulationConfiguration.parse(jsonObject) + else: + raise Exception("Respose says not ok") + elif r.status_code == 404: + raise Exception("EventSimulationConfiguration with specified name does not exist.") + else: + raise Exception(str(r.status_code) + ": " + r.text) + + def simulateSingleEvent(self, singleSimulationConfiguration): + ''' + Invokes a Single Simulation in WSO2 DAS Event Simulator + :param singleSimulationConfiguration: + :return: + ''' + logging.info("Sending: " + json.dumps(singleSimulationConfiguration.toJSONObject())) + r = self._sendPostRequest("/single", data=json.dumps(singleSimulationConfiguration.toJSONObject())) + if r.status_code == 200: + logging.info("Received: " + r.text) + result = r.json() + if result["status"].lower() == "ok": + return True + else: + raise Exception("Respose says not ok") + elif r.status_code == 409: + raise Exception("EventSimulationConfiguration with same name already exists.") + else: + raise Exception(str(r.status_code) + ": " + r.text) + + def uploadCSV(self, fileName, stream=None, path=None): + ''' + Uploads a CSV to WSO2 DAS Event Simulator. Only one of the parameters stream or path should be given. + :param fileName: fileName of file to be uploaded + :param stream: stream of file to be uploaded + :param path: path of file to be uploaded + :return: + ''' + files = {} + if stream is not None: + files = {"file": (fileName, stream)} + else: + files = {"file": (fileName, open(path, "rb"))} + r = self._sendPostRequest("/files", files=files) + + logging.info(r) + + if r.status_code == 201: + return True + else: + raise Exception(str(r.status_code) + ": " + r.text) + + def updateCSV(self, uploadedFileName, newFileName, stream=None, path=None): + ''' + Updates a CSV file uploaded to WSO2 DAS Event Simulator. Only one of parameters stream or path should + be provided. + :param uploadedFileName: previous file name + :param newFileName: new file name + :param stream: stream of file to be uploaded + :param path: path of file to be uploaded + :return: + ''' + files = {} + if stream is not None: + files = {"file": (newFileName, stream)} + else: + files = {"file": (newFileName, open(path, "rb"))} + r = self._sendPutRequest("/files/" + uploadedFileName, files=files) + + logging.info(r) + + if r.status_code == 200: + return True + else: + raise Exception(str(r.status_code) + ": " + r.text) + + def deleteCSV(self, fileName): + ''' + Deletes a CSV file uploaded to WSO2 DAS Event Simulator + :param fileName: + :return: + ''' + r = self._sendDeleteRequest("/files/" + fileName) + logging.info(r) + + if r.status_code == 200: + return True + else: + raise Exception(str(r.status_code) + ": " + r.text) diff --git a/PySiddhi4/das/EventSimulator/FeedSimulationConfiguration.py b/PySiddhi4/das/EventSimulator/FeedSimulationConfiguration.py new file mode 100644 index 0000000..14ccfbb --- /dev/null +++ b/PySiddhi4/das/EventSimulator/FeedSimulationConfiguration.py @@ -0,0 +1,38 @@ +from PySiddhi4.das.EventSimulator.SimulationProperties import SimulationProperties +from PySiddhi4.das.EventSimulator.SimulationSource import SimulationSource +from PySiddhi4.das.ObjectMapping.APIObject import APIObject +from PySiddhi4.das.ObjectMapping.FieldMapping import FieldMapping, ListFieldMapping + + +class FeedSimulationConfiguration(APIObject): + ''' + FeedSimulationConfiguration API Object which could be passed to WSO2 DAS Event Simulator via EventSimulatorClient. + ''' + + def __init__(self, simulation_name=None, properties=None): + ''' + Instantiates FeedSimulationConfiguration. + :param simulation_name: name of simulation + :param properties: SimulationProperties + ''' + self._setup( + field_mapping={"properties": FieldMapping(SimulationProperties.parse, SimulationProperties.toJSONObject), + "sources": ListFieldMapping(SimulationSource.parse, SimulationSource.toJSONObject, [])}) + if properties is not None: + self.properties = properties + elif simulation_name is not None: + self.properties = SimulationProperties(simulationName=simulation_name) + else: + self.properties = SimulationProperties() + self.sources = [] + + @classmethod + def parse(cls, jsonObject): + ''' + Converts a Python Class Object (from JSON) to FeedSimulationConfiguration. + :param jsonObject: + :return: + ''' + result = FeedSimulationConfiguration(simulation_name=jsonObject["properties"]["simulationName"]) + result._parse(jsonObject) + return result diff --git a/PySiddhi4/das/EventSimulator/SimulationProperties.py b/PySiddhi4/das/EventSimulator/SimulationProperties.py new file mode 100644 index 0000000..9ca0be9 --- /dev/null +++ b/PySiddhi4/das/EventSimulator/SimulationProperties.py @@ -0,0 +1,44 @@ +import random + +from PySiddhi4.das.ObjectMapping.APIObject import APIObject, NotSet +from PySiddhi4.das.ObjectMapping.FieldMapping import FieldMapping +from PySiddhi4.das.__Util import decodeField + +ran = random + + +class SimulationProperties(APIObject): + ''' + SimulationProperties API Object of FeedSimulationConfiguration. + ''' + + def __init__(self, simulationName="Simulation_" + str(random.randint(1, 1000)), timestampStartTime=NotSet(), + timestampEndTime=NotSet(), noOfEvents=NotSet(), timeInterval=NotSet()): + ''' + Instantiates SimulationProperties + :param simulationName: name of simulation + :param timestampStartTime: + :param timestampEndTime: + :param noOfEvents: + :param timeInterval: + ''' + self._setup(field_mapping={"simulationName": FieldMapping(str), "timestampStartTime": FieldMapping(int), + "timestampEndTime": FieldMapping(int), "noOfEvents": FieldMapping(int), + "timeInterval": FieldMapping(int)}) + + self.simulationName = simulationName + self.timestampStartTime = timestampStartTime + self.timestampEndTime = timestampEndTime + self.noOfEvents = noOfEvents + self.timeInterval = timeInterval + + @classmethod + def parse(cls, jsonObject): + ''' + Converts a Python Class Object (from JSON) to SimulationProperties Object. + :param jsonObject: + :return: + ''' + result = SimulationProperties(simulationName=decodeField(jsonObject["simulationName"], str)) + result._parse(jsonObject) + return result diff --git a/PySiddhi4/das/EventSimulator/SimulationSource.py b/PySiddhi4/das/EventSimulator/SimulationSource.py new file mode 100644 index 0000000..b0e42b3 --- /dev/null +++ b/PySiddhi4/das/EventSimulator/SimulationSource.py @@ -0,0 +1,93 @@ +from enum import Enum + +from PySiddhi4.das.EventSimulator.AttributeConfiguration import AttributeConfiguration +from PySiddhi4.das.ObjectMapping.APIObject import APIObject, NotSet +from PySiddhi4.das.ObjectMapping.FieldMapping import FieldMapping, ListFieldMapping, strOrInt + + +class SimulationSource(APIObject): + ''' + SimulationSource APIObject which can be added to sources of FeedSimulationConfiguration + ''' + + class Type(Enum): + ''' + Type of SimulationSource + ''' + RANDOM_DATA_SIMULATION = "RANDOM_DATA_SIMULATION" + CSV_SIMULATION = "CSV_SIMULATION" + DATABASE_SIMULATION = "DATABASE_SIMULATION" + + @classmethod + def encode(cls, v): + return v.value + + @classmethod + def decode(cls, v): + return SimulationSource.Type(v) + + def __init__(self, simulationType=Type.RANDOM_DATA_SIMULATION, streamName=NotSet(), siddhiAppName=NotSet(), + timestampInterval=NotSet(), attributeConfiguration=NotSet(), + fileName=NotSet(), isOrdered=NotSet(), delimiter=NotSet(), timestampAttribute=NotSet(), + dataSourceLocation=NotSet(), driver=NotSet(), + username=NotSet(), password=NotSet(), tableName=NotSet(), columnNamesList=NotSet()): + ''' + Instantiates Simulation Source. Refer DAS4 Documentation for details on parameters + :param simulationType: Type of SimulationSource + :param streamName: + :param siddhiAppName: + :param timestampInterval: + :param attributeConfiguration: + :param fileName: for File Access + :param isOrdered: + :param delimiter: + :param timestampAttribute: + :param dataSourceLocation: + :param driver: for DB Access + :param username: for DB access + :param password: for DB Access + :param tableName: for DB Access + :param columnNamesList: for DB Access + ''' + self._setup( + field_mapping={"simulationType": FieldMapping(SimulationSource.Type.decode, SimulationSource.Type.encode), + "streamName": FieldMapping(str), + "siddhiAppName": FieldMapping(str), "timestampInterval": FieldMapping(int), + "attributeConfiguration": ListFieldMapping(AttributeConfiguration.parse, + AttributeConfiguration.toJSONObject, []), + "fileName": FieldMapping(str), "isOrdered": FieldMapping(bool), + "delimiter": FieldMapping(str), + "timestampAttribute": FieldMapping(strOrInt), "dataSourceLocation": FieldMapping(str), + "driver": FieldMapping(str), + "username": FieldMapping(str), "password": FieldMapping(str), "tableName": FieldMapping(str), + "columnNamesList": FieldMapping(str)}) + + self.simulationType = simulationType + self.streamName = streamName + self.siddhiAppName = siddhiAppName + self.timestampInterval = timestampInterval + if attributeConfiguration == NotSet(): + self.attributeConfiguration = [] + else: + self.attributeConfiguration = attributeConfiguration + self.fileName = fileName + self.isOrdered = isOrdered + self.delimiter = delimiter + self.timestampAttribute = timestampAttribute + self.dataSourceLocation = dataSourceLocation + self.driver = driver + self.username = username + self.password = password + self.tableName = tableName + self.columnNamesList = columnNamesList + + @classmethod + def parse(cls, jsonObject): + ''' + Converts a Python Class Object (from JSON) to SimulationSource Object. + :param jsonObject: + :return: + ''' + result = SimulationSource() + result._parse(jsonObject) + return result diff --git a/PySiddhi4/das/EventSimulator/SingleSimulationConfiguration.py b/PySiddhi4/das/EventSimulator/SingleSimulationConfiguration.py new file mode 100644 index 0000000..066b1bd --- /dev/null +++ b/PySiddhi4/das/EventSimulator/SingleSimulationConfiguration.py @@ -0,0 +1,22 @@ +from PySiddhi4.das.ObjectMapping.APIObject import APIObject +from PySiddhi4.das.ObjectMapping.FieldMapping import FieldMapping, ListFieldMapping + + +class SingleSimulationConfiguration(APIObject): + ''' + SingleSimulationConfiguration APIObject which may be passed to WSO2 DAS Event Simulator via EventSimulatorClient. + ''' + def __init__(self, siddhiAppName, streamName, data): + ''' + Instantiates SingleSimulationConfiguration + :param siddhiAppName: + :param streamName: + :param data: + ''' + self._setup(field_mapping={"siddhiAppName":FieldMapping(str),"streamName":FieldMapping(str), + "data":ListFieldMapping(int,str, []), "timestamp":FieldMapping(int)}) + self.siddhiAppName = siddhiAppName + self.streamName = streamName + self.data = data + self.timestamp = None + diff --git a/PySiddhi4/das/EventSimulator/__init__.py b/PySiddhi4/das/EventSimulator/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/PySiddhi4/das/ObjectMapping/APIObject.py b/PySiddhi4/das/ObjectMapping/APIObject.py new file mode 100644 index 0000000..1db935b --- /dev/null +++ b/PySiddhi4/das/ObjectMapping/APIObject.py @@ -0,0 +1,82 @@ +from abc import ABCMeta +from future.utils import with_metaclass + +from PySiddhi4.das.__Util import decodeField, encodeField + +class NotSet(object): + ''' + Denotes that a fields value is not set. (null) + ''' + def __ne__(self, other): + return not self.__eq__(other) + def __eq__(self, other): + if isinstance(other,NotSet): + return True + return False + +class APIObject(with_metaclass(ABCMeta,object)): + ''' + Abstract Object representing a model used by Rest API + ''' + def __new__(cls, *args, **kwargs): + instance = object.__new__(cls) + instance._field_mapping = None + return instance + + def _setup(self, field_mapping): + ''' + Setup the APIObject using field mapping details provided + :param field_mapping: details on mappings between JSON object fields and Python Class (model) fields + :return: + ''' + self._field_mapping = field_mapping + for k,v in field_mapping.items(): + setattr(self,k,v.default_value) + + def __ne__(self, other): + ''' + Compare inequality between two API Objects + :param other: + :return: + ''' + # Note: Python2 requires explicit declaration of __ne__ for proper operation. + return not self.__eq__(other) + + def __eq__(self, other): + ''' + Compare equality between two API Objects + :param other: + :return: + ''' + if type(self) != type(other): + return False + for k,v in self._field_mapping.items(): + v1 = getattr(self,k,v.default_value) + v2 = getattr(other,k,v.default_value) + if(getattr(self,k,v.default_value) != getattr(other,k,v.default_value)): + return False + return True + + def toJSONObject(self): + ''' + Obtain JSON object of the APIObject + :return: + ''' + result = {} + for k,v in self._field_mapping.items(): + val = getattr(self,k,v.default_value) + if(v.addDefaultField or getattr(self,k,v.default_value) != v.default_value): + result[k] = encodeField(getattr(self,k,v.default_value),v.encode_function) + return result + + def _parse(self, jsonObject): + ''' + Obtain APIObject using JSONObject + :param jsonObject: + :return: + ''' + for k,v in self._field_mapping.items(): + if k in jsonObject.keys(): + setattr(self,k,decodeField(jsonObject[k],v.decode_function)) + else: + setattr(self,k,v.default_value) diff --git a/PySiddhi4/das/ObjectMapping/FieldMapping.py b/PySiddhi4/das/ObjectMapping/FieldMapping.py new file mode 100644 index 0000000..bc73775 --- /dev/null +++ b/PySiddhi4/das/ObjectMapping/FieldMapping.py @@ -0,0 +1,55 @@ +from PySiddhi4.das.ObjectMapping.APIObject import NotSet +from PySiddhi4.das.__Util import encodeField, decodeField + +def strOrInt(v): + ''' + Determines whether v is String or Integer and returns appropriate object. + :param v: + :return: + ''' + v = str(v) + if str.isnumeric(v): + return int(v) + else: + return v + +class FieldMapping(object): + ''' + Describes a mapping of a field between JSON Object and APIObject + ''' + def __init__(self, decode_function, encode_function=str, default_value=NotSet(), addDefaultField=False): + ''' + Creates a field mapping between JSON Object field and API Object field + :param decode_function: converts JSON field value to APIObject field value + :param encode_function: converts APIObject field value JSON Object field value + :param default_value: default value of APIObject field + :param addDefaultField: set True to include the field in JSON Object even if the value is default + ''' + self.encode_function = encode_function + self.decode_function = decode_function + self.default_value = default_value + self.addDefaultField = addDefaultField + +class ListFieldMapping(FieldMapping): + ''' + Describes a mapping between List of API Objects and a List of JSON Objects + ''' + def __init__(self, decode_function, encode_function, default_value=[]): + ''' + Creates a mapping between a List of API Objects and a List of JSON Objects + :param decode_function: converts a JSON Object List item APIObject List item + :param encode_function: converts an APIObject List item to JSON Object List item + :param default_value: default value to be used when field (associating List) is absent + ''' + def encode_func(input_object): + result_object = [] + for item in input_object: + result_object.append(encodeField(item,encode_function)) + return result_object + + def decode_func(input_object): + result_object = [] + for item in input_object: + result_object.append(decodeField(item,decode_function)) + return result_object + FieldMapping.__init__(self,decode_func,encode_func,default_value) diff --git a/PySiddhi4/das/ObjectMapping/__init__.py b/PySiddhi4/das/ObjectMapping/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/PySiddhi4/das/SiddhiAppManagement/SiddhiAppManagementClient.py b/PySiddhi4/das/SiddhiAppManagement/SiddhiAppManagementClient.py new file mode 100644 index 0000000..d786c72 --- /dev/null +++ b/PySiddhi4/das/SiddhiAppManagement/SiddhiAppManagementClient.py @@ -0,0 +1,140 @@ +from enum import Enum + +from PySiddhi4.das.__Communication.RestClient import RestClient + +class UpdateAppStatusResponse(Enum): + ''' + Response from WSO2 DAS on updateSidhdiApp call of SiddhiAppManagementClient. + ''' + savedNew=201, + updated=200 + +class SiddhiAppManagementClient(RestClient): + ''' + Client for Siddhi App Management (publish, edit, list, retrieve etc.) in WSO2 DAS. + ''' + def __init__(self, siddhi_apps_url): + ''' + Instantiates SiddhiAppMangementClient. + :param siddhi_apps_url: url to siddhi_apps endpoint (e.g. root_url + '/siddhi-apps') + ''' + RestClient.__init__(self,siddhi_apps_url) + + def retrieveSiddhiApp(self, siddhiAppName): + ''' + Retrieve siddhiApp stored in WSO2 DAS. + :param siddhiAppName: + :return: + ''' + r = self._sendGetRequest("/" + siddhiAppName) + if r.status_code == 200: + result = r.json() + if "content" in result.keys(): + siddhiApp = result["content"] + return siddhiApp + else: + raise Exception("No content defined in response") + elif r.status_code == 404: + raise Exception("Siddhi App with specified name does not exist.") + else: + raise Exception(str(r.status_code) + ": " + r.text) + + + def deleteSiddhiApp(self, siddhiAppName): + ''' + Deletes a SiddhiApp stored in WSO2 DAS. + :param siddhiAppName: + :return: + ''' + r = self._sendDeleteRequest("/" + siddhiAppName) + if r.status_code == 200: + return True + elif r.status_code == 400: + raise Exception("Siddhi App name provided is invalid.") + elif r.status_code == 404: + raise Exception("Siddhi App with specified name does not exist.") + elif r.status_code == 500: + raise Exception(str(r.status_code) + ": " + r.text) + else: + raise Exception(str(r.status_code) + ": " + r.text) + + + def retrieveStatusSiddhiApp(self, siddhiAppName): + ''' + Retrieve the status of a SiddhiApp in WSO2 DAS. + :param siddhiAppName: + :return: + ''' + r = self._sendGetRequest("/" + siddhiAppName + "/status") + if r.status_code == 200: + result = r.json() + if "status" in result.keys(): + status = result["status"] + return status + else: + raise Exception("No content defined in response") + elif r.status_code == 404: + raise Exception("Siddhi App with specified name does not exist.") + else: + raise Exception(str(r.status_code) + ": " + r.text) + + def listSiddhiApps(self, isActive=None): + ''' + Obtains the list of Siddhi Apps in WSO2 DAS. + :param isActive: + :return: + ''' + params = None + if isActive is not None: + params = {"isActive":isActive} + r = self._sendGetRequest("/",params=params) + if r.status_code == 200: + result = r.json() + return result + else: + raise Exception(str(r.status_code) + ": " + r.text) + + def updateSiddhiApp(self, siddhiApp): + ''' + Updates a Siddhi App in WSO2 DAS. + :param siddhiApp: + :return: + ''' + r = self._sendPutRequest("/", data=siddhiApp) + if r.status_code == 200 or r.status_code == 201: + result = r.json() + if result["type"] == "success": + if r.status_code == 200: + return UpdateAppStatusResponse.updated + elif r.status_code == 201: + return UpdateAppStatusResponse.savedNew + else: + raise Exception("Result 'type' not 'success'") + elif r.status_code == 400: + raise Exception("A validation error occured.") + elif r.status_code == 500: + raise Exception("An unexpected error occured.") + else: + raise Exception(str(r.status_code) + ": " + r.text) + + def saveSiddhiApp(self, siddhiApp): + ''' + Saves a Siddhi App to WSO2 DAS. + :param siddhiApp: + :return: + ''' + r = self._sendPostRequest("/",data=siddhiApp) + if r.status_code == 201: + result = r.json() + if result["type"] == "success": + return True + else: + raise Exception("Result 'type' not 'success'") + elif r.status_code == 400: + raise Exception("A validation error occured.") + elif r.status_code == 409: + raise Exception("A Siddhi Application with the given name already exists.") + elif r.status_code == 500: + raise Exception("An unexpected error occured.") + else: + raise Exception(str(r.status_code) + ": " + r.text) \ No newline at end of file diff --git a/PySiddhi4/das/SiddhiAppManagement/__init__.py b/PySiddhi4/das/SiddhiAppManagement/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/PySiddhi4/das/__Communication/RestClient.py b/PySiddhi4/das/__Communication/RestClient.py new file mode 100644 index 0000000..62ce193 --- /dev/null +++ b/PySiddhi4/das/__Communication/RestClient.py @@ -0,0 +1,59 @@ +import requests +class RestClient(object): + ''' + REST Client used internally to communicate with REST server + ''' + def __init__(self, base_url): + ''' + Instantiate Rest Client + :param base_url: root url used + ''' + self.base_url = base_url + + def _sendGetRequest(self, sub_url, params=None): + ''' + Sends a GET Request to Server + :param sub_url: endpoint url which is to be appended to base url + :param params: get parameters + :return: + ''' + headers = {'content-type': 'text/plain'} + resp = requests.get(self.base_url + sub_url, params=params, headers = headers) + return resp + + def _sendPostRequest(self, sub_url, data=None, params = None, files=None, headers=None): + ''' + Sends a POST Request to server + :param sub_url: endpoint url which is to be appended to base url + :param data: Payload data sent + :param params: URL Parameters + :param files: File Uploads + :param headers: Custom headers + :return: + ''' + resp = requests.post(self.base_url + sub_url, params=params, data=data, headers = headers,files=files) + return resp + + def _sendPutRequest(self, sub_url, data=None, params=None, files=None, headers=None): + ''' + Sends a PUT Request to server + :param sub_url: endpoint url which is to be appended to base url + :param data: Payload data sent + :param params: URL Parameters + :param files: File Uploads + :param headers: Custom headers + :return: + ''' + resp = requests.put(self.base_url + sub_url, params=params, files=files ,data=data, headers=headers) + return resp + + def _sendDeleteRequest(self, sub_url,params = None): + ''' + Sends a DELETE Request to server + :param sub_url: endpoint url which is to be appended to base url + :param params: URL Parameters + :return: + ''' + headers = {'content-type': 'text/plain'} + resp = requests.delete(self.base_url + sub_url, params=params, headers = headers) + return resp \ No newline at end of file diff --git a/PySiddhi4/das/__Communication/__init__.py b/PySiddhi4/das/__Communication/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/PySiddhi4/das/__Util.py b/PySiddhi4/das/__Util.py new file mode 100644 index 0000000..6f2b0af --- /dev/null +++ b/PySiddhi4/das/__Util.py @@ -0,0 +1,34 @@ +def encodeField(value, encode_function=str): + ''' + Encodes a field value using encode_function + :param value: + :param encode_function: + :return: + ''' + if value is None: + return None + return encode_function(value) + +def decodeField(value, decode_function): + ''' + Decodes a field value using given decode_function + :param value: + :param decode_function: + :return: + ''' + if value is None: + return None + return decode_function(value) + + +def decodeObject(jsonObject,target, decodeMap): + ''' + Decodes a JSON Object and assigns attributes to target. + :param jsonObject: + :param target: + :param decodeMap: + :return: + ''' + for (key,value) in jsonObject.items(): + setattr(target, key,decodeField(value, decodeMap[key])) + return target \ No newline at end of file diff --git a/PySiddhi4/das/__init__.py b/PySiddhi4/das/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Requirements.txt b/Requirements.txt index 6351c5e..35e6945 100644 --- a/Requirements.txt +++ b/Requirements.txt @@ -1,3 +1,4 @@ pyjnius enum34 -future \ No newline at end of file +future +requests \ No newline at end of file diff --git a/Tests/DASTests/EventSimulatorTests.py b/Tests/DASTests/EventSimulatorTests.py new file mode 100644 index 0000000..d18ac0b --- /dev/null +++ b/Tests/DASTests/EventSimulatorTests.py @@ -0,0 +1,820 @@ +import unittest + +import logging +import os +from time import sleep + +from PySiddhi4.das.DASClient import DASClient +from PySiddhi4.das.EventSimulator.AttributeConfiguration import AttributeConfiguration +from PySiddhi4.das.EventSimulator.FeedSimulationConfiguration import FeedSimulationConfiguration +from PySiddhi4.das.EventSimulator.SimulationSource import SimulationSource +from PySiddhi4.das.EventSimulator.SingleSimulationConfiguration import SingleSimulationConfiguration + +logging.basicConfig(level=logging.INFO) + +resources_path = os.path.join(os.path.dirname(__file__), "Resources/") + +class EventSimulatorTests(unittest.TestCase): + def setUp(self): + self.hostUrl = "http://localhost:9090" + #self.simulationUrl = self.hostUrl + "/simulation" + logging.info("Prior to launching tests, make sure DAS 4 is running at " + self.hostUrl) + + def tearDown(self): + sleep(5) # Sleep to provide sufficient time for DAS 4.0 to update status + + def testSingleSimulation(self): + logging.info("Test: Simulating a Single Event") + + dasPythonClient = DASClient(self.hostUrl) + eventSimulatorClient = dasPythonClient.getEventSimulatorClient() + + singleSimulationConfiguration = SingleSimulationConfiguration("TestSiddhiApp","FooStream",[None, 9, 45]) + + self.assertTrue(eventSimulatorClient.simulateSingleEvent(singleSimulationConfiguration)) + logging.info("Successfully Simulated Single Event") + + def testCSVUploadAndDelete(self): + logging.info("Test: Uploading and Deleting a CSV.") + + dasPythonClient = DASClient(self.hostUrl) + eventSimulatorClient = dasPythonClient.getEventSimulatorClient() + + self.assertTrue(eventSimulatorClient.uploadCSV("sample.csv",path=resources_path+"sample.csv")) + logging.info("Successfully Uploaded CSV") + + sleep(5) + + self.assertTrue(eventSimulatorClient.deleteCSV("sample.csv")) + logging.info("Successfully Deleted CSV") + + + def testCSVUpdate(self): + logging.info("Test: Uploading, Updating and Deleting a CSV.") + + dasPythonClient = DASClient(self.hostUrl) + eventSimulatorClient = dasPythonClient.getEventSimulatorClient() + + self.assertTrue(eventSimulatorClient.uploadCSV("sample.csv",path=resources_path+"sample.csv")) + logging.info("Successfully Uploaded CSV") + + sleep(5) + + self.assertTrue(eventSimulatorClient.updateCSV("sample.csv","sample2.csv", path=resources_path + "sample.csv")) + logging.info("Successfully Uploaded CSV") + + sleep(5) + + self.assertTrue(eventSimulatorClient.deleteCSV("sample2.csv")) + logging.info("Successfully Deleted CSV") + + + def testSaveDeleteSimulationFeedConfiguration(self): + logging.info("Test1: Saving and Deleting simulation feed configuration") + + dasPythonClient = DASClient(self.hostUrl) + eventSimulatorClient = dasPythonClient.getEventSimulatorClient() + + svr = FeedSimulationConfiguration("simulationPrimitive") + svr.properties.timestampStartTime = 1488615136958 + svr.properties.timestampEndTime = None + svr.properties.noOfEvents = 8 + svr.properties.timeInterval = 1000 + + sm1 = SimulationSource(simulationType=SimulationSource.Type.RANDOM_DATA_SIMULATION, streamName="FooStream", siddhiAppName="TestSiddhiApp", timestampInterval=5) + + sm1.attributeConfiguration.append(AttributeConfiguration(AttributeConfiguration.Type.PRIMITIVE_BASED, length=10)) + sm1.attributeConfiguration.append(AttributeConfiguration(AttributeConfiguration.Type.PRIMITIVE_BASED, min=35000, max=30000, precision=2)) + sm1.attributeConfiguration.append(AttributeConfiguration(AttributeConfiguration.Type.PRIMITIVE_BASED, min=150, max=300)) + + svr.sources.append(sm1) + + self.assertTrue(eventSimulatorClient.saveSimulationFeedConfiguration(svr)) + logging.info("Successfully Saved Simulation Feed Configuration") + self.assertTrue(eventSimulatorClient.deleteSimulationFeedConfiguration("simulationPrimitive")) + logging.info("Successfully Deleted Simulation Feed Configuration") + + def testEditSimulationFeedConfiguration(self): + logging.info("Test1: Saving, Editing and Deleting simulation feed configuration") + + dasPythonClient = DASClient(self.hostUrl) + eventSimulatorClient = dasPythonClient.getEventSimulatorClient() + + svr = FeedSimulationConfiguration("simulationPrimitive") + svr.properties.timestampStartTime = 1488615136958 + svr.properties.timestampEndTime = None + svr.properties.noOfEvents = 8 + svr.properties.timeInterval = 1000 + + sm1 = SimulationSource(simulationType=SimulationSource.Type.RANDOM_DATA_SIMULATION, streamName="FooStream", siddhiAppName="TestSiddhiApp", timestampInterval=5) + + sm1.attributeConfiguration.append(AttributeConfiguration(AttributeConfiguration.Type.PRIMITIVE_BASED, length=10)) + sm1.attributeConfiguration.append(AttributeConfiguration(AttributeConfiguration.Type.PRIMITIVE_BASED, min=35000, max=30000, precision=2)) + sm1.attributeConfiguration.append(AttributeConfiguration(AttributeConfiguration.Type.PRIMITIVE_BASED, min=150, max=300)) + + svr.sources.append(sm1) + + self.assertTrue(eventSimulatorClient.saveSimulationFeedConfiguration(svr)) + logging.info("Successfully Saved Simulation Feed Configuration") + sleep(5) + + svr.properties.simulationName = "simulationNewName" + self.assertTrue(eventSimulatorClient.editSimulationFeedConfiguration("simulationPrimitive",svr)) + logging.info("Successfully Editted Simulation Feed Configuration") + sleep(5) + + self.assertTrue(eventSimulatorClient.deleteSimulationFeedConfiguration("simulationNewName")) + logging.info("Successfully Deleted Simulation Feed Configuration") + + + def testRetrieveSimulationFeedConfiguration(self): + logging.info("Test1: Saving, Retrieving and Deleting simulation feed configuration") + + dasPythonClient = DASClient(self.hostUrl) + eventSimulatorClient = dasPythonClient.getEventSimulatorClient() + + svr = FeedSimulationConfiguration("simulationPrimitive") + svr.properties.timestampStartTime = 1488615136958 + svr.properties.timestampEndTime = None + svr.properties.noOfEvents = 8 + svr.properties.timeInterval = 1000 + + sm1 = SimulationSource(simulationType=SimulationSource.Type.RANDOM_DATA_SIMULATION, streamName="FooStream", siddhiAppName="TestSiddhiApp", timestampInterval=5) + + sm1.attributeConfiguration.append(AttributeConfiguration(AttributeConfiguration.Type.PRIMITIVE_BASED, length=10)) + sm1.attributeConfiguration.append(AttributeConfiguration(AttributeConfiguration.Type.PRIMITIVE_BASED, min=35000, max=30000, precision=2)) + sm1.attributeConfiguration.append(AttributeConfiguration(AttributeConfiguration.Type.PRIMITIVE_BASED, min=150, max=300)) + + svr.sources.append(sm1) + + self.assertTrue(eventSimulatorClient.saveSimulationFeedConfiguration(svr), "Unable to Save " + "SimulationConfiguration") + + sleep(5) + retrieveObject = eventSimulatorClient.retrieveSimulationFeedConfiguration("simulationPrimitive") + self.assertTrue(retrieveObject == svr, "Retrieved SimulationConfigurations does not match") + + sleep(5) + self.assertTrue(eventSimulatorClient.deleteSimulationFeedConfiguration("simulationPrimitive"),"Unable to delete" + "SimulationConfiguration") + + + def testRandomSimulationCustomList(self): + logging.info("Test: Random Simulation using Custom List") + + dasPythonClient = DASClient(self.hostUrl) + eventSimulatorClient = dasPythonClient.getEventSimulatorClient() + + svr = FeedSimulationConfiguration("sim") + svr.properties.timestampStartTime = 1488615136958 + svr.properties.timestampEndTime = 1488615136998 + svr.properties.noOfEvents = 5 + svr.properties.timeInterval = 1000 + + s1 = SimulationSource(simulationType=SimulationSource.Type.RANDOM_DATA_SIMULATION) + s1.streamName = "FooStream" + s1.siddhiAppName = "TestSiddhiApp" + s1.timestampInterval = 5 + svr.sources.append(s1) + + s1.attributeConfiguration.append( + AttributeConfiguration(type=AttributeConfiguration.Type.CUSTOM_DATA_BASED,list=["WSO2,AAA","DDD","IBM"])) + s1.attributeConfiguration.append( + AttributeConfiguration(type=AttributeConfiguration.Type.CUSTOM_DATA_BASED, list=[1.0,2.0,3.0])) + s1.attributeConfiguration.append( + AttributeConfiguration(type=AttributeConfiguration.Type.CUSTOM_DATA_BASED, list=[10, 20, 30])) + + self.assertTrue(eventSimulatorClient.saveSimulationFeedConfiguration(svr)) + logging.info("Successfully Saved Simulation Feed Configuration") + + sleep(5) + + self.assertTrue(eventSimulatorClient.deleteSimulationFeedConfiguration(svr.properties.simulationName)) + logging.info("Successfully Deleted Simulation Feed Configuration") + + def testCSVSimulationSingleSource(self): + logging.info("Test: CSV Simulation - One Source") + + dasPythonClient = DASClient(self.hostUrl) + eventSimulatorClient = dasPythonClient.getEventSimulatorClient() + + svr = FeedSimulationConfiguration("simulation1") + svr.properties.timestampStartTime = None + svr.properties.timeInterval = 8000 + + s1 = SimulationSource(simulationType=SimulationSource.Type.CSV_SIMULATION) + s1.streamName = "FooStream" + s1.siddhiAppName = "TestSiddhiApp" + s1.fileName = "sample.csv" + s1.timestampInterval = 1000 + s1.isOrdered = True + s1.delimiter = "," + svr.sources.append(s1) + + self.assertTrue(eventSimulatorClient.uploadCSV("sample.csv", path=resources_path + "sample.csv")) + logging.info("Successfully Uploaded CSV") + + sleep(5) + + self.assertTrue(eventSimulatorClient.saveSimulationFeedConfiguration(svr)) + logging.info("Successfully Saved Simulation Feed Configuration") + + sleep(5) + + self.assertTrue(eventSimulatorClient.deleteSimulationFeedConfiguration(svr.properties.simulationName)) + logging.info("Successfully Deleted Simulation Feed Configuration") + + self.assertTrue(eventSimulatorClient.deleteCSV("sample.csv")) + logging.info("Successfully Deleted CSV") + + + def testCSVSimulationTwoSource(self): + logging.info("Test: CSV Simulation - Two Source") + + dasPythonClient = DASClient(self.hostUrl) + eventSimulatorClient = dasPythonClient.getEventSimulatorClient() + + svr = FeedSimulationConfiguration("simCSV2") + svr.properties.timestampStartTime = 1488615136957 + svr.properties.timestampEndTime = 1488615136973 + svr.properties.noOfEvents = 7 + svr.properties.timeInterval = 1000 + + s1 = SimulationSource(simulationType=SimulationSource.Type.CSV_SIMULATION) + s1.streamName = "FooStream" + s1.siddhiAppName = "TestSiddhiApp" + s1.fileName = "sample.csv" + s1.timestampAttribute=0 + s1.isOrdered = True + s1.delimiter = "," + svr.sources.append(s1) + + s2 = SimulationSource(simulationType=SimulationSource.Type.CSV_SIMULATION) + s2.streamName = "FooStream" + s2.siddhiAppName = "TestSiddhiApp" + s2.fileName = "sample.csv" + s2.timestampAttribute = 0 + s2.isOrdered = True + s2.delimiter = "," + svr.sources.append(s2) + + self.assertTrue(eventSimulatorClient.uploadCSV("sample.csv", path=resources_path + "sample.csv")) + logging.info("Successfully Uploaded CSV") + + sleep(5) + + self.assertTrue(eventSimulatorClient.saveSimulationFeedConfiguration(svr)) + logging.info("Successfully Saved Simulation Feed Configuration") + + sleep(5) + + self.assertTrue(eventSimulatorClient.deleteSimulationFeedConfiguration(svr.properties.simulationName)) + logging.info("Successfully Deleted Simulation Feed Configuration") + + self.assertTrue(eventSimulatorClient.deleteCSV("sample.csv")) + logging.info("Successfully Deleted CSV") + + + + def testDBSimulationOneSource(self): + logging.info("Test: DB Simulation - One Source") + + target = { + "properties": { + "simulationName": "simDb", + "timestampStartTime": "1488615136958", + "timestampEndTime": None, + "noOfEvents" : None, + "timeInterval": "1000" + }, + "sources": [ + { + "simulationType": "DATABASE_SIMULATION", + "streamName": "FooStream", + "siddhiAppName": "TestSiddhiApp", + "dataSourceLocation": "jdbc:mysql:\/\/localhost:3306\/DatabaseFeedSimulation", + "driver" : "com.mysql.jdbc.Driver", + "username": "root", + "password": "root", + "tableName": "foostream3", + "timestampInterval": "1000", + "columnNamesList": None + } + ] + } + + dasPythonClient = DASClient(self.hostUrl) + eventSimulatorClient = dasPythonClient.getEventSimulatorClient() + + svr = FeedSimulationConfiguration("simDb") + svr.properties.timestampStartTime = 1488615136958 + svr.properties.timestampEndTime = None + svr.properties.noOfEvents = None + svr.properties.timeInterval = 1000 + + s1 = SimulationSource(simulationType=SimulationSource.Type.DATABASE_SIMULATION) + s1.streamName = "FooStream" + s1.siddhiAppName = "TestSiddhiApp" + s1.dataSourceLocation = "jdbc:mysql:\/\/localhost:3306\/DatabaseFeedSimulation" + s1.driver="com.mysql.jdbc.Driver" + s1.username="root" + s1.password="root" + s1.tableName="foostream3" + s1.timestampInterval=1000 + s1.columnNamesList=None + svr.sources.append(s1) + + match = svr.toJSONObject() + + self.assertDictEqual(target,match) + + self.assertTrue(eventSimulatorClient.saveSimulationFeedConfiguration(svr)) + logging.info("Successfully Saved Simulation Feed Configuration") + + sleep(5) + + self.assertTrue(eventSimulatorClient.deleteSimulationFeedConfiguration(svr.properties.simulationName)) + logging.info("Successfully Deleted Simulation Feed Configuration") + + + def testDBSimulationTwoSource(self): + logging.info("Test: DB Simulation - Two Sources") + + dasPythonClient = DASClient(self.hostUrl) + eventSimulatorClient = dasPythonClient.getEventSimulatorClient() + + svr = FeedSimulationConfiguration("simDb") + svr.properties.timestampStartTime = 1488615136958 + svr.properties.timestampEndTime = None + svr.properties.noOfEvents = None + svr.properties.timeInterval = 1000 + + s1 = SimulationSource(simulationType=SimulationSource.Type.DATABASE_SIMULATION) + s1.streamName = "FooStream" + s1.siddhiAppName = "TestSiddhiApp" + s1.dataSourceLocation = "jdbc:mysql:\/\/localhost:3306\/DatabaseFeedSimulation" + s1.driver = "com.mysql.jdbc.Driver" + s1.username = "root" + s1.password = "root" + s1.tableName = "foostream3" + s1.timestampInterval = 1000 + s1.columnNamesList = None + svr.sources.append(s1) + + + self.assertTrue(eventSimulatorClient.saveSimulationFeedConfiguration(svr)) + logging.info("Successfully Saved Simulation Feed Configuration") + + sleep(5) + + target = { + "properties": { + "simulationName": "simDb", + "timestampStartTime": "1488615136958", + "timestampEndTime": "1488615136961", + "timeInterval": "1000" + }, + "sources": [ + { + "simulationType": "DATABASE_SIMULATION", + "streamName": "FooStream", + "siddhiAppName": "TestSiddhiApp", + "dataSourceLocation": "jdbc:mysql:\/\/localhost:3306\/DatabaseFeedSimulation", + "driver" : "com.mysql.jdbc.Driver", + "username": "root", + "password": "root", + "tableName": "foostream4", + "timestampAttribute": "timestamp", + "columnNamesList": "symbol,price,volume" + }, + { + "simulationType": "DATABASE_SIMULATION", + "streamName": "FooStream", + "siddhiAppName": "TestSiddhiApp", + "dataSourceLocation": "jdbc:mysql:\/\/localhost:3306\/Simulation", + "driver" : "com.mysql.jdbc.Driver", + "username": "root", + "password": "root", + "tableName": "foostream", + "timestampAttribute": "timestamp", + "columnNamesList": "name,price,volume" + } + ] + } + + + svr = FeedSimulationConfiguration("simDb") + svr.properties.timestampStartTime = 1488615136958 + svr.properties.timestampEndTime = 1488615136961 + svr.properties.timeInterval = 1000 + + s1 = SimulationSource(simulationType=SimulationSource.Type.DATABASE_SIMULATION) + s1.streamName = "FooStream" + s1.siddhiAppName = "TestSiddhiApp" + s1.dataSourceLocation = "jdbc:mysql:\/\/localhost:3306\/DatabaseFeedSimulation" + s1.driver="com.mysql.jdbc.Driver" + s1.username="root" + s1.password="root" + s1.tableName="foostream4" + s1.timestampAttribute="timestamp" + s1.columnNamesList="symbol,price,volume" + svr.sources.append(s1) + + s2 = SimulationSource(simulationType=SimulationSource.Type.DATABASE_SIMULATION) + s2.streamName = "FooStream" + s2.siddhiAppName = "TestSiddhiApp" + s2.dataSourceLocation = "jdbc:mysql:\/\/localhost:3306\/Simulation" + s2.driver = "com.mysql.jdbc.Driver" + s2.username = "root" + s2.password = "root" + s2.tableName = "foostream" + s2.timestampAttribute = "timestamp" + s2.columnNamesList = "name,price,volume" + svr.sources.append(s2) + + match = svr.toJSONObject() + + self.assertDictEqual(target,match) + + self.assertTrue(eventSimulatorClient.runSimulationFeedConfiguration(svr)) + logging.info("Successfully Started Simulation Feed Configuration") + + sleep(5) + + self.assertTrue(eventSimulatorClient.deleteSimulationFeedConfiguration(svr.properties.simulationName)) + logging.info("Successfully Deleted Simulation Feed Configuration") + + + def testDBSimulationOneSourceWOColumnNames(self): + logging.info("Test: DB Simulation - One Source w\o column names") + + target={ + "properties": { + "simulationName": "simDbNoColumnsList", + "timestampStartTime": "1488615136958", + "timestampEndTime": "1488615136961", + "timeInterval": "1000" + }, + "sources": [ + { + "simulationType": "DATABASE_SIMULATION", + "streamName": "FooStream", + "siddhiAppName": "TestSiddhiApp", + "dataSourceLocation": "jdbc:mysql:\/\/localhost:3306\/DatabaseFeedSimulation", + "driver" : "com.mysql.jdbc.Driver", + "username": "root", + "password": "root", + "tableName": "foostream3", + "timestampAttribute": "timestamp", + "columnNamesList": None + } + ] + } + + dasPythonClient = DASClient(self.hostUrl) + eventSimulatorClient = dasPythonClient.getEventSimulatorClient() + + svr = FeedSimulationConfiguration("simDbNoColumnsList") + svr.properties.timestampStartTime = 1488615136958 + svr.properties.timestampEndTime = 1488615136961 + svr.properties.timeInterval = 1000 + + s1 = SimulationSource(simulationType=SimulationSource.Type.DATABASE_SIMULATION) + s1.streamName = "FooStream" + s1.siddhiAppName = "TestSiddhiApp" + s1.dataSourceLocation = "jdbc:mysql:\/\/localhost:3306\/DatabaseFeedSimulation" + s1.driver="com.mysql.jdbc.Driver" + s1.username="root" + s1.password="root" + s1.tableName="foostream3" + s1.timestampAttribute="timestamp" + s1.columnNamesList=None + svr.sources.append(s1) + + match = svr.toJSONObject() + + self.assertDictEqual(target,match) + + self.assertTrue(eventSimulatorClient.saveSimulationFeedConfiguration(svr)) + logging.info("Successfully Saved Simulation Feed Configuration") + + sleep(5) + + self.assertTrue(eventSimulatorClient.runSimulationFeedConfiguration(svr)) + logging.info("Successfully Started Simulation Feed Configuration") + + sleep(5) + + self.assertTrue(eventSimulatorClient.deleteSimulationFeedConfiguration(svr.properties.simulationName)) + logging.info("Successfully Deleted Simulation Feed Configuration") + + + def testPrimitiveRandomSimulation(self): + logging.info("Test: Random Simulation - Primitive") + + target = { + "properties": { + "simulationName": "simulationPrimitive", + "timestampStartTime": "1488615136958", + "timestampEndTime": None, + "noOfEvents" : "8", + "timeInterval": "1000" + }, + "sources": [ + { + "simulationType": "RANDOM_DATA_SIMULATION", + "streamName": "FooStream", + "siddhiAppName": "TestSiddhiApp", + "timestampInterval": "5", + "attributeConfiguration": [ + { + "type": "PRIMITIVE_BASED", + "length": "10" + }, + { + "type": "PRIMITIVE_BASED", + "min": "35000", + "max": "30000", + "precision": "2" + }, + { + "type": "PRIMITIVE_BASED", + "min": "150", + "max": "300" + } + ] + } + ] + } + + dasPythonClient = DASClient(self.hostUrl) + eventSimulatorClient = dasPythonClient.getEventSimulatorClient() + + svr = FeedSimulationConfiguration("simulationPrimitive") + svr.properties.timestampStartTime = 1488615136958 + svr.properties.timestampEndTime = None + svr.properties.noOfEvents=8 + svr.properties.timeInterval = 1000 + + s1 = SimulationSource(simulationType=SimulationSource.Type.RANDOM_DATA_SIMULATION, attributeConfiguration=list()) + s1.streamName = "FooStream" + s1.siddhiAppName = "TestSiddhiApp" + s1.timestampInterval = 5 + svr.sources.append(s1) + + s1.attributeConfiguration.append( + AttributeConfiguration(type=AttributeConfiguration.Type.PRIMITIVE_BASED,length=10)) + s1.attributeConfiguration.append( + AttributeConfiguration(type=AttributeConfiguration.Type.PRIMITIVE_BASED, min=35000, max=30000,precision=2)) + s1.attributeConfiguration.append( + AttributeConfiguration(type=AttributeConfiguration.Type.PRIMITIVE_BASED, min=150, max=300) + ) + + match = svr.toJSONObject() + + self.assertDictEqual(target, match) + + self.assertTrue(eventSimulatorClient.saveSimulationFeedConfiguration(svr)) + logging.info("Successfully Saved Simulation Feed Configuration") + + sleep(5) + + self.assertTrue(eventSimulatorClient.runSimulationFeedConfiguration(svr)) + logging.info("Successfully Started Simulation Feed Configuration") + + sleep(5) + + self.assertTrue(eventSimulatorClient.deleteSimulationFeedConfiguration(svr.properties.simulationName)) + logging.info("Successfully Deleted Simulation Feed Configuration") + + + + def testRandomSimulationRegexAndPrimitive(self): + logging.info("Test: Random Simulation - Regex and Primitive") + + target = { + "properties": { + "simulationName": "simRndm", + "timestampStartTime": "1488615136958", + "timestampEndTime": "1488615136998", + "noOfEvents" : None, + "timeInterval": "1000" + }, + "sources": [ + { + "simulationType": "RANDOM_DATA_SIMULATION", + "streamName": "FooStream", + "siddhiAppName": "TestSiddhiApp", + "timestampInterval": "5", + "attributeConfiguration": [ + { + "type": "REGEX_BASED", + "pattern": "[a-zA-Z]*" + }, + { + "type": "REGEX_BASED", + "pattern": "[0-9]*" + }, + { + "type": "PRIMITIVE_BASED", + "primitiveType": "LONG", + "min": "1500000", + "max": "30000000" + } + ] + } + ] + } + + dasPythonClient = DASClient(self.hostUrl) + eventSimulatorClient = dasPythonClient.getEventSimulatorClient() + + svr = FeedSimulationConfiguration("simRndm") + svr.properties.timestampStartTime = 1488615136958 + svr.properties.timestampEndTime = 1488615136998 + svr.properties.noOfEvents=None + svr.properties.timeInterval = 1000 + + s1 = SimulationSource(simulationType=SimulationSource.Type.RANDOM_DATA_SIMULATION) + s1.streamName = "FooStream" + s1.siddhiAppName = "TestSiddhiApp" + s1.timestampInterval = 5 + svr.sources.append(s1) + + s1.attributeConfiguration.append( + AttributeConfiguration(type=AttributeConfiguration.Type.REGEX_BASED,pattern="[a-zA-Z]*")) + s1.attributeConfiguration.append( + AttributeConfiguration(type=AttributeConfiguration.Type.REGEX_BASED, pattern="[0-9]*")) + s1.attributeConfiguration.append( + AttributeConfiguration(type=AttributeConfiguration.Type.PRIMITIVE_BASED, min=1500000, max=30000000, primitiveType=AttributeConfiguration.PrimitiveType.LONG) + ) + + match = svr.toJSONObject() + + self.assertDictEqual(target, match) + + self.assertTrue(eventSimulatorClient.saveSimulationFeedConfiguration(svr)) + logging.info("Successfully Saved Simulation Feed Configuration") + + sleep(5) + + self.assertTrue(eventSimulatorClient.runSimulationFeedConfiguration(svr)) + logging.info("Successfully Started Simulation Feed Configuration") + + sleep(5) + + self.assertTrue(eventSimulatorClient.deleteSimulationFeedConfiguration(svr.properties.simulationName)) + logging.info("Successfully Deleted Simulation Feed Configuration") + + + def testDBandCSVSimulation(self): + logging.info("Test: Random Simulation - Property and Primitive") + + target = { + "properties": { + "simulationName": "simulationCSV", + "timestampStartTime": "1488615136958", + "timestampEndTime": "1488615136966", + "timeInterval": "1000" + }, + "sources": [ + { + "simulationType": "DATABASE_SIMULATION", + "streamName": "FooStream", + "siddhiAppName": "TestSiddhiApp", + "dataSourceLocation": "jdbc:mysql:\/\/localhost:3306\/DatabaseFeedSimulation", + "driver" : "com.mysql.jdbc.Driver", + "username": "root", + "password": "root", + "tableName": "foostream3", + "timestampAttribute": "timestamp", + "columnNamesList": "symbol,price,volume" + }, + { + "simulationType": "CSV_SIMULATION", + "streamName": "FooStream", + "siddhiAppName": "TestSiddhiApp", + "fileName": "sample.csv", + "timestampAttribute": "0", + "isOrdered": "False", + "delimiter": "," + } + ] + } + + dasPythonClient = DASClient(self.hostUrl) + eventSimulatorClient = dasPythonClient.getEventSimulatorClient() + + svr = FeedSimulationConfiguration("simulationCSV") + svr.properties.timestampStartTime = 1488615136958 + svr.properties.timestampEndTime = 1488615136966 + svr.properties.timeInterval = 1000 + + s1 = SimulationSource(simulationType=SimulationSource.Type.DATABASE_SIMULATION) + s1.streamName = "FooStream" + s1.siddhiAppName = "TestSiddhiApp" + s1.dataSourceLocation = "jdbc:mysql:\/\/localhost:3306\/DatabaseFeedSimulation" + s1.driver = "com.mysql.jdbc.Driver" + s1.username = "root" + s1.password = "root" + s1.tableName = "foostream3" + s1.timestampAttribute = "timestamp" + s1.columnNamesList = "symbol,price,volume" + + svr.sources.append(s1) + + s2 = SimulationSource(simulationType=SimulationSource.Type.CSV_SIMULATION) + s2.streamName = "FooStream" + s2.siddhiAppName = "TestSiddhiApp" + s2.fileName = "sample.csv" + s2.timestampAttribute = 0 + s2.isOrdered = False + s2.delimiter = "," + + svr.sources.append(s2) + + match = svr.toJSONObject() + + self.assertDictEqual(target["sources"][1], match["sources"][1]) + + self.assertTrue(eventSimulatorClient.uploadCSV("sample.csv", path=resources_path + "sample.csv")) + logging.info("Successfully Uploaded CSV") + + sleep(5) + + + self.assertTrue(eventSimulatorClient.saveSimulationFeedConfiguration(svr)) + logging.info("Successfully Saved Simulation Feed Configuration") + + sleep(5) + + self.assertTrue(eventSimulatorClient.runSimulationFeedConfiguration(svr)) + logging.info("Successfully Started Simulation Feed Configuration") + + sleep(5) + + self.assertTrue(eventSimulatorClient.deleteSimulationFeedConfiguration(svr.properties.simulationName)) + logging.info("Successfully Deleted Simulation Feed Configuration") + + + self.assertTrue(eventSimulatorClient.deleteCSV("sample.csv")) + logging.info("Successfully Deleted CSV") + + + def testRunPausePrimitiveRandom(self): + logging.info("Test: Random Simulation - Primitive. Save, Run, Pause, Resume, Stop and Delete.") + + dasPythonClient = DASClient(self.hostUrl) + eventSimulatorClient = dasPythonClient.getEventSimulatorClient() + + svr = FeedSimulationConfiguration("simulationPrimitive") + svr.properties.noOfEvents=8 + svr.properties.timeInterval = 30000 + + s1 = SimulationSource(simulationType=SimulationSource.Type.RANDOM_DATA_SIMULATION) + s1.streamName = "FooStream" + s1.siddhiAppName = "TestSiddhiApp" + s1.timestampInterval = 5 + svr.sources.append(s1) + + s1.attributeConfiguration.append( + AttributeConfiguration(type=AttributeConfiguration.Type.PRIMITIVE_BASED,length=10)) + s1.attributeConfiguration.append( + AttributeConfiguration(type=AttributeConfiguration.Type.PRIMITIVE_BASED, min=35000, max=30000,precision=2)) + s1.attributeConfiguration.append( + AttributeConfiguration(type=AttributeConfiguration.Type.PRIMITIVE_BASED, min=150, max=300) + ) + + self.assertTrue(eventSimulatorClient.saveSimulationFeedConfiguration(svr)) + logging.info("Successfully Saved Simulation Feed Configuration") + + sleep(5) + + self.assertTrue(eventSimulatorClient.runSimulationFeedConfiguration(svr)) + logging.info("Successfully Started Simulation Feed Configuration") + + sleep(5) + + self.assertTrue(eventSimulatorClient.pauseSimulationFeedConfiguration(svr.properties.simulationName)) + logging.info("Successfully Paused Simulation Feed Configuration") + + sleep(5) + + self.assertTrue(eventSimulatorClient.resumeSimulationFeedConfiguration(svr.properties.simulationName)) + logging.info("Successfully Resumed Simulation Feed Configuration") + + sleep(5) + + self.assertTrue(eventSimulatorClient.stopSimulationFeedConfiguration(svr.properties.simulationName)) + logging.info("Successfully Stopped Simulation Feed Configuration") + + sleep(5) + + self.assertTrue(eventSimulatorClient.deleteSimulationFeedConfiguration(svr.properties.simulationName)) + logging.info("Successfully Deleted Simulation Feed Configuration") + + + + +if __name__ == '__main__': + unittest.main() diff --git a/Tests/DASTests/Resources/TestSiddhiApp.siddhi b/Tests/DASTests/Resources/TestSiddhiApp.siddhi new file mode 100644 index 0000000..af7004c --- /dev/null +++ b/Tests/DASTests/Resources/TestSiddhiApp.siddhi @@ -0,0 +1,9 @@ + +@App:name('TestSiddhiApp') +define stream FooStream (symbol string, price float, volume long); + +@source(type='inMemory', topic='symbol', @map(type='passThrough'))Define stream BarStream (symbol string, price float, volume long); + +from FooStream +select symbol, price, volume +insert into BarStream; \ No newline at end of file diff --git a/Tests/DASTests/Resources/TestSiddhiApp1.siddhi b/Tests/DASTests/Resources/TestSiddhiApp1.siddhi new file mode 100644 index 0000000..bf09c27 --- /dev/null +++ b/Tests/DASTests/Resources/TestSiddhiApp1.siddhi @@ -0,0 +1,9 @@ +@App:name('TestSiddhiApp1') +define stream FooStream (symbol string, price float, volume long); + +@source(type='inMemory', topic='symbol', @map(type='passThrough')) +Define stream BarStream (symbol string, price float, volume long); + +from FooStream +select symbol, price, volume +insert into BarStream; \ No newline at end of file diff --git a/Tests/DASTests/Resources/sample.csv b/Tests/DASTests/Resources/sample.csv new file mode 100644 index 0000000..4770039 --- /dev/null +++ b/Tests/DASTests/Resources/sample.csv @@ -0,0 +1,6 @@ +1488615136968,wso2,10.0,10 +1488615136970,wso2,20.0,20 +1488615136972,wso2,30.0,30 +1488615136977,wso2,40.0,40 +1488615136978,wso2,50.0,50 + diff --git a/Tests/DASTests/SiddhiAppManagerTests.py b/Tests/DASTests/SiddhiAppManagerTests.py new file mode 100644 index 0000000..168a291 --- /dev/null +++ b/Tests/DASTests/SiddhiAppManagerTests.py @@ -0,0 +1,138 @@ +import os +import unittest + +import logging +from time import sleep + +from PySiddhi4.das.DASClient import DASClient +from PySiddhi4.das.SiddhiAppManagement.SiddhiAppManagementClient import UpdateAppStatusResponse + +logging.basicConfig(level=logging.INFO) + + +resources_path = os.path.join(os.path.dirname(__file__), "Resources") + + +class EventSimulatorTests(unittest.TestCase): + def setUp(self): + self.hostUrl = "http://localhost:9090" + logging.info("Prior to launching tests, make sure DAS 4 is running at " + self.hostUrl) + + def tearDown(self): + sleep(5) # Sleep to provide sufficient time for DAS 4.0 to update status + + def testRetrieveSiddhiAppStatus(self): + logging.info("Test1: Retrieving a Siddhi App Status") + dasPythonClient = DASClient(self.hostUrl) + siddhiAppManagementClient = dasPythonClient.getSiddhiAppManagementClient() + + status = siddhiAppManagementClient.retrieveStatusSiddhiApp("TestSiddhiApp") + + self.assertEqual(status,"active") + + def testRetrieveSiddhiApp(self): + logging.info("Test1: Retrieving a Siddhi App") + + dasPythonClient = DASClient(self.hostUrl) + siddhiAppManagementClient = dasPythonClient.getSiddhiAppManagementClient() + + app = siddhiAppManagementClient.retrieveSiddhiApp("TestSiddhiApp") + + lines = [] + with open(resources_path + "/TestSiddhiApp.siddhi","rb") as f: + lines = [line.decode() for line in f.readlines()] + + target_app = "".join(lines) + + logging.info(target_app) + + logging.info(app) + self.assertEqual(app,target_app) + + + def testListSiddhiApps(self): + logging.info("Test1: List Siddhi Apps") + + dasPythonClient = DASClient(self.hostUrl) + siddhiAppManagementClient = dasPythonClient.getSiddhiAppManagementClient() + + lines = [] + with open(resources_path + "/TestSiddhiApp1.siddhi", "rb") as f: + lines = [line.decode() for line in f.readlines()] + + siddhiApp = "".join(lines) + + result = siddhiAppManagementClient.saveSiddhiApp(siddhiApp) + self.assertTrue(result) + + sleep(5) + + apps = siddhiAppManagementClient.listSiddhiApps() + print(apps) + self.assertTrue("TestSiddhiApp1" in apps) + logging.info(apps) + + apps = siddhiAppManagementClient.listSiddhiApps(isActive=True) + self.assertTrue("TestSiddhiApp1" in apps) + logging.info(apps) + + apps = siddhiAppManagementClient.listSiddhiApps(isActive=False) + self.assertTrue("TestSiddhiApp1" not in apps) + logging.info(apps) + + result = siddhiAppManagementClient.deleteSiddhiApp("TestSiddhiApp1") + self.assertTrue(result) + + + + + def testSaveAndDeleteSiddhiApp(self): + logging.info("Test1: Save and Delete Siddhi App") + + dasPythonClient = DASClient(self.hostUrl) + siddhiAppManagerClient = dasPythonClient.getSiddhiAppManagementClient() + + lines = [] + with open(resources_path + "/TestSiddhiApp1.siddhi", "rb") as f: + lines = [line.decode() for line in f.readlines()] + + siddhiApp = "".join(lines) + + result = siddhiAppManagerClient.saveSiddhiApp(siddhiApp) + self.assertTrue(result) + + + sleep(5) + + result = siddhiAppManagerClient.deleteSiddhiApp("TestSiddhiApp1") + self.assertTrue(result) + + + def testUpdateAndDeleteSiddhiApp(self): + logging.info("Test: Update and Delete Siddhi App") + + dasPythonClient = DASClient(self.hostUrl) + siddhiAppManagerClient = dasPythonClient.getSiddhiAppManagementClient() + + lines = [] + with open(resources_path + "/TestSiddhiApp1.siddhi", "rb") as f: + lines = [line.decode() for line in f.readlines()] + + siddhiApp = "".join(lines) + + result = siddhiAppManagerClient.updateSiddhiApp(siddhiApp) + self.assertTrue(result.name == UpdateAppStatusResponse.savedNew.name) + + sleep(5) + + result = siddhiAppManagerClient.updateSiddhiApp(siddhiApp) + self.assertTrue(result.name == UpdateAppStatusResponse.updated.name) + + sleep(5) + + result = siddhiAppManagerClient.deleteSiddhiApp("TestSiddhiApp1") + self.assertTrue(result) + + +if __name__ == '__main__': + unittest.main() diff --git a/Tests/DASTests/__init__.py b/Tests/DASTests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Tests/PySiddhi4Tests/BasicTest.py b/Tests/SiddhiCoreTests/BasicTest.py similarity index 100% rename from Tests/PySiddhi4Tests/BasicTest.py rename to Tests/SiddhiCoreTests/BasicTest.py diff --git a/Tests/PySiddhi4Tests/EventTest.py b/Tests/SiddhiCoreTests/EventTest.py similarity index 100% rename from Tests/PySiddhi4Tests/EventTest.py rename to Tests/SiddhiCoreTests/EventTest.py diff --git a/Tests/PySiddhi4Tests/ExtensionsTest.py b/Tests/SiddhiCoreTests/ExtensionsTest.py similarity index 95% rename from Tests/PySiddhi4Tests/ExtensionsTest.py rename to Tests/SiddhiCoreTests/ExtensionsTest.py index d167926..7a9c732 100644 --- a/Tests/PySiddhi4Tests/ExtensionsTest.py +++ b/Tests/SiddhiCoreTests/ExtensionsTest.py @@ -19,16 +19,14 @@ from PySiddhi4 import SiddhiLoader # Download extension jars -path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), +path = os.path.join(os.path.dirname(os.path.abspath(__file__)), os.path.join("Resources", "Extensions4")) if os.name == "nt": # For windows, shell=True is required - call(["mvn", "install"], shell=True, cwd=os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), - os.path.join("Resources", "Extensions4"))) + call(["mvn", "install"], shell=True, cwd=path) else: # For linux, shell=True causes cwd to not function properly - call(["mvn", "install"], cwd=os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), - os.path.join("Resources", "Extensions4"))) + call(["mvn", "install"], cwd=path) # Add extensions -extensions_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + "/Resources/Extensions4/jars/*" +extensions_path = os.path.join(path,"jars/*") SiddhiLoader.addExtensionPath(extensions_path) import unittest diff --git a/Tests/Resources/Extensions4/pom.xml b/Tests/SiddhiCoreTests/Resources/Extensions4/pom.xml similarity index 100% rename from Tests/Resources/Extensions4/pom.xml rename to Tests/SiddhiCoreTests/Resources/Extensions4/pom.xml diff --git a/Tests/PySiddhi4Tests/TestDebugger.py b/Tests/SiddhiCoreTests/TestDebugger.py similarity index 100% rename from Tests/PySiddhi4Tests/TestDebugger.py rename to Tests/SiddhiCoreTests/TestDebugger.py diff --git a/Tests/PySiddhi4Tests/TestOutputStream.py b/Tests/SiddhiCoreTests/TestOutputStream.py similarity index 100% rename from Tests/PySiddhi4Tests/TestOutputStream.py rename to Tests/SiddhiCoreTests/TestOutputStream.py diff --git a/Tests/PySiddhi4Tests/__init__.py b/Tests/SiddhiCoreTests/__init__.py similarity index 100% rename from Tests/PySiddhi4Tests/__init__.py rename to Tests/SiddhiCoreTests/__init__.py diff --git a/Tests/PySiddhi4Tests/log4j.xml b/Tests/SiddhiCoreTests/log4j.xml similarity index 100% rename from Tests/PySiddhi4Tests/log4j.xml rename to Tests/SiddhiCoreTests/log4j.xml