├── .gitignore ├── LICENSE.txt ├── PySiddhi ├── DataTypes │ ├── DataWrapper.py │ ├── DoubleType.py │ ├── LongType.py │ └── __init__.py ├── SiddhiLoader.py ├── __init__.py ├── core │ ├── SiddhiAppRuntime.py │ ├── SiddhiManager.py │ ├── __init__.py │ ├── debugger │ │ ├── SiddhiDebugger.py │ │ ├── SiddhiDebuggerCallback.py │ │ └── __init__.py │ ├── event │ │ ├── ComplexEvent.py │ │ ├── Event.py │ │ └── __init__.py │ ├── query │ │ ├── __init__.py │ │ └── output │ │ │ ├── __init__.py │ │ │ └── callback │ │ │ ├── QueryCallback.py │ │ │ └── __init__.py │ ├── stream │ │ ├── __init__.py │ │ ├── input │ │ │ ├── InputHandler.py │ │ │ └── __init__.py │ │ └── output │ │ │ ├── StreamCallback.py │ │ │ └── __init__.py │ └── util │ │ ├── EventPrinter.py │ │ └── __init__.py ├── log4j.xml └── sp │ ├── EventSimulator │ ├── AttributeConfiguration.py │ ├── EventSimulatorClient.py │ ├── FeedSimulationConfiguration.py │ ├── SimulationProperties.py │ ├── SimulationSource.py │ ├── SingleSimulationConfiguration.py │ └── __init__.py │ ├── ObjectMapping │ ├── APIObject.py │ ├── FieldMapping.py │ └── __init__.py │ ├── SPClient.py │ ├── SiddhiAppManagement │ ├── SiddhiAppManagementClient.py │ └── __init__.py │ ├── __Communication │ ├── RestClient.py │ └── __init__.py │ ├── __Util.py │ └── __init__.py ├── README.md ├── Requirements.txt ├── Tests ├── SPTests │ ├── EventSimulatorTests.py │ ├── Resources │ │ ├── TestSiddhiApp.siddhi │ │ ├── TestSiddhiApp1.siddhi │ │ └── sample.csv │ ├── SiddhiAppManagerTests.py │ └── __init__.py ├── SiddhiCoreTests │ ├── BasicTest.py │ ├── EventTest.py │ ├── ExtensionsTest.py │ ├── Resources │ │ └── Extensions │ │ │ └── pom.xml │ ├── TestDebugger.py │ ├── TestOutputStream.py │ ├── __init__.py │ └── log4j.xml ├── Util │ ├── AtomicInt.py │ └── __init__.py └── __init__.py ├── __PySiddhiProxy ├── pom.xml ├── src │ └── main │ │ ├── java │ │ ├── io │ │ │ └── siddhi │ │ │ │ └── pythonapi │ │ │ │ ├── DataWrapProxy.java │ │ │ │ ├── proxy │ │ │ │ └── core │ │ │ │ │ ├── SiddhiAPICoreProxy.java │ │ │ │ │ ├── debugger │ │ │ │ │ ├── siddhi_debugger │ │ │ │ │ │ └── QueryTerminalProxy.java │ │ │ │ │ └── siddhi_debugger_callback │ │ │ │ │ │ ├── SiddhiDebuggerCallbackProxy.java │ │ │ │ │ │ └── event_polling │ │ │ │ │ │ ├── EventQueue.java │ │ │ │ │ │ └── QueuedEvent.java │ │ │ │ │ ├── event │ │ │ │ │ ├── complex_event │ │ │ │ │ │ ├── ComplexEventProxy.java │ │ │ │ │ │ └── TypeProxy.java │ │ │ │ │ └── event │ │ │ │ │ │ └── EventProxy.java │ │ │ │ │ ├── query │ │ │ │ │ └── output │ │ │ │ │ │ └── callback │ │ │ │ │ │ └── query_callback │ │ │ │ │ │ ├── QueryCallbackProxy.java │ │ │ │ │ │ └── ReceiveCallbackProxy.java │ │ │ │ │ ├── stream │ │ │ │ │ ├── input │ │ │ │ │ │ └── input_handler │ │ │ │ │ │ │ └── InputHandlerProxy.java │ │ │ │ │ └── output │ │ │ │ │ │ └── callback │ │ │ │ │ │ └── stream_callback │ │ │ │ │ │ ├── ReceiveCallbackProxy.java │ │ │ │ │ │ └── StreamCallbackProxy.java │ │ │ │ │ └── util │ │ │ │ │ └── EventPrinterProxy.java │ │ │ │ └── threadfix │ │ │ │ ├── PyThreadFix.java │ │ │ │ └── PyThreadFixCaller.java │ │ └── org │ │ │ └── jnius │ │ │ └── NativeInvocationHandler.java │ │ └── resources │ │ └── log4j.xml └── threadfix_c_code │ ├── README.MD │ ├── build.sh │ ├── io_siddhi_pythonapi_threadfix_PyThreadFix.c │ ├── io_siddhi_pythonapi_threadfix_PyThreadFix.h │ └── makefile ├── docs ├── Debugging-Siddhi-Queries.md ├── Installation-Guide.md ├── Run-PySiddhi.md ├── Using-Siddhi-from-Python.md ├── assets │ ├── javascripts │ │ └── extra.js │ └── stylesheets │ │ └── extra.css ├── images │ ├── favicon.ico │ └── siddhi-logo.svg ├── index.md └── license.md ├── issue_template.md ├── log4j.xml ├── mkdocs.yml ├── pull_request_template.md ├── setup.cfg └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | *.dylib 9 | 10 | # Distribution / packaging 11 | .Python 12 | env/ 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *,cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # IPython Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # dotenv 80 | .env 81 | 82 | # virtualenv 83 | venv/ 84 | ENV/ 85 | 86 | # Spyder project settings 87 | .spyderproject 88 | 89 | # Rope project settings 90 | .ropeproject 91 | .idea/ 92 | *.iml 93 | -------------------------------------------------------------------------------- /PySiddhi/DataTypes/DataWrapper.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | 18 | from PySiddhi import SiddhiLoader 19 | from PySiddhi.DataTypes.DoubleType import DoubleType 20 | from PySiddhi.DataTypes.LongType import LongType 21 | 22 | ''' 23 | Data Wrapping is used because python 3 doesn't distinctly support long and double data types 24 | ''' 25 | 26 | 27 | def unwrapDataItem(d): 28 | ''' 29 | Unwraps a data item (String, float, int, long) sent from Java Proxy Classes 30 | :param d: 31 | :return: 32 | ''' 33 | if d.isNull(): 34 | return None 35 | elif d.isLong(): 36 | return LongType(d.getData()) 37 | elif d.isDouble(): 38 | return DoubleType(d.getData()) 39 | return d.getData() 40 | 41 | 42 | def unwrapDataList(d): 43 | ''' 44 | Unwraps a list of data sent from Java Proxy Classes 45 | :param d: 46 | :return: 47 | ''' 48 | results = [] 49 | for r in d: 50 | results.append(unwrapDataItem(r)) 51 | return results 52 | 53 | 54 | def unwrapData(data): 55 | ''' 56 | Unwraps a data object sent from Java Proxy Classes 57 | :param data: 58 | :return: 59 | ''' 60 | if isinstance(data, list): 61 | return unwrapDataList(data) 62 | else: 63 | return unwrapDataItem(data) 64 | 65 | 66 | def wrapDataItem(d): 67 | ''' 68 | Wraps a data item (int, long, string or float) , making it suitable to be transfered to Java Proxy 69 | :param d: 70 | :return: 71 | ''' 72 | wrapped_data_proxy = SiddhiLoader._loadType("io.siddhi.pythonapi.DataWrapProxy") 73 | wrapped_data = None 74 | if d is None: 75 | # Constructor for null type 76 | wrapped_data = wrapped_data_proxy(0, False, True) 77 | elif type(d) is LongType: 78 | # Consutrctor for Long Type 79 | wrapped_data = wrapped_data_proxy(d, True) 80 | elif type(d) is DoubleType: 81 | wrapped_data = wrapped_data_proxy(d, False, False, True) 82 | else: 83 | wrapped_data = wrapped_data_proxy(d) 84 | return wrapped_data 85 | 86 | 87 | def wrapDataList(data): 88 | ''' 89 | Wraps a list of data, making it suitable for transfer to java proxy classes 90 | :param data: 91 | :return: 92 | ''' 93 | results = [] 94 | for d in data: 95 | results.append(wrapData(d)) 96 | return results 97 | 98 | 99 | def wrapData(data): 100 | ''' 101 | Wraps a data object (List or item) to suite transmission to Java proxy classes 102 | :param data: 103 | :return: 104 | ''' 105 | if isinstance(data, list): 106 | return wrapDataList(data) 107 | else: 108 | return wrapDataItem(data) 109 | 110 | 111 | def unwrapHashMap(map): 112 | ''' 113 | Obtains a copy of a Java HashMap as a Dictionary 114 | :param map: 115 | :return: 116 | ''' 117 | if (not isinstance(map, SiddhiLoader._JavaClass)) or ( 118 | map.__javaclass__ != "java/util/Map" and map.__javaclass__ != "java/util/HashMap"): 119 | return map 120 | # TODO: Should prevent exposure of subtypes of ComplexEvent 121 | results = {} 122 | entry_set = map.entrySet().toArray() 123 | for v in entry_set: 124 | if v.value is None: 125 | results[v.key] = None 126 | else: 127 | results[v.key] = unwrapHashMap(v.value) 128 | return results 129 | -------------------------------------------------------------------------------- /PySiddhi/DataTypes/DoubleType.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | class DoubleType(float): 18 | ''' 19 | Siddhi Double Data Type. 20 | Use DoubleType(int_value) to create DoubleType variables. 21 | ''' 22 | 23 | def __new__(cls, *args, **kwargs): 24 | return super(DoubleType, cls).__new__(cls, args[0]) 25 | -------------------------------------------------------------------------------- /PySiddhi/DataTypes/LongType.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | 18 | class LongType(int): 19 | ''' 20 | Siddhi Long Data Type. 21 | Use LongType(int_value) to create LongType variables. 22 | ''' 23 | 24 | def __new__(cls, *args, **kwargs): 25 | return super(LongType, cls).__new__(cls, args[0]) 26 | -------------------------------------------------------------------------------- /PySiddhi/DataTypes/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /PySiddhi/SiddhiLoader.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | import logging 18 | import os 19 | 20 | import sys 21 | 22 | import PySiddhi 23 | 24 | # Instantiate Global Variables 25 | siddhi_api_core = None 26 | siddhi_api_core_inst = None 27 | 28 | _java_method = None 29 | _PythonJavaClass = None 30 | _JavaClass = None 31 | 32 | def addExtensionPath(): 33 | ''' 34 | Adds an Extension to Siddhi. Should be called prior to importing any Siddhi Libraries. 35 | :param class_path: Path to Jar File. Wild Card (*) directory selection is accepted 36 | :return: 37 | ''' 38 | siddhi_home = os.getenv("SIDDHISDK_HOME") 39 | class_path = os.path.join(siddhi_home, "lib", "*") 40 | if "siddhi_api_configured" in globals(): 41 | raise Exception("Cannot add extensions after loading library.") 42 | 43 | if not "extensions" in globals(): 44 | globals()["extensions"] = [] 45 | 46 | globals()["extensions"].append(class_path) 47 | 48 | 49 | def _resumeLibrary(): 50 | ''' 51 | Resumes values of global variables from backup 52 | :return: 53 | ''' 54 | if not "siddhi_api_configured" in globals(): 55 | logging.info("Premature library resume ignored") 56 | return 57 | 58 | # Resume Global variables values from backup 59 | global t_siddhi_api_core, t_siddhi_api_core_inst, t_java_method, t_PythonJavaClass, t_JavaClass 60 | global siddhi_api_core, siddhi_api_core_inst, _java_method, _PythonJavaClass, _JavaClass 61 | 62 | siddhi_api_core = t_siddhi_api_core 63 | siddhi_api_core_inst = t_siddhi_api_core_inst 64 | _java_method = t_java_method 65 | _PythonJavaClass = t_PythonJavaClass 66 | _JavaClass = t_JavaClass 67 | 68 | 69 | # Resume global variables values from backup 70 | _resumeLibrary() 71 | 72 | 73 | def loadLibrary(): 74 | ''' 75 | Loads Siddi Library 76 | :return: 77 | ''' 78 | siddhi_home = os.getenv("SIDDHISDK_HOME") 79 | # Test whether Java Library is already loaded 80 | if "siddhi_api_configured" in globals(): 81 | if globals()["siddhi_api_configured"] != 4: 82 | raise Exception("Unable to use multiple versions of Siddhi Library") 83 | # Resume global variables if already loaded 84 | _resumeLibrary() 85 | return 86 | 87 | # Add Java library to class path of jvm 88 | import jnius_config 89 | 90 | # NOTE: The following code-line is required on Linux Kernel 4.4.0-81-generic and above to avoid segmentation fault 91 | # at initialization of pyjnius 92 | jnius_config.add_options('-Xss1280k') 93 | 94 | jnius_config.add_options('-Djava.library.path=' + PySiddhi.root_path + "/__PySiddhiProxy") 95 | 96 | # Determine library class path 97 | class_paths = ['.', os.path.join(siddhi_home, 'lib', '*')] 98 | 99 | # Add Extensions 100 | if not "extensions" in globals(): 101 | global extensions 102 | extensions = [] 103 | 104 | for extension in extensions: 105 | class_paths.append(extension) 106 | 107 | jnius_config.set_classpath(*(tuple(class_paths))) 108 | 109 | # Mark API configured 110 | global siddhi_api_configured 111 | siddhi_api_configured = 4 112 | 113 | logging.info("Classpath Configured") 114 | 115 | # Load Pyjnius (Starts JVM) 116 | from jnius import autoclass, java_method, PythonJavaClass, JavaClass 117 | 118 | # Generate references and store in backup 119 | global t_siddhi_api_core, t_siddhi_api_core_inst, t_java_method, t_PythonJavaClass, t_JavaClass 120 | t_siddhi_api_core = autoclass("io.siddhi.pythonapi.proxy.core.SiddhiAPICoreProxy") 121 | t_siddhi_api_core_inst = t_siddhi_api_core(sys.version_info[0], sys.version_info[1]) 122 | t_java_method = java_method 123 | t_PythonJavaClass = PythonJavaClass 124 | t_JavaClass = JavaClass 125 | 126 | # Resume references stored in backup 127 | _resumeLibrary() 128 | 129 | 130 | def _loadType(type_name): 131 | loadLibrary() 132 | from jnius import autoclass 133 | return autoclass(type_name) 134 | 135 | 136 | def _detachThread(): 137 | loadLibrary() 138 | import jnius 139 | jnius.detach() 140 | -------------------------------------------------------------------------------- /PySiddhi/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | import logging 18 | import os 19 | 20 | source_path = os.path.dirname(os.path.abspath(__file__)) 21 | root_path = os.path.dirname(source_path) -------------------------------------------------------------------------------- /PySiddhi/core/SiddhiAppRuntime.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from PySiddhi import SiddhiLoader 18 | from PySiddhi.core.debugger.SiddhiDebugger import SiddhiDebugger 19 | from PySiddhi.core.query.output.callback.QueryCallback import QueryCallback 20 | from PySiddhi.core.stream.input.InputHandler import InputHandler 21 | from PySiddhi.core.stream.output.StreamCallback import StreamCallback 22 | 23 | 24 | class SiddhiAppRuntime(object): 25 | ''' 26 | Wrapper on io.core.SiddhiAppRuntime 27 | ''' 28 | 29 | def __init__(self): 30 | ''' 31 | Use SiddhiManager to instantiate SiddhiAppEngine 32 | ''' 33 | raise NotImplementedError("Initialize SiddhiAppRuntime using Siddhi Manager") 34 | 35 | def __new__(cls): 36 | bare_instance = object.__new__(cls) 37 | bare_instance.siddhi_app_runtime_proxy = None 38 | return bare_instance 39 | 40 | def addCallback(self, queryName, queryCallback): 41 | ''' 42 | Assign callback interface to SiddhiAppRuntime 43 | :param queryName: 44 | :param queryCallback: 45 | :return: 46 | ''' 47 | if isinstance(queryCallback, QueryCallback): 48 | SiddhiLoader.siddhi_api_core_inst.addSiddhiAppRuntimeQueryCallback(self.siddhi_app_runtime_proxy, queryName, 49 | queryCallback._query_callback_proxy_inst) 50 | elif isinstance(queryCallback, StreamCallback): 51 | SiddhiLoader.siddhi_api_core_inst.addSiddhiAppRuntimeStreamCallback(self.siddhi_app_runtime_proxy, 52 | queryName, 53 | queryCallback._stream_callback_proxy) 54 | else: 55 | raise NotImplementedError("Unknown type of callback") 56 | 57 | def start(self): 58 | ''' 59 | Start SiddhiAppRuntime 60 | :return: void 61 | ''' 62 | self.siddhi_app_runtime_proxy.start() 63 | 64 | def shutdown(self): 65 | ''' 66 | Shutdown SiddhiAppRuntime 67 | :return: 68 | ''' 69 | self.siddhi_app_runtime_proxy.shutdown() 70 | del self.siddhi_app_runtime_proxy 71 | 72 | def getInputHandler(self, streamId): 73 | ''' 74 | Retrieve input handler assigned with a stream 75 | :param streamId: stream id of stream 76 | :return: InputHandler 77 | ''' 78 | input_handler_proxy = self.siddhi_app_runtime_proxy.getInputHandler(streamId) 79 | return InputHandler._fromInputHandlerProxy(input_handler_proxy) 80 | 81 | def debug(self): 82 | ''' 83 | Retrieve the Siddhi Debugger used to debug the Siddhi app 84 | :return: SiddhiDebugger 85 | ''' 86 | # Obtain debugger proxy class 87 | siddhi_debugger_proxy = self.siddhi_app_runtime_proxy.debug() 88 | return SiddhiDebugger._fromSiddhiDebuggerProxy(siddhi_debugger_proxy) 89 | 90 | @classmethod 91 | def _fromSiddhiAppRuntimeProxy(cls, siddhi_app_runtime_proxy): 92 | ''' 93 | Internal Constructor to wrap around JAVA Class SiddhiAppRuntime 94 | :param siddhi_app_runtime_proxy: 95 | :return: 96 | ''' 97 | instance = cls.__new__(cls) 98 | instance.siddhi_app_runtime_proxy = siddhi_app_runtime_proxy 99 | return instance 100 | 101 | def getName(self): 102 | ''' 103 | Returns name of SiddhiAppContext 104 | :return: 105 | ''' 106 | return self.siddhi_app_runtime_proxy.getName() 107 | 108 | def persist(self): 109 | ''' 110 | Persists state 111 | :return: 112 | ''' 113 | return self.siddhi_app_runtime_proxy.persist() 114 | 115 | def restoreRevision(self, revision): 116 | ''' 117 | Restores revision 118 | :param revision: Revision 119 | :return: 120 | ''' 121 | self.siddhi_app_runtime_proxy.restoreRevision(revision) 122 | 123 | def restoreLastRevision(self): 124 | ''' 125 | Restores last revision 126 | :return: 127 | ''' 128 | self.siddhi_app_runtime_proxy.restoreLastRevision() 129 | 130 | def snapshot(self): 131 | ''' 132 | Obtains snapshot 133 | :return: byteArray 134 | ''' 135 | return self.siddhi_app_runtime_proxy.snapshot() 136 | -------------------------------------------------------------------------------- /PySiddhi/core/SiddhiManager.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from PySiddhi import SiddhiLoader 18 | from PySiddhi.DataTypes import DataWrapper 19 | from PySiddhi.core.SiddhiAppRuntime import SiddhiAppRuntime 20 | 21 | 22 | class SiddhiManager(object): 23 | ''' 24 | This is the main interface class of Siddhi where users will interact when using Siddhi as a library. 25 | ''' 26 | 27 | def __init__(self): 28 | ''' 29 | ''Initialize a new SiddhiManager 30 | ''' 31 | SiddhiLoader.loadLibrary() 32 | self._siddhi_manager_proxy = SiddhiLoader.siddhi_api_core_inst.initSiddhiManager() 33 | 34 | def createSiddhiAppRuntime(self, siddhiApp): 35 | ''' 36 | Create an Siddhi app Runtime 37 | :param siddhiApp: SiddhiQuery (string) defining siddhi app 38 | :return: SiddhiAppRuntime 39 | ''' 40 | 41 | siddhi_app_runtime_proxy = self._siddhi_manager_proxy.createSiddhiAppRuntime(siddhiApp) 42 | return SiddhiAppRuntime._fromSiddhiAppRuntimeProxy(siddhi_app_runtime_proxy) 43 | 44 | def getExtensions(self): 45 | ''' 46 | Obtain the dictionary of loaded extensions 47 | :return: 48 | ''' 49 | return DataWrapper.unwrapHashMap(self._siddhi_manager_proxy.getExtensions()) 50 | 51 | def setExtension(self, name, clazz): 52 | ''' 53 | Loads an extension into Siddhi Manager. The Extension Path must be already added via 54 | SiddhiLoader.addExtensionPath. 55 | :param name: Name of extension 56 | :param clazz: Fully qualified class name of extension 57 | :return: 58 | ''' 59 | if isinstance(clazz, str): 60 | self._siddhi_manager_proxy.setExtension(name, SiddhiLoader._loadType(clazz)) 61 | else: 62 | self._siddhi_manager_proxy.setExtension(name, clazz) 63 | 64 | def persist(self): 65 | ''' 66 | Method used persist state of current Siddhi Manager instance. 67 | :return: 68 | ''' 69 | self._siddhi_manager_proxy.persist() 70 | 71 | def restoreLastState(self): 72 | ''' 73 | Method used to restore state of Current Siddhi Manager instance. 74 | :return: 75 | ''' 76 | self._siddhi_manager_proxy.restoreLastState() 77 | 78 | def shutdown(self): 79 | ''' 80 | Shutdown SiddhiManager 81 | :return: 82 | ''' 83 | self._siddhi_manager_proxy.shutdown() 84 | del self._siddhi_manager_proxy 85 | -------------------------------------------------------------------------------- /PySiddhi/core/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /PySiddhi/core/debugger/SiddhiDebuggerCallback.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | 18 | from abc import ABCMeta, abstractmethod 19 | from future.utils import with_metaclass 20 | from PySiddhi import SiddhiLoader 21 | 22 | _siddhi_debugger_callback_proxy = SiddhiLoader._loadType( 23 | "io.siddhi.pythonapi.proxy.core.debugger.siddhi_debugger_callback.SiddhiDebuggerCallbackProxy") 24 | 25 | 26 | class SiddhiDebuggerCallback(with_metaclass(ABCMeta, object)): 27 | ''' 28 | Callback to get notification about the events passing through the break points. 29 | Should be extended by subclass. 30 | ''' 31 | 32 | def __init__(self): 33 | _siddhi_debugger_callback_self = self 34 | self._siddhi_debugger_callback_proxy_inst = _siddhi_debugger_callback_proxy() 35 | 36 | @abstractmethod 37 | def debugEvent(self, complexEvent, queryName, queryTerminal, debugger): 38 | ''' 39 | Receive the events passing through the registered breakpoints. 40 | 41 | :param complexEvent: ComplexEvent waiting at the breakpoint 42 | :param queryName: Name of the query where the current breakpoint is 43 | :param queryTerminal: IN or OUT terminal of the query 44 | :param debugger: SiddhiDebugger to have control over the debug flow within the event caller 45 | :return: 46 | ''' 47 | pass 48 | -------------------------------------------------------------------------------- /PySiddhi/core/debugger/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /PySiddhi/core/event/ComplexEvent.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | 18 | from enum import Enum 19 | from PySiddhi import SiddhiLoader 20 | from PySiddhi.DataTypes.DataWrapper import unwrapData, wrapData 21 | 22 | 23 | class ComplexEvent(object): 24 | ''' 25 | Wrapper on @io.siddhi.core.event.ComplexEvent 26 | ''' 27 | 28 | class Type(Enum): 29 | CURRENT = SiddhiLoader._loadType( 30 | "io.siddhi.pythonapi.proxy.core.event.complex_event.TypeProxy")().CURRENT(), 31 | EXPIRED = SiddhiLoader._loadType( 32 | "io.siddhi.pythonapi.proxy.core.event.complex_event.TypeProxy")().EXPIRED(), 33 | TIMER = SiddhiLoader._loadType("io.siddhi.pythonapi.proxy.core.event.complex_event.TypeProxy")().TIMER(), 34 | RESET = SiddhiLoader._loadType("io.siddhi.pythonapi.proxy.core.event.complex_event.TypeProxy")().RESET() 35 | 36 | @classmethod 37 | def _map_value(cls, type_proxy): 38 | type_value = None 39 | if type_proxy.isValueCurrent(): 40 | type_value = ComplexEvent.Type.CURRENT 41 | elif type_proxy.isValueExpired(): 42 | type_value = ComplexEvent.Type.EXPIRED 43 | elif type_proxy.isValueTimer(): 44 | type_value = ComplexEvent.Type.TIMER 45 | elif type_proxy.isValueReset(): 46 | type_value = ComplexEvent.Type.RESET 47 | else: 48 | raise TypeError("Unknown Complex Event Type") 49 | return ComplexEvent.Type(type_value) 50 | 51 | def __init__(self, ): 52 | raise NotImplementedError("Complex Event is Abstract") 53 | 54 | def __new__(cls): 55 | bare_instance = object.__new__(cls) 56 | bare_instance._complex_event_proxy = None 57 | return bare_instance 58 | 59 | @classmethod 60 | def _fromComplexEventProxy(cls, complex_event_proxy): 61 | ''' 62 | Internal Constructor to wrap around JAVA Interface Complex Event 63 | :param complex_event_proxy: 64 | :return: 65 | ''' 66 | if complex_event_proxy is None: 67 | return None 68 | instance = cls.__new__(cls) 69 | instance._complex_event_proxy = complex_event_proxy 70 | return instance 71 | 72 | def getNext(self): 73 | next_proxy = self._complex_event_proxy.getNext() 74 | return ComplexEvent._fromComplexEventProxy(next_proxy) 75 | 76 | def setNext(self, next_event): 77 | self._complex_event_proxy.setNext(next_event._complex_event_proxy) 78 | 79 | next = property(getNext, setNext) 80 | 81 | def getOutputData(self): 82 | complex_event_static_proxy = SiddhiLoader._loadType( 83 | "io.siddhi.pythonapi.proxy.core.event.complex_event.ComplexEventProxy")() 84 | output_data = unwrapData(complex_event_static_proxy.getOutputData(self._complex_event_proxy)) 85 | return output_data 86 | 87 | def setOutputData(self, datum, index): 88 | complex_event_static_proxy = SiddhiLoader._loadType( 89 | "io.siddhi.pythonapi.proxy.core.event.complex_event.ComplexEventProxy")() 90 | complex_event_static_proxy.setOutputData(self._complex_event_proxy, wrapData(datum), index) 91 | 92 | def getTimestamp(self): 93 | return self._complex_event_proxy.getTimestamp() 94 | 95 | timestamp = property(fget=getTimestamp, fset=None) 96 | 97 | def getAttribute(self, position): 98 | return self._complex_event_proxy.getAttribute(position) 99 | 100 | def setAttribute(self, value, position): 101 | # TODO: Improve logic here by adding support to long. Will need to make a java wrapping for handling long 102 | self._complex_event_proxy.setAttribute(value, position) 103 | 104 | def getType(self): 105 | raw_type_proxy = self._complex_event_proxy.getType() 106 | type_proxy = SiddhiLoader._loadType("io.siddhi.pythonapi.proxy.core.event.complex_event.TypeProxy")( 107 | raw_type_proxy) 108 | return ComplexEvent.Type._map_value(type_proxy) 109 | 110 | def setType(self, type): 111 | self._complex_event_proxy.setType(type.value()) 112 | 113 | type = property(getType, setType) 114 | -------------------------------------------------------------------------------- /PySiddhi/core/event/Event.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from PySiddhi import SiddhiLoader 18 | 19 | from PySiddhi.DataTypes import DataWrapper 20 | from PySiddhi.core.event import ComplexEvent 21 | 22 | _event_class = SiddhiLoader._loadType("io.siddhi.core.event.Event") 23 | _event_proxy_class = SiddhiLoader._loadType("io.siddhi.pythonapi.proxy.core.event.event.EventProxy") 24 | _event_proxy_class_inst = _event_proxy_class() 25 | 26 | 27 | class Event(object): 28 | ''' 29 | Wrapper on @io.siddhi.core.event.Event 30 | ''' 31 | 32 | @classmethod 33 | def _fromEventProxy(cls, event_proxy): 34 | ''' 35 | Internal Constructor to wrap around JAVA class Event 36 | :param event_proxy: 37 | :return: 38 | ''' 39 | if event_proxy is None: 40 | return None 41 | instance = cls.__new__(cls) 42 | instance._event_proxy = event_proxy 43 | return instance 44 | 45 | def __init__(self, dataSizeOrTimeStamp=None, data=None, dataSize=None, timeStamp=None): 46 | ''' 47 | Constructor. Refer the Java Documentation for optional parameters and possible combinations. 48 | :param dataSizeOrTimeStamp: DataSize or TimeStamp of event 49 | :param data: Data as a List of same type objects 50 | :param dataSize: Size of Data 51 | :param timeStamp: Timestamp 52 | ''' 53 | if dataSizeOrTimeStamp is None and data is None and dataSize is None and timeStamp is None: 54 | self._event_proxy = _event_class() 55 | elif dataSizeOrTimeStamp is not None and data is None and dataSize is None and timeStamp is None: 56 | self._event_proxy = _event_class(int(dataSizeOrTimeStamp)) 57 | elif dataSizeOrTimeStamp is not None and data is not None and dataSize is None and timeStamp is None: 58 | self._event_proxy = _event_proxy_class_inst.createEvent(dataSizeOrTimeStamp, DataWrapper.wrapDataList(data)) 59 | elif dataSizeOrTimeStamp is None and data is None and timeStamp is None and dataSize is not None: 60 | self._event_proxy = _event_class(int(dataSize)) 61 | elif dataSizeOrTimeStamp is None and data is not None and timeStamp is not None and dataSize is None: 62 | self._event_proxy = _event_class(timeStamp, data) 63 | else: 64 | raise NotImplementedError("Unknown constructor parameter combination") 65 | 66 | def __str__(self): 67 | ''' 68 | ToString 69 | :return: 70 | ''' 71 | return self._event_proxy.toString() 72 | 73 | def getId(self): 74 | ''' 75 | Get event id 76 | :return: 77 | ''' 78 | return self._event_proxy.getId() 79 | 80 | def setId(self, value): 81 | ''' 82 | Set event id 83 | :param value: 84 | :return: 85 | ''' 86 | self._event_proxy.setId(value) 87 | 88 | def getTimestamp(self): 89 | ''' 90 | Retrieve timestamp 91 | :return: 92 | ''' 93 | return self._event_proxy.getTimestamp() 94 | 95 | def setTimestamp(self, value): 96 | ''' 97 | Set timestamp 98 | :param value: 99 | :return: 100 | ''' 101 | self._event_proxy.setTimestamp(value) 102 | 103 | def getData(self, index=None): 104 | ''' 105 | Retrieve data as a list (if index not specified) or datum at index (if index specified) 106 | :param index: Index (optional) 107 | :return: 108 | ''' 109 | if index is None: 110 | return DataWrapper.unwrapDataList(_event_proxy_class_inst.getData(self._event_proxy)) 111 | else: 112 | data = _event_proxy_class_inst.getDataItem(self._event_proxy, index) 113 | if data is None: 114 | return None 115 | return DataWrapper.unwrapDataItem(data) 116 | 117 | def setData(self, data): 118 | ''' 119 | Set data as a list 120 | :param data: 121 | :return: 122 | ''' 123 | _event_proxy_class_inst.setData(self._event_proxy, DataWrapper.wrapDataList(data)) 124 | 125 | def isExpired(self): 126 | ''' 127 | Retrieve whether event has expired 128 | :return: 129 | ''' 130 | return self._event_proxy.isExpired() 131 | 132 | def setExpired(self, value): 133 | ''' 134 | Set whether event has expired 135 | :param value: 136 | :return: 137 | ''' 138 | if value: 139 | _event_proxy_class_inst.makeExpired(self._event_proxy) 140 | else: 141 | _event_proxy_class_inst.makeUnExpired(self._event_proxy) 142 | 143 | def copyFrom(self, event): 144 | ''' 145 | Copy values from an event 146 | :param event: source event 147 | :return: 148 | ''' 149 | if isinstance(event, Event): 150 | self._event_proxy.copyFrom(event._event_proxy) 151 | elif isinstance(event, ComplexEvent.ComplexEvent): 152 | self._event_proxy.copyFrom(event._complex_event_proxy) 153 | 154 | def __eq__(self, other): 155 | ''' 156 | Test for equality 157 | :param other: 158 | :return: 159 | ''' 160 | if isinstance(other, Event): 161 | return self._event_proxy.equals(other._event_proxy) 162 | else: 163 | return False 164 | 165 | def equals(self, other): 166 | ''' 167 | Test for equality with other event 168 | :param other: 169 | :return: 170 | ''' 171 | return self == other 172 | 173 | def __hash__(self): 174 | ''' 175 | Obtains hashCode of event 176 | :return: 177 | ''' 178 | return self._event_proxy.hashCode() 179 | -------------------------------------------------------------------------------- /PySiddhi/core/event/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /PySiddhi/core/query/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /PySiddhi/core/query/output/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /PySiddhi/core/query/output/callback/QueryCallback.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | import logging 18 | 19 | from abc import ABCMeta, abstractmethod 20 | 21 | from PySiddhi import SiddhiLoader 22 | from PySiddhi.core.event.Event import Event 23 | 24 | from future.utils import with_metaclass 25 | 26 | _query_callback_proxy = SiddhiLoader._loadType( 27 | "io.siddhi.pythonapi.proxy.core.query.output.callback.query_callback.QueryCallbackProxy") 28 | 29 | _created_instances = [] # Hold references to prevent python from GCing Callbacks until Java does 30 | 31 | 32 | class QueryCallback(with_metaclass(ABCMeta, object)): 33 | ''' 34 | Callback to receive events from SiddhiAppRuntime. Should be extended by child class. 35 | Wrapper on io.siddhi.core.query.output.callback.QueryCallback 36 | ''' 37 | 38 | def __init__(self): 39 | self._query_callback_proxy_inst = _query_callback_proxy() 40 | query_callback_self = self 41 | 42 | class ReceiveCallback(SiddhiLoader._PythonJavaClass): 43 | ''' 44 | Innerclass to wrap around Java Interface 45 | ''' 46 | __javainterfaces__ = [ 47 | "io/siddhi/pythonapi/proxy/core/query/output/callback/query_callback/ReceiveCallbackProxy"] 48 | 49 | @SiddhiLoader._java_method( 50 | signature='(J[Lio/siddhi/core/event/Event;[Lio/siddhi/core/event/Event;)V', 51 | name="receive") 52 | def receive(self, timestamp, inEvents, outEvents): 53 | # _lock.acquire() 54 | if inEvents is not None: 55 | inEvents = [Event._fromEventProxy(event) for event in inEvents] 56 | if outEvents is not None: 57 | outEvents = [Event._fromEventProxy(event) for event in outEvents] 58 | query_callback_self.receive(timestamp, inEvents, outEvents) 59 | # _lock.release() 60 | 61 | @SiddhiLoader._java_method(signature='()V', name="gc") 62 | def gc(self): 63 | _created_instances.remove(query_callback_self) 64 | logging.info("Java Reported GC Collected Query Callback") 65 | 66 | self._receive_callback_ref = ReceiveCallback() # Hold reference to prevent python from GC before java does 67 | self._query_callback_proxy_inst.setReceiveCallback(self._receive_callback_ref) 68 | _created_instances.append(self) 69 | 70 | @abstractmethod 71 | def receive(self, timestamp, inEvents, outEvents): 72 | ''' 73 | Receives callback from SiddhiAppRuntime 74 | :param timestamp: 75 | :param inEvents: 76 | :param outEvents: 77 | :return: 78 | ''' 79 | pass 80 | -------------------------------------------------------------------------------- /PySiddhi/core/query/output/callback/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /PySiddhi/core/stream/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /PySiddhi/core/stream/input/InputHandler.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from PySiddhi import SiddhiLoader 18 | from PySiddhi.DataTypes.DataWrapper import wrapData 19 | 20 | input_handler_proxy = SiddhiLoader._loadType( 21 | "io.siddhi.pythonapi.proxy.core.stream.input.input_handler.InputHandlerProxy") 22 | 23 | 24 | class InputHandler(object): 25 | ''' 26 | Handles input to SiddhiAppRuntime. 27 | Wrapper on io.siddhi.core.stream.input.InputHandler 28 | ''' 29 | 30 | def __init__(self): 31 | raise NotImplementedError("Initialize InputHandler using SiddhiAppRuntime") 32 | 33 | def __new__(cls): 34 | bare_instance = object.__new__(cls) 35 | bare_instance.input_handler_proxy = None 36 | return bare_instance 37 | 38 | def send(self, data): 39 | ''' 40 | Sends data as an event to system. 41 | :param data: 42 | :return: 43 | ''' 44 | wrapped_data = wrapData(data) 45 | input_handler_proxy_inst = input_handler_proxy() 46 | input_handler_proxy_inst.send(self.input_handler_proxy, wrapped_data) 47 | 48 | @classmethod 49 | def _fromInputHandlerProxy(cls, input_handler_proxy): 50 | ''' 51 | Internal Constructor to wrap around JAVA Class InputHandler 52 | :param input_handler_proxy: 53 | :return: 54 | ''' 55 | instance = cls.__new__(cls) 56 | instance.input_handler_proxy = input_handler_proxy 57 | return instance 58 | -------------------------------------------------------------------------------- /PySiddhi/core/stream/input/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /PySiddhi/core/stream/output/StreamCallback.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from multiprocessing import RLock 18 | 19 | import logging 20 | 21 | from abc import ABCMeta, abstractmethod 22 | 23 | from PySiddhi import SiddhiLoader 24 | from PySiddhi.core.event.Event import Event 25 | 26 | from future.utils import with_metaclass 27 | 28 | _stream_callback_proxy = SiddhiLoader._loadType( 29 | "io.siddhi.pythonapi.proxy.core.stream.output.callback.stream_callback.StreamCallbackProxy") 30 | 31 | _lock = RLock() 32 | 33 | _created_instances = [] # Hold reference to prevent python from GC callback before java does 34 | 35 | 36 | class StreamCallback(with_metaclass(ABCMeta, object)): 37 | ''' 38 | StreamCallback is used to receive events from StreamJunction 39 | This class should be extended if one intends to get events from a Siddhi Stream. 40 | ''' 41 | 42 | # __metaclass__ = ABCMeta 43 | 44 | def __init__(self): 45 | self._stream_callback_proxy = _stream_callback_proxy() 46 | stream_callback_self = self 47 | 48 | class ReceiveCallback(SiddhiLoader._PythonJavaClass): 49 | ''' 50 | Innerclass to wrap around Java Interface 51 | ''' 52 | __javainterfaces__ = [ 53 | "io/siddhi/pythonapi/proxy/core/stream/output/callback/stream_callback/ReceiveCallbackProxy"] 54 | 55 | @SiddhiLoader._java_method(signature='([Lio/siddhi/core/event/Event;)V', name="receive") 56 | def receive(self, events): 57 | if events is not None: 58 | events = [Event._fromEventProxy(event) for event in events] 59 | stream_callback_self.receive(events) 60 | 61 | @SiddhiLoader._java_method(signature='()V', name="gc") 62 | def gc(self): 63 | _created_instances.remove(stream_callback_self) 64 | logging.info("Java Reported GC Collected Stream Callback") 65 | 66 | self._receive_callback_ref = ReceiveCallback() # Hold reference to prevent python 67 | # from GC callback before java does 68 | self._stream_callback_proxy.setReceiveCallback(self._receive_callback_ref) 69 | _created_instances.append(self) 70 | 71 | @abstractmethod 72 | def receive(self, events): 73 | pass 74 | -------------------------------------------------------------------------------- /PySiddhi/core/stream/output/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /PySiddhi/core/util/EventPrinter.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from PySiddhi import SiddhiLoader 18 | 19 | _event_printer_proxy = SiddhiLoader._loadType("io.siddhi.pythonapi.proxy.core.util.EventPrinterProxy") 20 | 21 | 22 | def PrintEvent(timestamp, inEvents, outEvents): 23 | ''' 24 | Prints Stream Event to Log 25 | :param timestamp: 26 | :param inEvents: 27 | :param outEvents: 28 | :return: 29 | ''' 30 | if inEvents is not None: 31 | inEvents = [event._event_proxy for event in inEvents] 32 | 33 | if outEvents is not None: 34 | outEvents = [event._event_proxy for event in outEvents] 35 | _event_printer_proxy.printEvent(timestamp, inEvents, outEvents) 36 | 37 | # NOTE: We are unable to call io.siddhi.core.util.EventPrinter.print directly 38 | # because print is a keyword of python 39 | -------------------------------------------------------------------------------- /PySiddhi/core/util/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /PySiddhi/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /PySiddhi/sp/EventSimulator/AttributeConfiguration.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from enum import Enum 18 | 19 | from PySiddhi.sp.ObjectMapping.APIObject import APIObject, NotSet 20 | from PySiddhi.sp.ObjectMapping.FieldMapping import FieldMapping, ListFieldMapping 21 | from PySiddhi.sp.__Util import decodeField, decodeObject 22 | 23 | 24 | class AttributeConfiguration(APIObject): 25 | ''' 26 | Attribute Configuration API Object, which is an attribute of SimulationSource 27 | ''' 28 | 29 | class Type(Enum): 30 | ''' 31 | Type of Attribute Configuration 32 | ''' 33 | CUSTOM_DATA_BASED = "CUSTOM_DATA_BASED" 34 | PRIMITIVE_BASED = "PRIMITIVE_BASED" 35 | REGEX_BASED = "REGEX_BASED" 36 | PROPERTY_BASED = "PROPERTY_BASED" 37 | 38 | @classmethod 39 | def encode(cls, v): 40 | return v.value 41 | 42 | @classmethod 43 | def decode(cls, v): 44 | return AttributeConfiguration.Type(v) 45 | 46 | class PrimitiveType(Enum): 47 | ''' 48 | Type of primitive data type involved 49 | ''' 50 | LONG = "LONG" 51 | INT = "INT" 52 | STRING = "STRING" 53 | FLOAT = "FLOAT" 54 | DOUBLE = "DOUBLE" 55 | 56 | @classmethod 57 | def encode(cls, v): 58 | return v.value 59 | 60 | @classmethod 61 | def decode(cls, v): 62 | return AttributeConfiguration.Type(v) 63 | 64 | def __init__(self, type, min=NotSet(), max=NotSet(), length=NotSet(), precision=NotSet(), list=NotSet(), 65 | pattern=NotSet(), 66 | primitiveType=NotSet(), property=NotSet()): 67 | ''' 68 | Instantiates Attribute Configuration API Object 69 | :param type: Type of AttributeConfiguration 70 | :param min: 71 | :param max: 72 | :param length: 73 | :param precision: 74 | :param list: 75 | :param pattern: 76 | :param primitiveType: PrimitiveType involved 77 | :param property: 78 | ''' 79 | self._setup( 80 | field_mapping={"type": FieldMapping(AttributeConfiguration.Type.decode, AttributeConfiguration.Type.encode), 81 | "length": FieldMapping(int), 82 | "min": FieldMapping(int), "max": FieldMapping(int), 83 | "precision": FieldMapping(int), "list": ListFieldMapping(str, str, NotSet()), 84 | "pattern": FieldMapping(str), "property": FieldMapping(str), 85 | "primitiveType": FieldMapping(AttributeConfiguration.PrimitiveType.decode, 86 | AttributeConfiguration.PrimitiveType.encode)}) 87 | self.type = type 88 | self.length = length 89 | self.min = min 90 | self.max = max 91 | self.precision = precision 92 | self.list = list 93 | self.pattern = pattern 94 | self.primitiveType = primitiveType 95 | self.property = property 96 | 97 | @classmethod 98 | def parse(cls, jsonObject): 99 | ''' 100 | Converts a Python Class Object (from JSON) to AttributeConfiguration 101 | :param jsonObject: 102 | :return: 103 | ''' 104 | result = AttributeConfiguration(type=decodeField(jsonObject["type"], str)) 105 | result._parse(jsonObject) 106 | return result 107 | -------------------------------------------------------------------------------- /PySiddhi/sp/EventSimulator/FeedSimulationConfiguration.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from PySiddhi.sp.EventSimulator.SimulationProperties import SimulationProperties 18 | from PySiddhi.sp.EventSimulator.SimulationSource import SimulationSource 19 | from PySiddhi.sp.ObjectMapping.APIObject import APIObject 20 | from PySiddhi.sp.ObjectMapping.FieldMapping import FieldMapping, ListFieldMapping 21 | 22 | 23 | class FeedSimulationConfiguration(APIObject): 24 | ''' 25 | FeedSimulationConfiguration API Object which could be passed to WSO2 SP Event Simulator via EventSimulatorClient. 26 | ''' 27 | 28 | def __init__(self, simulation_name=None, properties=None): 29 | ''' 30 | Instantiates FeedSimulationConfiguration. 31 | :param simulation_name: name of simulation 32 | :param properties: SimulationProperties 33 | ''' 34 | self._setup( 35 | field_mapping={"properties": FieldMapping(SimulationProperties.parse, SimulationProperties.toJSONObject), 36 | "sources": ListFieldMapping(SimulationSource.parse, SimulationSource.toJSONObject, [])}) 37 | if properties is not None: 38 | self.properties = properties 39 | elif simulation_name is not None: 40 | self.properties = SimulationProperties(simulationName=simulation_name) 41 | else: 42 | self.properties = SimulationProperties() 43 | self.sources = [] 44 | 45 | @classmethod 46 | def parse(cls, jsonObject): 47 | ''' 48 | Converts a Python Class Object (from JSON) to FeedSimulationConfiguration. 49 | :param jsonObject: 50 | :return: 51 | ''' 52 | result = FeedSimulationConfiguration(simulation_name=jsonObject["properties"]["simulationName"]) 53 | result._parse(jsonObject) 54 | return result 55 | -------------------------------------------------------------------------------- /PySiddhi/sp/EventSimulator/SimulationProperties.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | import random 18 | 19 | from PySiddhi.sp.ObjectMapping.APIObject import APIObject, NotSet 20 | from PySiddhi.sp.ObjectMapping.FieldMapping import FieldMapping 21 | from PySiddhi.sp.__Util import decodeField 22 | 23 | ran = random 24 | 25 | 26 | class SimulationProperties(APIObject): 27 | ''' 28 | SimulationProperties API Object of FeedSimulationConfiguration. 29 | ''' 30 | 31 | def __init__(self, simulationName="Simulation_" + str(random.randint(1, 1000)), timestampStartTime=NotSet(), 32 | timestampEndTime=NotSet(), noOfEvents=NotSet(), timeInterval=NotSet()): 33 | ''' 34 | Instantiates SimulationProperties 35 | :param simulationName: name of simulation 36 | :param timestampStartTime: 37 | :param timestampEndTime: 38 | :param noOfEvents: 39 | :param timeInterval: 40 | ''' 41 | self._setup(field_mapping={"simulationName": FieldMapping(str), "timestampStartTime": FieldMapping(int), 42 | "timestampEndTime": FieldMapping(int), "noOfEvents": FieldMapping(int), 43 | "timeInterval": FieldMapping(int)}) 44 | 45 | self.simulationName = simulationName 46 | self.timestampStartTime = timestampStartTime 47 | self.timestampEndTime = timestampEndTime 48 | self.noOfEvents = noOfEvents 49 | self.timeInterval = timeInterval 50 | 51 | @classmethod 52 | def parse(cls, jsonObject): 53 | ''' 54 | Converts a Python Class Object (from JSON) to SimulationProperties Object. 55 | :param jsonObject: 56 | :return: 57 | ''' 58 | result = SimulationProperties(simulationName=decodeField(jsonObject["simulationName"], str)) 59 | result._parse(jsonObject) 60 | return result 61 | -------------------------------------------------------------------------------- /PySiddhi/sp/EventSimulator/SimulationSource.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from enum import Enum 18 | 19 | from PySiddhi.sp.EventSimulator.AttributeConfiguration import AttributeConfiguration 20 | from PySiddhi.sp.ObjectMapping.APIObject import APIObject, NotSet 21 | from PySiddhi.sp.ObjectMapping.FieldMapping import FieldMapping, ListFieldMapping, strOrInt 22 | 23 | 24 | class SimulationSource(APIObject): 25 | ''' 26 | SimulationSource APIObject which can be added to sources of FeedSimulationConfiguration 27 | ''' 28 | 29 | class Type(Enum): 30 | ''' 31 | Type of SimulationSource 32 | ''' 33 | RANDOM_DATA_SIMULATION = "RANDOM_DATA_SIMULATION" 34 | CSV_SIMULATION = "CSV_SIMULATION" 35 | DATABASE_SIMULATION = "DATABASE_SIMULATION" 36 | 37 | @classmethod 38 | def encode(cls, v): 39 | return v.value 40 | 41 | @classmethod 42 | def decode(cls, v): 43 | return SimulationSource.Type(v) 44 | 45 | def __init__(self, simulationType=Type.RANDOM_DATA_SIMULATION, streamName=NotSet(), siddhiAppName=NotSet(), 46 | timestampInterval=NotSet(), attributeConfiguration=NotSet(), 47 | fileName=NotSet(), isOrdered=NotSet(), delimiter=NotSet(), timestampAttribute=NotSet(), 48 | dataSourceLocation=NotSet(), driver=NotSet(), 49 | username=NotSet(), password=NotSet(), tableName=NotSet(), columnNamesList=NotSet()): 50 | ''' 51 | Instantiates Simulation Source. Refer SP4 Documentation for details on parameters 52 | :param simulationType: Type of SimulationSource 53 | :param streamName: 54 | :param siddhiAppName: 55 | :param timestampInterval: 56 | :param attributeConfiguration: 57 | :param fileName: for File Access 58 | :param isOrdered: 59 | :param delimiter: 60 | :param timestampAttribute: 61 | :param dataSourceLocation: 62 | :param driver: for DB Access 63 | :param username: for DB access 64 | :param password: for DB Access 65 | :param tableName: for DB Access 66 | :param columnNamesList: for DB Access 67 | ''' 68 | self._setup( 69 | field_mapping={"simulationType": FieldMapping(SimulationSource.Type.decode, SimulationSource.Type.encode), 70 | "streamName": FieldMapping(str), 71 | "siddhiAppName": FieldMapping(str), "timestampInterval": FieldMapping(int), 72 | "attributeConfiguration": ListFieldMapping(AttributeConfiguration.parse, 73 | AttributeConfiguration.toJSONObject, []), 74 | "fileName": FieldMapping(str), "isOrdered": FieldMapping(bool), 75 | "delimiter": FieldMapping(str), 76 | "timestampAttribute": FieldMapping(strOrInt), "dataSourceLocation": FieldMapping(str), 77 | "driver": FieldMapping(str), 78 | "username": FieldMapping(str), "password": FieldMapping(str), "tableName": FieldMapping(str), 79 | "columnNamesList": FieldMapping(str)}) 80 | 81 | self.simulationType = simulationType 82 | self.streamName = streamName 83 | self.siddhiAppName = siddhiAppName 84 | self.timestampInterval = timestampInterval 85 | if attributeConfiguration == NotSet(): 86 | self.attributeConfiguration = [] 87 | else: 88 | self.attributeConfiguration = attributeConfiguration 89 | self.fileName = fileName 90 | self.isOrdered = isOrdered 91 | self.delimiter = delimiter 92 | self.timestampAttribute = timestampAttribute 93 | self.dataSourceLocation = dataSourceLocation 94 | self.driver = driver 95 | self.username = username 96 | self.password = password 97 | self.tableName = tableName 98 | self.columnNamesList = columnNamesList 99 | 100 | @classmethod 101 | def parse(cls, jsonObject): 102 | ''' 103 | Converts a Python Class Object (from JSON) to SimulationSource Object. 104 | :param jsonObject: 105 | :return: 106 | ''' 107 | result = SimulationSource() 108 | result._parse(jsonObject) 109 | return result 110 | -------------------------------------------------------------------------------- /PySiddhi/sp/EventSimulator/SingleSimulationConfiguration.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from PySiddhi.sp.ObjectMapping.APIObject import APIObject 18 | from PySiddhi.sp.ObjectMapping.FieldMapping import FieldMapping, ListFieldMapping 19 | 20 | 21 | class SingleSimulationConfiguration(APIObject): 22 | ''' 23 | SingleSimulationConfiguration APIObject which may be passed to WSO2 SP Event Simulator via EventSimulatorClient. 24 | ''' 25 | 26 | def __init__(self, siddhiAppName, streamName, data): 27 | ''' 28 | Instantiates SingleSimulationConfiguration 29 | :param siddhiAppName: 30 | :param streamName: 31 | :param data: 32 | ''' 33 | self._setup(field_mapping={"siddhiAppName": FieldMapping(str), "streamName": FieldMapping(str), 34 | "data": ListFieldMapping(int, str, []), "timestamp": FieldMapping(int)}) 35 | self.siddhiAppName = siddhiAppName 36 | self.streamName = streamName 37 | self.data = data 38 | self.timestamp = None 39 | -------------------------------------------------------------------------------- /PySiddhi/sp/EventSimulator/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /PySiddhi/sp/ObjectMapping/APIObject.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from abc import ABCMeta 18 | from future.utils import with_metaclass 19 | 20 | from PySiddhi.sp.__Util import decodeField, encodeField 21 | 22 | 23 | class NotSet(object): 24 | ''' 25 | Denotes that a fields value is not set. (null) 26 | ''' 27 | 28 | def __ne__(self, other): 29 | return not self.__eq__(other) 30 | 31 | def __eq__(self, other): 32 | if isinstance(other, NotSet): 33 | return True 34 | return False 35 | 36 | 37 | class APIObject(with_metaclass(ABCMeta, object)): 38 | ''' 39 | Abstract Object representing a model used by Rest API 40 | ''' 41 | 42 | def __new__(cls, *args, **kwargs): 43 | instance = object.__new__(cls) 44 | instance._field_mapping = None 45 | return instance 46 | 47 | def _setup(self, field_mapping): 48 | ''' 49 | Setup the APIObject using field mapping details provided 50 | :param field_mapping: details on mappings between JSON object fields and Python Class (model) fields 51 | :return: 52 | ''' 53 | self._field_mapping = field_mapping 54 | for k, v in field_mapping.items(): 55 | setattr(self, k, v.default_value) 56 | 57 | def __ne__(self, other): 58 | ''' 59 | Compare inequality between two API Objects 60 | :param other: 61 | :return: 62 | ''' 63 | # Note: Python2 requires explicit declaration of __ne__ for proper operation. 64 | return not self.__eq__(other) 65 | 66 | def __eq__(self, other): 67 | ''' 68 | Compare equality between two API Objects 69 | :param other: 70 | :return: 71 | ''' 72 | if type(self) != type(other): 73 | return False 74 | for k, v in self._field_mapping.items(): 75 | v1 = getattr(self, k, v.default_value) 76 | v2 = getattr(other, k, v.default_value) 77 | if (getattr(self, k, v.default_value) != getattr(other, k, v.default_value)): 78 | return False 79 | return True 80 | 81 | def toJSONObject(self): 82 | ''' 83 | Obtain JSON object of the APIObject 84 | :return: 85 | ''' 86 | result = {} 87 | for k, v in self._field_mapping.items(): 88 | val = getattr(self, k, v.default_value) 89 | if (v.addDefaultField or getattr(self, k, v.default_value) != v.default_value): 90 | result[k] = encodeField(getattr(self, k, v.default_value), v.encode_function) 91 | return result 92 | 93 | def _parse(self, jsonObject): 94 | ''' 95 | Obtain APIObject using JSONObject 96 | :param jsonObject: 97 | :return: 98 | ''' 99 | for k, v in self._field_mapping.items(): 100 | if k in jsonObject.keys(): 101 | setattr(self, k, decodeField(jsonObject[k], v.decode_function)) 102 | else: 103 | setattr(self, k, v.default_value) 104 | -------------------------------------------------------------------------------- /PySiddhi/sp/ObjectMapping/FieldMapping.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from PySiddhi.sp.ObjectMapping.APIObject import NotSet 18 | from PySiddhi.sp.__Util import encodeField, decodeField 19 | 20 | 21 | def strOrInt(v): 22 | ''' 23 | Determines whether v is String or Integer and returns appropriate object. 24 | :param v: 25 | :return: 26 | ''' 27 | v = str(v) 28 | if str.isnumeric(v): 29 | return int(v) 30 | else: 31 | return v 32 | 33 | 34 | class FieldMapping(object): 35 | ''' 36 | Describes a mapping of a field between JSON Object and APIObject 37 | ''' 38 | 39 | def __init__(self, decode_function, encode_function=str, default_value=NotSet(), addDefaultField=False): 40 | ''' 41 | Creates a field mapping between JSON Object field and API Object field 42 | :param decode_function: converts JSON field value to APIObject field value 43 | :param encode_function: converts APIObject field value JSON Object field value 44 | :param default_value: default value of APIObject field 45 | :param addDefaultField: set True to include the field in JSON Object even if the value is default 46 | ''' 47 | self.encode_function = encode_function 48 | self.decode_function = decode_function 49 | self.default_value = default_value 50 | self.addDefaultField = addDefaultField 51 | 52 | 53 | class ListFieldMapping(FieldMapping): 54 | ''' 55 | Describes a mapping between List of API Objects and a List of JSON Objects 56 | ''' 57 | 58 | def __init__(self, decode_function, encode_function, default_value=[]): 59 | ''' 60 | Creates a mapping between a List of API Objects and a List of JSON Objects 61 | :param decode_function: converts a JSON Object List item APIObject List item 62 | :param encode_function: converts an APIObject List item to JSON Object List item 63 | :param default_value: default value to be used when field (associating List) is absent 64 | ''' 65 | 66 | def encode_func(input_object): 67 | result_object = [] 68 | for item in input_object: 69 | result_object.append(encodeField(item, encode_function)) 70 | return result_object 71 | 72 | def decode_func(input_object): 73 | result_object = [] 74 | for item in input_object: 75 | result_object.append(decodeField(item, decode_function)) 76 | return result_object 77 | 78 | FieldMapping.__init__(self, decode_func, encode_func, default_value) 79 | -------------------------------------------------------------------------------- /PySiddhi/sp/ObjectMapping/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /PySiddhi/sp/SPClient.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from PySiddhi.sp.EventSimulator.EventSimulatorClient import EventSimulatorClient 18 | from PySiddhi.sp.SiddhiAppManagement.SiddhiAppManagementClient import SiddhiAppManagementClient 19 | 20 | 21 | class SPClient(object): 22 | ''' 23 | REST Client to work with WSO2 Stream Processor 4.x.x 24 | ''' 25 | 26 | def __init__(self, host_url): 27 | ''' 28 | Instantiate REST Client 29 | :param host_url: host url of SP worker. E.g. http://localhost:9090 30 | ''' 31 | self.host_url = host_url 32 | 33 | def getSiddhiAppManagementClient(self): 34 | ''' 35 | Obtain client for managing Siddhi Apps 36 | :return: 37 | ''' 38 | return SiddhiAppManagementClient(self.host_url + "/siddhi-apps") 39 | 40 | def getEventSimulatorClient(self): 41 | ''' 42 | Obtain client on event simulator 43 | :return: 44 | ''' 45 | return EventSimulatorClient(self.host_url + "/simulation") 46 | -------------------------------------------------------------------------------- /PySiddhi/sp/SiddhiAppManagement/SiddhiAppManagementClient.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from enum import Enum 18 | from requests.auth import HTTPBasicAuth 19 | 20 | from PySiddhi.sp.__Communication.RestClient import RestClient 21 | 22 | 23 | class UpdateAppStatusResponse(Enum): 24 | ''' 25 | Response from WSO2 SP on updateSidhdiApp call of SiddhiAppManagementClient. 26 | ''' 27 | savedNew = 201, 28 | updated = 200 29 | 30 | 31 | class SiddhiAppManagementClient(RestClient): 32 | ''' 33 | Client for Siddhi App Management (publish, edit, list, retrieve etc.) in WSO2 SP. 34 | ''' 35 | 36 | def __init__(self, siddhi_apps_url): 37 | ''' 38 | Instantiates SiddhiAppMangementClient. 39 | :param siddhi_apps_url: url to siddhi_apps endpoint (e.g. root_url + '/siddhi-apps') 40 | ''' 41 | RestClient.__init__(self, siddhi_apps_url) 42 | 43 | def retrieveSiddhiApp(self, siddhiAppName, username, password): 44 | ''' 45 | Retrieve siddhiApp stored in WSO2 SP. 46 | :param siddhiAppName: 47 | :return: 48 | ''' 49 | r = self._sendGetRequest("/" + siddhiAppName, auth=HTTPBasicAuth(username, password)) 50 | if r.status_code == 200: 51 | result = r.json() 52 | if "content" in result.keys(): 53 | siddhiApp = result["content"] 54 | return siddhiApp 55 | else: 56 | raise Exception("No content defined in response") 57 | elif r.status_code == 404: 58 | raise Exception("Siddhi App with specified name does not exist.") 59 | else: 60 | raise Exception(str(r.status_code) + ": " + r.text) 61 | 62 | def deleteSiddhiApp(self, siddhiAppName, username, password): 63 | ''' 64 | Deletes a SiddhiApp stored in WSO2 SP. 65 | :param siddhiAppName: 66 | :return: 67 | ''' 68 | r = self._sendDeleteRequest("/" + siddhiAppName, auth=HTTPBasicAuth(username, password)) 69 | if r.status_code == 200: 70 | return True 71 | elif r.status_code == 400: 72 | raise Exception("Siddhi App name provided is invalid.") 73 | elif r.status_code == 404: 74 | raise Exception("Siddhi App with specified name does not exist.") 75 | elif r.status_code == 500: 76 | raise Exception(str(r.status_code) + ": " + r.text) 77 | else: 78 | raise Exception(str(r.status_code) + ": " + r.text) 79 | 80 | def retrieveStatusSiddhiApp(self, siddhiAppName, username, password): 81 | ''' 82 | Retrieve the status of a SiddhiApp in WSO2 SP. 83 | :param siddhiAppName: 84 | :return: 85 | ''' 86 | r = self._sendGetRequest("/" + siddhiAppName + "/status", auth=HTTPBasicAuth(username, password)) 87 | if r.status_code == 200: 88 | result = r.json() 89 | if "status" in result.keys(): 90 | status = result["status"] 91 | return status 92 | else: 93 | raise Exception("No content defined in response") 94 | elif r.status_code == 404: 95 | raise Exception("Siddhi App with specified name does not exist.") 96 | else: 97 | raise Exception(str(r.status_code) + ": " + r.text) 98 | 99 | def listSiddhiApps(self,username, password, isActive=None): 100 | ''' 101 | Obtains the list of Siddhi Apps in WSO2 SP. 102 | :param isActive: 103 | :return: 104 | ''' 105 | params = None 106 | if isActive is not None: 107 | params = {"isActive": isActive} 108 | r = self._sendGetRequest("/", params=params, auth=HTTPBasicAuth(username, password)) 109 | if r.status_code == 200: 110 | result = r.json() 111 | return result 112 | else: 113 | raise Exception(str(r.status_code) + ": " + r.text) 114 | 115 | def updateSiddhiApp(self, siddhiApp, username, password): 116 | ''' 117 | Updates a Siddhi App in WSO2 SP. 118 | :param siddhiApp: 119 | :return: 120 | ''' 121 | r = self._sendPutRequest("/", data=siddhiApp, auth=HTTPBasicAuth(username, password)) 122 | if r.status_code == 200 or r.status_code == 201: 123 | result = r.json() 124 | if result["type"] == "success": 125 | if r.status_code == 200: 126 | return UpdateAppStatusResponse.updated 127 | elif r.status_code == 201: 128 | return UpdateAppStatusResponse.savedNew 129 | else: 130 | raise Exception("Result 'type' not 'success'") 131 | elif r.status_code == 400: 132 | raise Exception("A validation error occured.") 133 | elif r.status_code == 500: 134 | raise Exception("An unexpected error occured.") 135 | else: 136 | raise Exception(str(r.status_code) + ": " + r.text) 137 | 138 | def saveSiddhiApp(self, siddhiApp, username, password): 139 | ''' 140 | Saves a Siddhi App to WSO2 SP. 141 | :param siddhiApp: 142 | :return: 143 | ''' 144 | r = self._sendPostRequest("/", data=siddhiApp, auth=HTTPBasicAuth(username, password)) 145 | if r.status_code == 201: 146 | result = r.json() 147 | if result["type"] == "success": 148 | return True 149 | else: 150 | raise Exception("Result 'type' not 'success'") 151 | elif r.status_code == 400: 152 | raise Exception("A validation error occured.") 153 | elif r.status_code == 409: 154 | raise Exception("A Siddhi Application with the given name already exists.") 155 | elif r.status_code == 500: 156 | raise Exception("An unexpected error occured.") 157 | else: 158 | raise Exception(str(r.status_code) + ": " + r.text) 159 | -------------------------------------------------------------------------------- /PySiddhi/sp/SiddhiAppManagement/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /PySiddhi/sp/__Communication/RestClient.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | import requests 18 | 19 | 20 | class RestClient(object): 21 | ''' 22 | REST Client used internally to communicate with REST server 23 | ''' 24 | 25 | def __init__(self, base_url): 26 | ''' 27 | Instantiate Rest Client 28 | :param base_url: root url used 29 | ''' 30 | self.base_url = base_url 31 | 32 | def _sendGetRequest(self, sub_url, params=None, auth=None): 33 | ''' 34 | Sends a GET Request to Server 35 | :param sub_url: endpoint url which is to be appended to base url 36 | :param params: get parameters 37 | :return: 38 | ''' 39 | headers = {'content-type': 'text/plain'} 40 | resp = requests.get(self.base_url + sub_url, params=params, headers=headers, auth=auth) 41 | return resp 42 | 43 | def _sendPostRequest(self, sub_url, data=None, params=None, files=None, headers=None, auth=None): 44 | ''' 45 | Sends a POST Request to server 46 | :param sub_url: endpoint url which is to be appended to base url 47 | :param data: Payload data sent 48 | :param params: URL Parameters 49 | :param files: File Uploads 50 | :param headers: Custom headers 51 | :param username: auth user name 52 | :return: 53 | ''' 54 | resp = requests.post(self.base_url + sub_url, params=params, data=data, headers=headers, files=files, 55 | auth=auth) 56 | return resp 57 | 58 | def _sendPutRequest(self, sub_url, data=None, params=None, files=None, headers=None, auth=None): 59 | ''' 60 | Sends a PUT Request to server 61 | :param sub_url: endpoint url which is to be appended to base url 62 | :param data: Payload data sent 63 | :param params: URL Parameters 64 | :param files: File Uploads 65 | :param headers: Custom headers 66 | :return: 67 | ''' 68 | resp = requests.put(self.base_url + sub_url, params=params, files=files, data=data, headers=headers, auth=auth) 69 | return resp 70 | 71 | def _sendDeleteRequest(self, sub_url, params=None, auth=None): 72 | ''' 73 | Sends a DELETE Request to server 74 | :param sub_url: endpoint url which is to be appended to base url 75 | :param params: URL Parameters 76 | :return: 77 | ''' 78 | headers = {'content-type': 'text/plain'} 79 | resp = requests.delete(self.base_url + sub_url, params=params, headers=headers, auth=auth) 80 | return resp 81 | -------------------------------------------------------------------------------- /PySiddhi/sp/__Communication/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /PySiddhi/sp/__Util.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | def encodeField(value, encode_function=str): 18 | ''' 19 | Encodes a field value using encode_function 20 | :param value: 21 | :param encode_function: 22 | :return: 23 | ''' 24 | if value is None: 25 | return None 26 | return encode_function(value) 27 | 28 | 29 | def decodeField(value, decode_function): 30 | ''' 31 | Decodes a field value using given decode_function 32 | :param value: 33 | :param decode_function: 34 | :return: 35 | ''' 36 | if value is None: 37 | return None 38 | return decode_function(value) 39 | 40 | 41 | def decodeObject(jsonObject, target, decodeMap): 42 | ''' 43 | Decodes a JSON Object and assigns attributes to target. 44 | :param jsonObject: 45 | :param target: 46 | :param decodeMap: 47 | :return: 48 | ''' 49 | for (key, value) in jsonObject.items(): 50 | setattr(target, key, decodeField(value, decodeMap[key])) 51 | return target 52 | -------------------------------------------------------------------------------- /PySiddhi/sp/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [PySiddhi](https://siddhi-io.github.io/PySiddhi/) 2 | 3 | ***PySiddhi*** is a Python wrapper for [Siddhi](https://siddhi-io.github.io/siddhi/). Which can listens to events from data streams, detects complex conditions 4 | described via a ***Streaming SQL language***, and triggers actions. It performs both ***Stream Processing*** and 5 | ***Complex Event Processing*** on streaming data. Its Siddhi core is written in Java library. 6 | 7 | - PySiddhi wraps [Siddhi 5](https://siddhi-io.github.io/siddhi/) 8 | 9 | ## Features 10 | 11 | - [x] Basic functionality of Siddhi 5.x.x 12 | - [x] Siddhi Debugger 13 | - [x] Support to Siddhi Extensions Loading 14 | 15 | For a Quick Demo and documentation refer [PySiddhi Site](https://siddhi-io.github.io/PySiddhi/) 16 | 17 | ## Contribution 18 | 19 | _PySiddhi is initiated by a project for Google Summer of Code 2017 Program._ 20 | 21 | Contributed by: __Madhawa Vidanapathirana__ 22 | Email: madhawavidanapathirana@gmail.com 23 | Organization: University of Moratuwa, Sri Lanka. 24 | 25 | ## Support and Contribution 26 | 27 | * We encourage users to ask questions and get support via StackOverflow, make sure to add the `siddhi` tag to the issue for better response. 28 | 29 | * If you find any issues related to the extension please report them on the issue tracker. 30 | 31 | * For production support and other contribution related information refer Siddhi Community documentation. 32 | -------------------------------------------------------------------------------- /Requirements.txt: -------------------------------------------------------------------------------- 1 | pyjnius 2 | enum34 3 | future 4 | requests -------------------------------------------------------------------------------- /Tests/SPTests/Resources/TestSiddhiApp.siddhi: -------------------------------------------------------------------------------- 1 | 2 | @App:name('TestSiddhiApp') 3 | define stream FooStream (symbol string, price float, volume long); 4 | 5 | @source(type='inMemory', topic='symbol', @map(type='passThrough'))Define stream BarStream (symbol string, price float, volume long); 6 | 7 | from FooStream 8 | select symbol, price, volume 9 | insert into BarStream; -------------------------------------------------------------------------------- /Tests/SPTests/Resources/TestSiddhiApp1.siddhi: -------------------------------------------------------------------------------- 1 | @App:name('TestSiddhiApp1') 2 | define stream FooStream (symbol string, price float, volume long); 3 | 4 | @source(type='inMemory', topic='symbol', @map(type='passThrough')) 5 | Define stream BarStream (symbol string, price float, volume long); 6 | 7 | from FooStream 8 | select symbol, price, volume 9 | insert into BarStream; -------------------------------------------------------------------------------- /Tests/SPTests/Resources/sample.csv: -------------------------------------------------------------------------------- 1 | 1488615136968,wso2,10.0,10 2 | 1488615136970,wso2,20.0,20 3 | 1488615136972,wso2,30.0,30 4 | 1488615136977,wso2,40.0,40 5 | 1488615136978,wso2,50.0,50 6 | 7 | -------------------------------------------------------------------------------- /Tests/SPTests/SiddhiAppManagerTests.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | import os 18 | import unittest 19 | 20 | import logging 21 | from time import sleep 22 | 23 | from PySiddhi.sp.SPClient import SPClient 24 | from PySiddhi.sp.SiddhiAppManagement.SiddhiAppManagementClient import UpdateAppStatusResponse 25 | 26 | logging.basicConfig(level=logging.INFO) 27 | 28 | resources_path = os.path.join(os.path.dirname(__file__), "Resources") 29 | 30 | 31 | class EventSimulatorTests(unittest.TestCase): 32 | def setUp(self): 33 | self.hostUrl = "http://localhost:9090" 34 | logging.info("Prior to launching tests, make sure SP 4 is running at " + self.hostUrl) 35 | 36 | def tearDown(self): 37 | sleep(5) # Sleep to provide sufficient time for SP 4.0 to update status 38 | 39 | def testRetrieveSiddhiAppStatus(self): 40 | logging.info("Test1: Retrieving a Siddhi App Status") 41 | spPythonClient = SPClient(self.hostUrl) 42 | siddhiAppManagementClient = spPythonClient.getSiddhiAppManagementClient() 43 | 44 | status = siddhiAppManagementClient.retrieveStatusSiddhiApp("TestSiddhiApp", username="admin", 45 | password="admin") 46 | 47 | self.assertEqual(status, "active") 48 | 49 | def testRetrieveSiddhiApp(self): 50 | logging.info("Test1: Retrieving a Siddhi App") 51 | 52 | spPythonClient = SPClient(self.hostUrl) 53 | siddhiAppManagementClient = spPythonClient.getSiddhiAppManagementClient() 54 | 55 | app = siddhiAppManagementClient.retrieveSiddhiApp("TestSiddhiApp", username="admin", 56 | password="admin") 57 | 58 | lines = [] 59 | with open(resources_path + "/TestSiddhiApp.siddhi", "rb") as f: 60 | lines = [line.decode() for line in f.readlines()] 61 | 62 | target_app = "".join(lines) 63 | 64 | logging.info(target_app) 65 | 66 | logging.info(app) 67 | self.assertEqual(app, target_app) 68 | 69 | def testListSiddhiApps(self): 70 | logging.info("Test1: List Siddhi Apps") 71 | 72 | spPythonClient = SPClient(self.hostUrl) 73 | siddhiAppManagementClient = spPythonClient.getSiddhiAppManagementClient() 74 | 75 | lines = [] 76 | with open(resources_path + "/TestSiddhiApp1.siddhi", "rb") as f: 77 | lines = [line.decode() for line in f.readlines()] 78 | 79 | siddhiApp = "".join(lines) 80 | 81 | result = siddhiAppManagementClient.saveSiddhiApp(siddhiApp, username="admin", 82 | password="admin") 83 | self.assertTrue(result) 84 | 85 | sleep(5) 86 | 87 | apps = siddhiAppManagementClient.listSiddhiApps(username="admin", 88 | password="admin") 89 | logging.info(apps) 90 | self.assertTrue("TestSiddhiApp1" in apps) 91 | logging.info(apps) 92 | 93 | apps = siddhiAppManagementClient.listSiddhiApps(username="admin", 94 | password="admin", isActive=True) 95 | self.assertTrue("TestSiddhiApp1" in apps) 96 | logging.info(apps) 97 | 98 | apps = siddhiAppManagementClient.listSiddhiApps(username="admin", 99 | password="admin", isActive=False) 100 | self.assertTrue("TestSiddhiApp1" not in apps) 101 | logging.info(apps) 102 | 103 | result = siddhiAppManagementClient.deleteSiddhiApp("TestSiddhiApp1", username="admin", 104 | password="admin") 105 | self.assertTrue(result) 106 | 107 | def testSaveAndDeleteSiddhiApp(self): 108 | logging.info("Test1: Save and Delete Siddhi App") 109 | 110 | spPythonClient = SPClient(self.hostUrl) 111 | siddhiAppManagerClient = spPythonClient.getSiddhiAppManagementClient() 112 | 113 | lines = [] 114 | with open(resources_path + "/TestSiddhiApp1.siddhi", "rb") as f: 115 | lines = [line.decode() for line in f.readlines()] 116 | 117 | siddhiApp = "".join(lines) 118 | 119 | result = siddhiAppManagerClient.saveSiddhiApp(siddhiApp, username="admin", 120 | password="admin") 121 | self.assertTrue(result) 122 | 123 | sleep(5) 124 | 125 | result = siddhiAppManagerClient.deleteSiddhiApp("TestSiddhiApp1", username="admin", 126 | password="admin") 127 | self.assertTrue(result) 128 | 129 | def testUpdateAndDeleteSiddhiApp(self): 130 | logging.info("Test: Update and Delete Siddhi App") 131 | 132 | spPythonClient = SPClient(self.hostUrl) 133 | siddhiAppManagerClient = spPythonClient.getSiddhiAppManagementClient() 134 | 135 | lines = [] 136 | with open(resources_path + "/TestSiddhiApp1.siddhi", "rb") as f: 137 | lines = [line.decode() for line in f.readlines()] 138 | 139 | siddhiApp = "".join(lines) 140 | 141 | result = siddhiAppManagerClient.updateSiddhiApp(siddhiApp, username="admin", 142 | password="admin") 143 | self.assertTrue(result.name == UpdateAppStatusResponse.savedNew.name) 144 | 145 | sleep(5) 146 | 147 | result = siddhiAppManagerClient.updateSiddhiApp(siddhiApp, username="admin", 148 | password="admin") 149 | self.assertTrue(result.name == UpdateAppStatusResponse.updated.name) 150 | 151 | sleep(5) 152 | 153 | result = siddhiAppManagerClient.deleteSiddhiApp("TestSiddhiApp1", username="admin", 154 | password="admin") 155 | self.assertTrue(result) 156 | 157 | 158 | if __name__ == '__main__': 159 | unittest.main() 160 | -------------------------------------------------------------------------------- /Tests/SPTests/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /Tests/SiddhiCoreTests/BasicTest.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | 18 | import unittest 19 | import logging 20 | from time import sleep 21 | from PySiddhi.DataTypes.LongType import LongType 22 | from PySiddhi.core.SiddhiManager import SiddhiManager 23 | from PySiddhi.core.query.output.callback.QueryCallback import QueryCallback 24 | from PySiddhi.core.util.EventPrinter import PrintEvent 25 | 26 | logging.basicConfig(level=logging.INFO) 27 | 28 | 29 | class BasicTests(unittest.TestCase): 30 | def setUp(self): 31 | # Creating SiddhiManager 32 | self.siddhiManager = SiddhiManager() 33 | self.siddhiApp = "" + "define stream cseEventStream (symbol string, price float, volume long); " \ 34 | + "" + "@info(name = 'query1') " + "from cseEventStream[volume < 150] " \ 35 | + "select symbol,price " + "insert into outputStream ;" 36 | # Generating runtime 37 | # print(self.siddhiApp) 38 | self.siddhiAppRuntime = self.siddhiManager.createSiddhiAppRuntime(self.siddhiApp) 39 | 40 | def test_input_handler(self): 41 | logging.info("Test1: Test Input Handler") 42 | # Retrieving input handler to push events into Siddhi 43 | inputHandler = self.siddhiAppRuntime.getInputHandler("cseEventStream") 44 | # Starting event processing 45 | self.siddhiAppRuntime.start() 46 | 47 | # Sending events to Siddhi 48 | inputHandler.send(["IBM", 700.0, LongType(100)]) 49 | inputHandler.send(["WSO2", 60.5, LongType(200)]) 50 | inputHandler.send(["GOOG", 50, LongType(30)]) 51 | inputHandler.send(["IBM", 76.6, LongType(400)]) 52 | 53 | def test_siddhi_app_runtime_callback(self): 54 | logging.info("Test2: Test Siddhi App Runtime Callback") 55 | # Adding callback to retrieve output events from query 56 | 57 | global hitCount 58 | hitCount = 2 59 | 60 | class ConcreteQueryCallback(QueryCallback): 61 | def receive(self, timestamp, inEvents, outEvents): 62 | PrintEvent(timestamp, inEvents, outEvents) 63 | global hitCount 64 | hitCount -= 1 65 | 66 | self.siddhiAppRuntime.addCallback("query1", ConcreteQueryCallback()) 67 | 68 | # Retrieving input handler to push events into Siddhi 69 | inputHandler = self.siddhiAppRuntime.getInputHandler("cseEventStream") 70 | # Starting event processing 71 | self.siddhiAppRuntime.start() 72 | 73 | # Sending events to Siddhi 74 | inputHandler.send(["IBM", 700.0, LongType(100)]) 75 | inputHandler.send(["WSO2", 60.5, LongType(200)]) 76 | inputHandler.send(["GOOG", 50, LongType(30)]) 77 | inputHandler.send(["IBM", 76.6, LongType(400)]) 78 | 79 | sleep(0.5) 80 | self.assertEqual(hitCount, 0) 81 | 82 | def tearDown(self): 83 | # shutting down the runtime 84 | self.siddhiAppRuntime.shutdown() 85 | 86 | # shutting down Siddhi 87 | self.siddhiManager.shutdown() 88 | 89 | 90 | if __name__ == '__main__': 91 | unittest.main() 92 | -------------------------------------------------------------------------------- /Tests/SiddhiCoreTests/EventTest.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | import unittest 18 | import logging 19 | 20 | logging.basicConfig(level=logging.INFO) 21 | 22 | from PySiddhi.DataTypes.LongType import LongType 23 | from PySiddhi.core.event.Event import Event 24 | 25 | 26 | class BasicTests(unittest.TestCase): 27 | def test_data(self): 28 | logging.info("Test GetData and SetData Methods") 29 | 30 | event = Event(1, [2, LongType(3)]) 31 | self.assertListEqual(event.getData(), [2, LongType(3)], "GetData not equal to data given in constructor") 32 | self.assertTrue(type(event.getData(1)) == LongType, "Type of Parameter is not LongType") 33 | 34 | event.setData([1, 2]) 35 | self.assertListEqual(event.getData(), [1, 2], "GetData not equal to data set by SetData") 36 | 37 | def test_copyFromAndToString(self): 38 | logging.info("Test CopyFrom and ToString methods") 39 | 40 | event = Event(1, [2, LongType(3)]) 41 | event2 = Event(2) 42 | event2.copyFrom(event) 43 | 44 | self.assertEqual(str(event), str(event2), "ToString forms of copy is not equal") 45 | 46 | def test_Equals(self): 47 | logging.info("Test CopyFrom and ToString methods") 48 | 49 | event = Event(1, [2, LongType(3)]) 50 | event2 = Event(1, [2, LongType(3)]) 51 | 52 | self.assertEqual(event, event2, "Copy is not equal") 53 | 54 | event2 = Event(1, [2, 3]) 55 | self.assertNotEqual(event, event2, "Should not be equal due to Type diference") 56 | 57 | 58 | if __name__ == '__main__': 59 | unittest.main() 60 | -------------------------------------------------------------------------------- /Tests/SiddhiCoreTests/Resources/Extensions/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 23 | 4.0.0 24 | 25 | io.siddhi.python.api 26 | siddhi-python-api-extensions-downloader-for-tests 27 | 5.1.0 28 | Downloads extensions (JARS) used by Siddhi Python API Tests 29 | pom 30 | 31 | 32 | 33 | io.siddhi.extension.execution.string 34 | siddhi-execution-string 35 | 5.0.5 36 | 37 | 38 | io.siddhi.extension.execution.math 39 | siddhi-execution-math 40 | 5.0.3 41 | 42 | 43 | org.apache.commons 44 | commons-math3 45 | 3.2 46 | 47 | 48 | gov.nist.math 49 | jama 50 | 1.0.3 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | org.apache.maven.plugins 59 | maven-dependency-plugin 60 | 2.1 61 | 62 | 63 | copy-dependencies 64 | package 65 | 66 | copy-dependencies 67 | 68 | 69 | ${project.basedir}/jars/ 70 | false 71 | false 72 | true 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | wso2-nexus 84 | WSO2 internal Repository 85 | http://maven.wso2.org/nexus/content/groups/wso2-public/ 86 | 87 | true 88 | daily 89 | ignore 90 | 91 | 92 | 93 | 94 | wso2.releases 95 | WSO2 internal Repository 96 | http://maven.wso2.org/nexus/content/repositories/releases/ 97 | 98 | true 99 | daily 100 | ignore 101 | 102 | 103 | 104 | 105 | wso2.snapshots 106 | Apache Snapshot Repository 107 | http://maven.wso2.org/nexus/content/repositories/snapshots/ 108 | 109 | true 110 | daily 111 | 112 | 113 | false 114 | 115 | 116 | 117 | 118 | central 119 | Maven Repository Switchboard 120 | default 121 | http://repo1.maven.org/maven2 122 | 123 | false 124 | 125 | 126 | 127 | 128 | sonatype.releases 129 | https://oss.sonatype.org/content/repositories/releases/ 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | wso2.releases 138 | WSO2 internal Repository 139 | http://maven.wso2.org/nexus/content/repositories/releases/ 140 | 141 | true 142 | daily 143 | ignore 144 | 145 | 146 | 147 | 148 | wso2.snapshots 149 | Apache Snapshot Repository 150 | http://maven.wso2.org/nexus/content/repositories/snapshots/ 151 | 152 | true 153 | daily 154 | 155 | 156 | false 157 | 158 | 159 | 160 | 161 | wso2-nexus 162 | WSO2 internal Repository 163 | http://maven.wso2.org/nexus/content/groups/wso2-public/ 164 | 165 | true 166 | daily 167 | ignore 168 | 169 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /Tests/SiddhiCoreTests/TestOutputStream.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | import unittest 18 | 19 | import logging 20 | 21 | logging.basicConfig(level=logging.INFO) 22 | 23 | from time import sleep 24 | from unittest.case import TestCase 25 | 26 | from PySiddhi.core.SiddhiManager import SiddhiManager 27 | from PySiddhi.core.stream.output.StreamCallback import StreamCallback 28 | from Tests.Util.AtomicInt import AtomicInt 29 | 30 | 31 | class TestOutputStream(TestCase): 32 | def setUp(self): 33 | self.inEventCount = AtomicInt(0) 34 | self.debugEventCount = AtomicInt(0) 35 | 36 | def getCount(self, event): 37 | count = 0 38 | while event != None: 39 | count += 1 40 | event = event.getNext() 41 | 42 | return count 43 | 44 | def test_outputstram(self): 45 | logging.info("OutputStream Test 1: Test reception of events") 46 | siddhiManager = SiddhiManager() 47 | cseEventStream = "define stream cseEventStream (symbol string, price float, volume int);" 48 | 49 | query = "@info(name = 'query 1') from cseEventStream select symbol, price, volume insert into OutputStream; " 50 | 51 | siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(cseEventStream + query) 52 | 53 | _self_shaddow = self 54 | 55 | class StreamCallbackImpl(StreamCallback): 56 | def receive(self, events): 57 | _self_shaddow.inEventCount.addAndGet(len(events)) 58 | 59 | siddhiAppRuntime.addCallback("OutputStream", StreamCallbackImpl()) 60 | siddhiAppRuntime.start() 61 | 62 | inputHandler = siddhiAppRuntime.getInputHandler("cseEventStream") 63 | 64 | inputHandler.send(["WSO2", 50.0, 60]) 65 | inputHandler.send(["WSO2", 70.0, 40]) 66 | 67 | sleep(1) 68 | 69 | _self_shaddow.assertEqual(2, _self_shaddow.inEventCount.get(), "Invalid number of output events") 70 | 71 | siddhiAppRuntime.shutdown() 72 | 73 | 74 | if __name__ == '__main__': 75 | unittest.main() 76 | -------------------------------------------------------------------------------- /Tests/SiddhiCoreTests/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /Tests/SiddhiCoreTests/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Tests/Util/AtomicInt.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from multiprocessing import RLock 18 | 19 | 20 | class AtomicInt: 21 | ''' 22 | An atomic integer class. All operations are thread safe. 23 | ''' 24 | 25 | def __init__(self, value=0): 26 | self.value = value 27 | self.lock = RLock() 28 | 29 | def set(self, value): 30 | self.lock.acquire() 31 | self.value = value 32 | self.lock.release() 33 | 34 | def addAndGet(self, value): 35 | self.lock.acquire() 36 | self.value += value 37 | val = self.value 38 | self.lock.release() 39 | return val 40 | 41 | def get(self): 42 | self.lock.acquire() 43 | val = self.value 44 | self.lock.release() 45 | return val 46 | -------------------------------------------------------------------------------- /Tests/Util/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /Tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/java/io/siddhi/pythonapi/DataWrapProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package io.siddhi.pythonapi; 19 | 20 | import com.sun.org.apache.xpath.internal.operations.Bool; 21 | 22 | import java.util.logging.Logger; 23 | 24 | public class DataWrapProxy { 25 | /** 26 | * Wrapper on Data sent between Python and Java. This wrapper is needed due to following reasons 27 | * - Python doesnt support long datatype 28 | * - Pyjnius require uniform data type objects in arrays 29 | */ 30 | /** 31 | * Note: The approach taken here causes loss of precision in Double and Loss of range in Long. 32 | * TODO: Look for a better implementation of Double and Long, without loss of precision and range 33 | */ 34 | 35 | private Object data; 36 | 37 | /** 38 | * Constructor for integer wrapping 39 | * 40 | * @param data 41 | */ 42 | public DataWrapProxy(int data) { 43 | this.data = data; 44 | } 45 | 46 | /** 47 | * Constructor for boolean wrapping 48 | * 49 | * @param data 50 | */ 51 | public DataWrapProxy(boolean data) { 52 | this.data = data; 53 | } 54 | 55 | /** 56 | * Constructor for float wrapping 57 | * 58 | * @param data 59 | */ 60 | public DataWrapProxy(float data) { 61 | this.data = data; 62 | } 63 | 64 | /** 65 | * Constructor for String wrapping 66 | * 67 | * @param data 68 | */ 69 | public DataWrapProxy(String data) { 70 | this.data = data; 71 | } 72 | 73 | /** 74 | * Constructor for long wrapping 75 | * 76 | * @param data 77 | * @param isLong 78 | */ 79 | public DataWrapProxy(int data, boolean isLong) { 80 | this.data = (long) data; 81 | } 82 | 83 | /** 84 | * Constructor for null wrapping 85 | * 86 | * @param data 87 | * @param isLong 88 | * @param isNull 89 | */ 90 | public DataWrapProxy(int data, boolean isLong, boolean isNull) { 91 | if (isNull) { 92 | this.data = null; 93 | } 94 | } 95 | 96 | /** 97 | * Constructor for double wrapping 98 | * 99 | * @param data 100 | * @param isLong 101 | * @param isNull 102 | * @param isDouble 103 | */ 104 | public DataWrapProxy(float data, boolean isLong, boolean isNull, boolean isDouble) { 105 | if (isDouble) { 106 | this.data = (double) data; 107 | } 108 | } 109 | 110 | /** 111 | * Retrieve whether wrapped data is null 112 | * 113 | * @return 114 | */ 115 | public boolean isNull() { 116 | return this.data == null; 117 | } 118 | 119 | /** 120 | * Retrieve whether wrapped data is long 121 | * 122 | * @return 123 | */ 124 | public boolean isLong() { 125 | return this.data instanceof Long; 126 | } 127 | 128 | /** 129 | * Retrieve whether wrapped data is Double 130 | * 131 | * @return 132 | */ 133 | public boolean isDouble() { 134 | return this.data instanceof Double; 135 | } 136 | 137 | /** 138 | * Retrieve whether wrapped data is Int 139 | * 140 | * @return 141 | */ 142 | public boolean isInt() { 143 | return this.data instanceof Integer; 144 | } 145 | 146 | /** 147 | * Retrieve whether wrapped data is Float 148 | * 149 | * @return 150 | */ 151 | public boolean isFloat() { 152 | return this.data instanceof Float; 153 | } 154 | 155 | /** 156 | * Retrieve whether wrapped data is boolean 157 | * 158 | * @return 159 | */ 160 | public boolean isBoolean() { 161 | return this.data instanceof Boolean; 162 | } 163 | 164 | /** 165 | * Retrieve whether wrapped data is String 166 | * 167 | * @return 168 | */ 169 | public boolean isString() { 170 | return this.data instanceof String; 171 | } 172 | 173 | /** 174 | * Retrieve wrapped data 175 | * 176 | * @return 177 | */ 178 | public Object getData() { 179 | return data; 180 | } 181 | 182 | /** 183 | * Wrap data array 184 | * 185 | * @param data 186 | * @return 187 | */ 188 | public static DataWrapProxy[] wrapArray(Object[] data) { 189 | DataWrapProxy[] results = new DataWrapProxy[data.length]; 190 | for (int i = 0; i < data.length; i++) 191 | results[i] = DataWrapProxy.wrap(data[i]); 192 | return results; 193 | } 194 | 195 | /** 196 | * Wraps data item 197 | * 198 | * @param data data to be wrapped 199 | * @return 200 | */ 201 | public static DataWrapProxy wrap(Object data) { 202 | if (data == null) 203 | return new DataWrapProxy(null); 204 | if (data instanceof Integer) 205 | return new DataWrapProxy((Integer) data); 206 | else if (data instanceof Long) 207 | //TODO: Check removal of Integer casting here 208 | return new DataWrapProxy((int) (long) (Long) data, true); 209 | else if (data instanceof String) 210 | return new DataWrapProxy((String) data); 211 | else if (data instanceof Float) 212 | return new DataWrapProxy((Float) data); 213 | else if (data instanceof Boolean) 214 | return new DataWrapProxy((Boolean) data); 215 | else if (data instanceof Double) 216 | return new DataWrapProxy((float) (double) (Double) data, false, false, true); 217 | 218 | Logger.getLogger(DataWrapProxy.class.getName()).info("Unsupported Data Type: " 219 | + data.getClass().toString()); 220 | throw new RuntimeException("Unsupported Data Type"); 221 | } 222 | 223 | /** 224 | * Unwraps wrapped data item. 225 | * 226 | * @param data wrappedData 227 | * @return 228 | */ 229 | public static Object[] unwrapArray(DataWrapProxy[] data) { 230 | Object[] results = new Object[data.length]; 231 | for (int i = 0; i < data.length; i++) 232 | results[i] = data[i].getData(); 233 | return results; 234 | } 235 | 236 | 237 | } 238 | -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/java/io/siddhi/pythonapi/proxy/core/SiddhiAPICoreProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | 20 | package io.siddhi.pythonapi.proxy.core; 21 | 22 | import io.siddhi.core.SiddhiAppRuntime; 23 | import io.siddhi.core.SiddhiManager; 24 | import io.siddhi.pythonapi.proxy.core.query.output.callback.query_callback.QueryCallbackProxy; 25 | import io.siddhi.pythonapi.proxy.core.stream.output.callback.stream_callback.StreamCallbackProxy; 26 | 27 | public class SiddhiAPICoreProxy { 28 | /** 29 | * Instatiate API 30 | * 31 | * @param versionMajor Major Version of Python 32 | * @param versionMinor Minor Version of Python 33 | */ 34 | public SiddhiAPICoreProxy(int versionMajor, int versionMinor) { 35 | SiddhiAPICoreProxy.setPythonVersionMajor(versionMajor); 36 | SiddhiAPICoreProxy.setPythonVersionMinor(versionMinor); 37 | } 38 | 39 | /** 40 | * Initiates a new Siddhi Manager and return instance to Python API 41 | * 42 | * @return new SiddhiManager Instance 43 | */ 44 | public SiddhiManager initSiddhiManager() { 45 | return new SiddhiManager(); 46 | } 47 | 48 | private static int python_version_major = -1; 49 | private static int python_version_minor = -1; 50 | 51 | /** 52 | * Register a SiddhiAppRuntimeQueryCallback with SiddhiAppRuntime 53 | * 54 | * @param siddhiAppRuntime 55 | * @param name 56 | * @param queryCallbackProxy 57 | */ 58 | public void addSiddhiAppRuntimeQueryCallback(SiddhiAppRuntime siddhiAppRuntime, String name, 59 | final QueryCallbackProxy queryCallbackProxy) { 60 | siddhiAppRuntime.addCallback(name, queryCallbackProxy); 61 | } 62 | 63 | /** 64 | * Register a SiddhiAppRuntimeStreamCallback with SiddhiAppRuntime 65 | * 66 | * @param siddhiAppRuntime 67 | * @param name 68 | * @param queryCallbackProxy 69 | */ 70 | public void addSiddhiAppRuntimeStreamCallback(SiddhiAppRuntime siddhiAppRuntime, String name, 71 | final StreamCallbackProxy streamCallbackProxy) { 72 | siddhiAppRuntime.addCallback(name, streamCallbackProxy); 73 | 74 | } 75 | 76 | /** 77 | * Retrieve Major Python Version 78 | * 79 | * @return 80 | */ 81 | public static int getPythonVersionMajor() { 82 | return python_version_major; 83 | } 84 | 85 | /** 86 | * Sets Major Python Version 87 | * 88 | * @param python_version_major 89 | */ 90 | public static void setPythonVersionMajor(int python_version_major) { 91 | SiddhiAPICoreProxy.python_version_major = python_version_major; 92 | } 93 | 94 | /** 95 | * Retrieve Major Python Version 96 | * 97 | * @return 98 | */ 99 | public static int getPythonVersionMinor() { 100 | return python_version_minor; 101 | } 102 | 103 | /** 104 | * Sets Major Python Version 105 | * 106 | * @param python_version_minor 107 | */ 108 | public static void setPythonVersionMinor(int python_version_minor) { 109 | SiddhiAPICoreProxy.python_version_minor = python_version_minor; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/java/io/siddhi/pythonapi/proxy/core/debugger/siddhi_debugger/QueryTerminalProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package io.siddhi.pythonapi.proxy.core.debugger.siddhi_debugger; 20 | 21 | import io.siddhi.core.debugger.SiddhiDebugger; 22 | 23 | /** 24 | * Proxy on io.siddhi.core.debugger.SiddhiDebugger.QueryTerminal 25 | */ 26 | public class QueryTerminalProxy { 27 | public SiddhiDebugger.QueryTerminal IN() { 28 | return SiddhiDebugger.QueryTerminal.IN; 29 | } 30 | 31 | public SiddhiDebugger.QueryTerminal OUT() { 32 | return SiddhiDebugger.QueryTerminal.OUT; 33 | } 34 | 35 | private SiddhiDebugger.QueryTerminal enclosedValue = SiddhiDebugger.QueryTerminal.IN; 36 | 37 | public QueryTerminalProxy() { 38 | //Constructor let open to allow access of IN and OUT methods from Python (because Pyjnius doesn't support 39 | // class level methods) 40 | } 41 | 42 | public QueryTerminalProxy(SiddhiDebugger.QueryTerminal enclosedValue) { 43 | this.enclosedValue = enclosedValue; 44 | } 45 | 46 | public SiddhiDebugger.QueryTerminal getValue() { 47 | return this.enclosedValue; 48 | } 49 | 50 | public boolean isValueIn() { 51 | return this.enclosedValue == IN(); 52 | } 53 | 54 | public boolean isValueOut() { 55 | return this.enclosedValue == OUT(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/java/io/siddhi/pythonapi/proxy/core/debugger/siddhi_debugger_callback/SiddhiDebuggerCallbackProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package io.siddhi.pythonapi.proxy.core.debugger.siddhi_debugger_callback; 20 | 21 | import org.apache.log4j.Logger; 22 | import io.siddhi.core.debugger.SiddhiDebugger; 23 | import io.siddhi.core.debugger.SiddhiDebuggerCallback; 24 | import io.siddhi.core.event.ComplexEvent; 25 | import io.siddhi.pythonapi.proxy.core.debugger.siddhi_debugger_callback.event_polling.EventQueue; 26 | import io.siddhi.pythonapi.proxy.core.debugger.siddhi_debugger_callback.event_polling.QueuedEvent; 27 | import io.siddhi.pythonapi.proxy.core.debugger.siddhi_debugger.QueryTerminalProxy; 28 | import io.siddhi.pythonapi.proxy.core.stream.output.callback.stream_callback.StreamCallbackProxy; 29 | import io.siddhi.pythonapi.threadfix.PyThreadFixCaller; 30 | 31 | /** 32 | * Proxy on io.siddhi.core.debugger.SiddhiDebuggerCallback 33 | */ 34 | public class SiddhiDebuggerCallbackProxy implements SiddhiDebuggerCallback { 35 | private static final Logger log = Logger.getLogger(StreamCallbackProxy.class); 36 | 37 | private EventQueue debuggerEventQueue = new EventQueue(); 38 | 39 | public EventQueue getEventQueue() { 40 | return this.debuggerEventQueue; 41 | } 42 | 43 | public void debugEvent(ComplexEvent complexEvent, String queryName, 44 | SiddhiDebugger.QueryTerminal queryTerminal, SiddhiDebugger siddhiDebugger) { 45 | PyThreadFixCaller.fix(); 46 | log.info("Debug Event Called"); 47 | debuggerEventQueue.addEvent(QueuedEvent.createDebugEvent(complexEvent, queryName, 48 | new QueryTerminalProxy(queryTerminal), siddhiDebugger)); 49 | } 50 | 51 | @Override 52 | public void finalize() throws java.lang.Throwable { 53 | //We need to inform Python when Java GC collects so it can remove the references held 54 | log.info("Java GC Collection"); 55 | debuggerEventQueue.addEvent(QueuedEvent.createGCEvent()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/java/io/siddhi/pythonapi/proxy/core/debugger/siddhi_debugger_callback/event_polling/EventQueue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package io.siddhi.pythonapi.proxy.core.debugger.siddhi_debugger_callback.event_polling; 20 | 21 | import org.apache.log4j.Logger; 22 | import io.siddhi.pythonapi.proxy.core.stream.output.callback.stream_callback.StreamCallbackProxy; 23 | 24 | import java.util.Queue; 25 | import java.util.concurrent.ConcurrentLinkedQueue; 26 | import java.util.concurrent.Semaphore; 27 | 28 | /** 29 | * Shared Queue of events between Java and Python. Used to pass Debug Events to Python from Java using polling. 30 | */ 31 | public class EventQueue { 32 | private Queue queuedEvents = null; 33 | private Semaphore eventsBlock = null; //Used to block getQueuedEvents when no events are present 34 | private boolean blocked = false; //Indicates whether a blocked getQueuedEvents is pending 35 | 36 | /** 37 | * Instantiate a new EventQueue 38 | */ 39 | public EventQueue() { 40 | this.queuedEvents = new ConcurrentLinkedQueue(); 41 | this.eventsBlock = new Semaphore(0); 42 | this.blocked = false; 43 | } 44 | 45 | private static final Logger log = Logger.getLogger(EventQueue.class); 46 | 47 | /** 48 | * Retrieve the next event in queue. Blocks if no events in queue. 49 | * 50 | * @return 51 | */ 52 | public QueuedEvent getQueuedEvent() { 53 | 54 | if (queuedEvents.isEmpty()) { 55 | try { 56 | synchronized (this) { 57 | this.blocked = true; 58 | } 59 | log.trace("Event Block Check"); 60 | eventsBlock.acquire(); 61 | log.trace("Event Block Acquired"); 62 | synchronized (this) { 63 | this.blocked = false; 64 | } 65 | log.trace("Block unset"); 66 | } catch (InterruptedException e) { 67 | e.printStackTrace(); 68 | } 69 | } 70 | log.trace("Returning queued events"); 71 | return queuedEvents.remove(); 72 | } 73 | 74 | /** 75 | * Interrupts a pending blocking call to getQueuedEvent. 76 | * Interrupt should be used when SiddhiDebuggerCallback is changed to release the event processing thread 77 | * from blocking getQueuedEvent call 78 | */ 79 | public void interrupt() { 80 | synchronized (this) { 81 | if (blocked) { 82 | eventsBlock.release(); 83 | log.trace("Interrupt Released"); 84 | this.blocked = false; 85 | } 86 | } 87 | } 88 | 89 | /** 90 | * Retrieve the next event in queue. Return null if no event. 91 | * 92 | * @return 93 | */ 94 | public QueuedEvent getQueuedEventAsync() { 95 | if (queuedEvents.isEmpty()) 96 | return null; 97 | 98 | return queuedEvents.remove(); 99 | } 100 | 101 | /** 102 | * Adds an event to event queue. 103 | * 104 | * @param event Event to be added 105 | */ 106 | public void addEvent(QueuedEvent event) { 107 | log.trace("Event Added"); 108 | queuedEvents.add(event); 109 | synchronized (this) { 110 | if (blocked) { 111 | eventsBlock.release(); 112 | this.blocked = false; 113 | } 114 | 115 | } 116 | } 117 | } 118 | 119 | -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/java/io/siddhi/pythonapi/proxy/core/debugger/siddhi_debugger_callback/event_polling/QueuedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package io.siddhi.pythonapi.proxy.core.debugger.siddhi_debugger_callback.event_polling; 20 | 21 | import org.apache.log4j.Logger; 22 | import io.siddhi.core.debugger.SiddhiDebugger; 23 | import io.siddhi.core.event.ComplexEvent; 24 | import io.siddhi.pythonapi.proxy.core.debugger.siddhi_debugger.QueryTerminalProxy; 25 | 26 | /** 27 | * Event queued in EventQueue 28 | */ 29 | public class QueuedEvent { 30 | 31 | private static final Logger log = Logger.getLogger(QueuedEvent.class); 32 | 33 | /** 34 | * Type of event 35 | */ 36 | public enum QueuedEventType { 37 | /** 38 | * SiddhiDebuggerCallback Debug event 39 | */ 40 | DebugEvent, 41 | 42 | /** 43 | * Java Garbage Collection event. This is raised when the debugger callback is destroyed from JVM. 44 | */ 45 | GCEvent 46 | } 47 | 48 | /** 49 | * Create a QueuedEvent informing a SiddhiDebuggerCallback debugEvent 50 | * 51 | * @param complexEvent event parameter of debugEvent 52 | * @param queryName queryName of debugEvent 53 | * @param queryTerminal queryTerminal of debugEvent 54 | * @param debugger debugger of debugEvent 55 | * @return QueuedEvent on debugEvent 56 | */ 57 | public static QueuedEvent createDebugEvent(ComplexEvent complexEvent, String queryName, 58 | QueryTerminalProxy queryTerminal, SiddhiDebugger debugger) { 59 | Object[] params = {complexEvent, queryName, queryTerminal, debugger}; 60 | return new QueuedEvent(QueuedEventType.DebugEvent, params); 61 | } 62 | 63 | /** 64 | * Create a QueuedEvent informing JVM Garbage Collection SiddhiDebuggerCallback 65 | * 66 | * @return QueuedEvent on JVM Garbage Collection 67 | */ 68 | public static QueuedEvent createGCEvent() { 69 | return new QueuedEvent(QueuedEventType.GCEvent, null); 70 | } 71 | 72 | /** 73 | * Creates a QueuedEvent of given type and parameters 74 | * 75 | * @param eventType Type of event 76 | * @param parameters Arguments to be provided to event callback 77 | */ 78 | public QueuedEvent(QueuedEventType eventType, Object[] parameters) { 79 | this.eventType = eventType; 80 | this.parameters = parameters; 81 | } 82 | 83 | private QueuedEventType eventType; 84 | private Object[] parameters; 85 | 86 | /** 87 | * Retrieve event type 88 | * 89 | * @return event type 90 | */ 91 | public QueuedEventType getEventType() { 92 | return eventType; 93 | } 94 | 95 | /** 96 | * Retrieve whether the QueuedEvent is a SiddhiDebuggerCallback debugEvent 97 | * 98 | * @return true if QueuedEvent is a SiddhiDebuggerCallback debugEvent. Otherwise return false. 99 | */ 100 | public boolean isDebugEvent() { 101 | return eventType == QueuedEventType.DebugEvent; 102 | } 103 | 104 | /** 105 | * Retrieve whether the QueuedEvent is a GCEvent 106 | * 107 | * @return true if QueuedEvent is a GCEvent. Otherwise return false. 108 | */ 109 | public boolean isGCEvent() { 110 | return eventType == QueuedEventType.GCEvent; 111 | } 112 | 113 | /** 114 | * Obtain parameter at given index as a @ComplexEvent 115 | * 116 | * @param parameterId Argument Index 117 | * @return @ComplexEvent which is passed as @parameterId argument of callback 118 | */ 119 | public ComplexEvent getComplexEvent(int parameterId) { 120 | return (ComplexEvent) parameters[parameterId]; 121 | } 122 | 123 | /** 124 | * Obtain parameter at given index as a @String 125 | * 126 | * @param parameterId Argument Index 127 | * @return @String which is passed as @parameterId argument of callback 128 | */ 129 | public String getString(int parameterId) { 130 | return (String) parameters[parameterId]; 131 | } 132 | 133 | /** 134 | * Obtain parameter at given index as a @SiddhiDebugger 135 | * 136 | * @param parameterId Argument Index 137 | * @return @SiddhiDebugger which is passed as @parameterId argument of callback 138 | */ 139 | public SiddhiDebugger getSiddhiDebugger(int parameterId) { 140 | return (SiddhiDebugger) parameters[parameterId]; 141 | } 142 | 143 | /** 144 | * Obtain parameter at given index as a @QueryTerminalProxy 145 | * 146 | * @param parameterId Argument Index 147 | * @return @SiddhiDebugger which is passed as @parameterId argument of callback 148 | */ 149 | public QueryTerminalProxy getQueryTerminal(int parameterId) { 150 | return (QueryTerminalProxy) parameters[parameterId]; 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/java/io/siddhi/pythonapi/proxy/core/event/complex_event/ComplexEventProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package io.siddhi.pythonapi.proxy.core.event.complex_event; 20 | 21 | import io.siddhi.core.event.ComplexEvent; 22 | import io.siddhi.pythonapi.DataWrapProxy; 23 | 24 | /** 25 | * Proxy on io.siddhi.core.event.ComplexEvent 26 | */ 27 | public class ComplexEventProxy { 28 | public DataWrapProxy[] getOutputData(ComplexEvent target) { 29 | return DataWrapProxy.wrapArray(target.getOutputData()); 30 | } 31 | 32 | public void setOutputData(ComplexEvent target, DataWrapProxy data, int index) { 33 | target.setOutputData(data.getData(), index); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/java/io/siddhi/pythonapi/proxy/core/event/complex_event/TypeProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package io.siddhi.pythonapi.proxy.core.event.complex_event; 20 | 21 | import io.siddhi.core.event.ComplexEvent; 22 | 23 | /** 24 | * Proxy on type of ComplexEvent 25 | */ 26 | public class TypeProxy { 27 | public ComplexEvent.Type CURRENT() { 28 | return ComplexEvent.Type.CURRENT; 29 | } 30 | 31 | public ComplexEvent.Type EXPIRED() { 32 | return ComplexEvent.Type.EXPIRED; 33 | } 34 | 35 | public ComplexEvent.Type TIMER() { 36 | return ComplexEvent.Type.TIMER; 37 | } 38 | 39 | public ComplexEvent.Type RESET() { 40 | return ComplexEvent.Type.RESET; 41 | } 42 | 43 | private ComplexEvent.Type enclosedValue = ComplexEvent.Type.CURRENT; 44 | 45 | public TypeProxy() { 46 | //Constructor let open to allow access of CURRENT, EXPIRED, TIMER and RESET (because Pyjnius doesn't 47 | // support class level methods) 48 | } 49 | 50 | public TypeProxy(ComplexEvent.Type enclosedValue) { 51 | this.enclosedValue = enclosedValue; 52 | } 53 | 54 | public ComplexEvent.Type getValue() { 55 | return this.enclosedValue; 56 | } 57 | 58 | public boolean isValueCurrent() { 59 | return this.enclosedValue == CURRENT(); 60 | } 61 | 62 | public boolean isValueExpired() { 63 | return this.enclosedValue == EXPIRED(); 64 | } 65 | 66 | public boolean isValueTimer() { 67 | return this.enclosedValue == TIMER(); 68 | } 69 | 70 | public boolean isValueReset() { 71 | return this.enclosedValue == RESET(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/java/io/siddhi/pythonapi/proxy/core/event/event/EventProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package io.siddhi.pythonapi.proxy.core.event.event; 20 | 21 | import io.siddhi.core.event.ComplexEvent; 22 | import io.siddhi.core.event.Event; 23 | import io.siddhi.pythonapi.DataWrapProxy; 24 | 25 | /** 26 | * Proxy on io.siddhi.core.event.Event 27 | */ 28 | public class EventProxy { 29 | public Event createEvent(long timeStamp, DataWrapProxy[] data) { 30 | return new Event(timeStamp, DataWrapProxy.unwrapArray(data)); 31 | } 32 | 33 | public DataWrapProxy[] getData(Event target) { 34 | return DataWrapProxy.wrapArray(target.getData()); 35 | } 36 | 37 | public DataWrapProxy getDataItem(Event target, int index) { 38 | Object data = target.getData(index); 39 | return DataWrapProxy.wrap(data); 40 | } 41 | 42 | public void setData(Event target, DataWrapProxy[] data) { 43 | target.setData(DataWrapProxy.unwrapArray(data)); 44 | } 45 | 46 | public void makeExpired(Event target) { 47 | target.setIsExpired(true); 48 | } 49 | 50 | public void makeUnExpired(Event target) { 51 | target.setIsExpired(false); 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/java/io/siddhi/pythonapi/proxy/core/query/output/callback/query_callback/QueryCallbackProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package io.siddhi.pythonapi.proxy.core.query.output.callback.query_callback; 20 | 21 | import org.apache.log4j.Logger; 22 | import io.siddhi.core.event.Event; 23 | import io.siddhi.core.query.output.callback.QueryCallback; 24 | import io.siddhi.pythonapi.threadfix.PyThreadFixCaller; 25 | 26 | /** 27 | * Proxy class on io.siddhi.core.query.output.callback.QueryCallback 28 | */ 29 | public class QueryCallbackProxy extends QueryCallback { 30 | private ReceiveCallbackProxy receiveCallback = null; 31 | 32 | public void setReceiveCallback(ReceiveCallbackProxy value) { 33 | this.receiveCallback = value; 34 | } 35 | 36 | private static final Logger log = Logger.getLogger(QueryCallbackProxy.class); 37 | 38 | public void receive(long timestamp, Event[] inEvents, Event[] ouEvents) { 39 | PyThreadFixCaller.fix(); 40 | 41 | if (this.receiveCallback != null) 42 | this.receiveCallback.receive(timestamp, inEvents, ouEvents); 43 | 44 | } 45 | 46 | @Override 47 | public void finalize() throws java.lang.Throwable { 48 | //We need to inform Python when Java GC collects so it can remove the references held 49 | log.info("Java GC Collection"); 50 | this.receiveCallback.gc(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/java/io/siddhi/pythonapi/proxy/core/query/output/callback/query_callback/ReceiveCallbackProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package io.siddhi.pythonapi.proxy.core.query.output.callback.query_callback; 20 | 21 | import io.siddhi.core.event.Event; 22 | 23 | /** 24 | * Proxy callback on receive method of io.siddhi.core.query.output.callback.QueryCallback 25 | */ 26 | public interface ReceiveCallbackProxy { 27 | void receive(long l, Event[] events, Event[] events1); 28 | 29 | void gc(); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/java/io/siddhi/pythonapi/proxy/core/stream/input/input_handler/InputHandlerProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package io.siddhi.pythonapi.proxy.core.stream.input.input_handler; 20 | 21 | import io.siddhi.core.stream.input.InputHandler; 22 | import io.siddhi.pythonapi.DataWrapProxy; 23 | 24 | import java.util.HashMap; 25 | 26 | /** 27 | * Proxy wrapper on io.siddhi.core.stream.input.InputHandler 28 | */ 29 | public class InputHandlerProxy { 30 | /** 31 | * Sends input via InputHandler 32 | * 33 | * @param target target InputHandler 34 | * @param data data fed into InputHandler 35 | * @throws InterruptedException 36 | */ 37 | public void send(InputHandler target, DataWrapProxy[] data) throws InterruptedException { 38 | target.send(DataWrapProxy.unwrapArray(data)); 39 | 40 | HashMap hm = new HashMap(); 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/java/io/siddhi/pythonapi/proxy/core/stream/output/callback/stream_callback/ReceiveCallbackProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package io.siddhi.pythonapi.proxy.core.stream.output.callback.stream_callback; 20 | 21 | import io.siddhi.core.event.Event; 22 | 23 | public interface ReceiveCallbackProxy { 24 | void receive(Event[] events); 25 | 26 | void gc(); 27 | } 28 | -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/java/io/siddhi/pythonapi/proxy/core/stream/output/callback/stream_callback/StreamCallbackProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package io.siddhi.pythonapi.proxy.core.stream.output.callback.stream_callback; 20 | 21 | import org.apache.log4j.Logger; 22 | import io.siddhi.core.event.Event; 23 | import io.siddhi.core.stream.output.StreamCallback; 24 | import io.siddhi.pythonapi.threadfix.PyThreadFix; 25 | import io.siddhi.pythonapi.threadfix.PyThreadFixCaller; 26 | 27 | public class StreamCallbackProxy extends StreamCallback { 28 | private ReceiveCallbackProxy receiveCallback = null; 29 | 30 | public void setReceiveCallback(ReceiveCallbackProxy value) { 31 | this.receiveCallback = value; 32 | } 33 | 34 | private static final Logger log = Logger.getLogger(StreamCallbackProxy.class); 35 | 36 | public void receive(Event[] events) { 37 | PyThreadFixCaller.fix(); 38 | 39 | this.receiveCallback.receive(events); 40 | } 41 | 42 | @Override 43 | public void finalize() throws java.lang.Throwable { 44 | //We need to inform Python when Java GC collects so it can remove the references held 45 | log.info("Java GC Collection"); 46 | this.receiveCallback.gc(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/java/io/siddhi/pythonapi/proxy/core/util/EventPrinterProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package io.siddhi.pythonapi.proxy.core.util; 20 | 21 | import io.siddhi.core.event.Event; 22 | import io.siddhi.core.util.EventPrinter; 23 | 24 | /** 25 | * Proxy class used to interface with io.siddhi.core.util.EventPrinter 26 | */ 27 | public class EventPrinterProxy { 28 | private EventPrinterProxy() { 29 | } 30 | 31 | public static void printEvent(long timeStamp, Event[] inEvents, Event[] outEvents) { 32 | EventPrinter.print(timeStamp, inEvents, outEvents); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/java/io/siddhi/pythonapi/threadfix/PyThreadFix.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package io.siddhi.pythonapi.threadfix; 20 | 21 | import io.siddhi.pythonapi.proxy.core.SiddhiAPICoreProxy; 22 | 23 | public class PyThreadFix { 24 | /** 25 | * PyThreadFix is used to fix a threading related issue in Python 3.4+. 26 | * Issue Description: 27 | * In Python 3.4+, callbacks to Python from non Python created threads cause Python interpreter to crash. 28 | * This could be fixed by calling a set of Python C API functions prior to sending the callback to Python. 29 | * The set of Python C API functions required are called in fixThread native method. 30 | */ 31 | static { 32 | System.loadLibrary("io_siddhi_pythonapi_threadfix_pythreadfix"); // Load native library at runtime 33 | } 34 | 35 | // The native fixThread method which has necessary C code to fix the threading issue 36 | private native void fixThread(); 37 | 38 | /** 39 | * Invoke fixThread 40 | */ 41 | public void fix() { 42 | this.fixThread(); 43 | } 44 | 45 | // Test Driver 46 | public static void main(String[] args) { 47 | new PyThreadFix().fixThread(); // invoke the native method 48 | } 49 | } -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/java/io/siddhi/pythonapi/threadfix/PyThreadFixCaller.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package io.siddhi.pythonapi.threadfix; 20 | 21 | import io.siddhi.pythonapi.proxy.core.SiddhiAPICoreProxy; 22 | 23 | /** 24 | * A wrapper on ThreadFix Call 25 | */ 26 | public class PyThreadFixCaller { 27 | 28 | private PyThreadFixCaller() { 29 | } 30 | 31 | /** 32 | * Invokes threadFix if required 33 | */ 34 | public static void fix() { 35 | if (System.getProperty("os.name").toLowerCase().startsWith("windows")) //No Threadfix for Windows 36 | return; 37 | //Do a version check. The fix is needed in Python 3.4+ 38 | if (SiddhiAPICoreProxy.getPythonVersionMajor() == 3 && SiddhiAPICoreProxy.getPythonVersionMinor() >= 4) 39 | new PyThreadFix().fix(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/java/org/jnius/NativeInvocationHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file has been directly extracted from Project pyjnius (https://github.com/kivy/pyjnius/) by kivy which 3 | * is subjected to following MIT License. 4 | * 5 | * Copyright (c) 2010-2017 Kivy Team and other contributors 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | package org.jnius; 26 | import org.apache.log4j.Logger; 27 | 28 | import java.lang.reflect.InvocationHandler; 29 | import java.lang.reflect.Method; 30 | 31 | public class NativeInvocationHandler implements InvocationHandler { 32 | static boolean DEBUG = false; 33 | private long ptr; 34 | 35 | public NativeInvocationHandler(long ptr) { 36 | this.ptr = ptr; 37 | } 38 | 39 | public Object invoke(Object proxy, Method method, Object[] args) { 40 | 41 | if ( DEBUG ) { 42 | Logger log = Logger.getLogger(NativeInvocationHandler.class); 43 | log.info("+ java:invoke(, "); 44 | // don't call it, or recursive lookup/proxy will go! 45 | //log.info(proxy); 46 | //log.info(", "); 47 | log.info(method); 48 | log.info(", "); 49 | log.info(args); 50 | log.info(")"); 51 | } 52 | Object ret = invoke0(proxy, method, args); 53 | 54 | if ( DEBUG ) { 55 | Logger log = Logger.getLogger(NativeInvocationHandler.class); 56 | log.info("+ java:invoke returned: "); 57 | log.info(ret); 58 | } 59 | 60 | return ret; 61 | } 62 | 63 | native Object invoke0(Object proxy, Method method, Object[] args); 64 | } -------------------------------------------------------------------------------- /__PySiddhiProxy/src/main/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /__PySiddhiProxy/threadfix_c_code/README.MD: -------------------------------------------------------------------------------- 1 | threadfix is used in Python 3.4+ to treat a threading related bug introduced in Python 3.4. 2 | In Python 3.4+, if a callback is received from a non Python created thread to a Python program, it causes Python Interpreter to fail. 3 | 4 | The threadfix_c_code directory contains source code of Native Java Class io.siddhi.pythonapi.threadfix.PyThreadFix. The above mentioned issue is fixed by the code in method fixThread of Jave Native Class io.siddhi.pythonapi.threadfix.PyThreadFix. The fixthread method should be called prior to sending callback event from Java to Python in order to avoid the mentioned bug. 5 | 6 | The above issue does not affect Windows Operating System. Therefore, threadfix code building is skipped in Windows. -------------------------------------------------------------------------------- /__PySiddhiProxy/threadfix_c_code/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # --------------------------------------------------------------------------- 3 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | echo "Compiling C++ Code used for fixing threading issue" 18 | echo "Invoking G++ Compiler" 19 | 20 | if [["$OSTYPE" == "darwin"*]]; then 21 | g++ -I "$JAVA_HOME/include" -I "$JAVA_HOME/include/darwin" -I "$PYTHONHOME" -shared -flat_namespace -undefined suppress -dynamiclib -o libio_siddhi_pythonapi_threadfix_pythreadfix.so io_siddhi_pythonapi_threadfix_PyThreadFix.c 22 | elif [["$OSTYPE" == "linux-gnu"]]; then 23 | g++ -I "$JAVA_HOME/include" -I "$JAVA_HOME/include/linux" -I "$PYTHONHOME" -shared -fPIC -o libio_siddhi_pythonapi_threadfix_pythreadfix.so io_siddhi_pythonapi_threadfix_PyThreadFix.c 24 | fi 25 | 26 | echo "Copying output library to ../../../../SiddhiCEP4" 27 | cp libio_siddhi_pythonapi_threadfix_pythreadfix.so ../../../libio_siddhi_pythonapi_threadfix_pythreadfix.so 28 | echo "All is well!" 29 | -------------------------------------------------------------------------------- /__PySiddhiProxy/threadfix_c_code/io_siddhi_pythonapi_threadfix_PyThreadFix.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | #include "io_siddhi_pythonapi_threadfix_PyThreadFix.h" 25 | 26 | JNIEXPORT void JNICALL Java_io_siddhi_pythonapi_threadfix_PyThreadFix_fixThread(JNIEnv *env, jobject thisObj) 27 | { 28 | PyGILState_STATE state; 29 | 30 | PyInterpreterState *istate = PyInterpreterState_Head(); 31 | PyThreadState_New(istate); 32 | 33 | state = PyGILState_Ensure(); 34 | PyGILState_Release(state); 35 | 36 | return; 37 | } 38 | -------------------------------------------------------------------------------- /__PySiddhiProxy/threadfix_c_code/io_siddhi_pythonapi_threadfix_PyThreadFix.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | #include 20 | /* Header for class io_siddhi_pythonapi_threadfix_PyThreadFix */ 21 | 22 | #ifndef _Included_io_siddhi_pythonapi_threadfix_PyThreadFix 23 | #define _Included_io_siddhi_pythonapi_threadfix_PyThreadFix 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | /* 28 | * Class: io_siddhi_pythonapi_threadfix_PyThreadFix 29 | * Method: fixThread 30 | * Signature: ()V 31 | */ 32 | JNIEXPORT void JNICALL Java_io_siddhi_pythonapi_threadfix_PyThreadFix_fixThread 33 | (JNIEnv *, jobject); 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | #endif 39 | -------------------------------------------------------------------------------- /__PySiddhiProxy/threadfix_c_code/makefile: -------------------------------------------------------------------------------- 1 | # --------------------------------------------------------------------------- 2 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # use g++ compiler 17 | CC = g++ 18 | 19 | # define JAVA_HOME here 20 | JAVAHOME = ${JAVA_HOME} 21 | 22 | # Please provide the python path according to the python version of the machine 23 | LINUX_PYTHON_PATH = /usr/include/python 24 | 25 | # Please provide the python path according to the python version of the machine 26 | MACOS_PYTHON_PATH = /usr/local/var/homebrew/linked/python/Frameworks/Python.framework/Versions/3.7/include/python3.7m 27 | 28 | OS = ${shell uname} 29 | 30 | CP = cp 31 | 32 | ifeq ($(OS), Darwin) 33 | CFLAGS = -shared -flat_namespace -undefined suppress -dynamiclib 34 | INCLUDES = -I "$(JAVAHOME)/include" -I "$(JAVAHOME)/include/darwin" -I "$(MACOS_PYTHON_PATH)" 35 | OUT_EXT = dylib 36 | else 37 | CFLAGS = -shared -fPIC 38 | INCLUDES = -I "$(JAVAHOME)/include" -I "$(JAVAHOME)/include/linux" -I "$(LINUX_PYTHON_PATH)" 39 | OUT_EXT = so 40 | endif 41 | 42 | # build target details 43 | TARGET_SOURCE_NAME = io_siddhi_pythonapi_threadfix_PyThreadFix 44 | TARGET_OUTPUT_NAME = libio_siddhi_pythonapi_threadfix_pythreadfix 45 | TARGET_INSTALL_NAME = libio_siddhi_pythonapi_threadfix_pythreadfix 46 | TARGET = threadfix 47 | 48 | all: install 49 | 50 | $(TARGET_OUTPUT_NAME).$(OUT_EXT): $(TARGET_SOURCE_NAME).c $(TARGET_SOURCE_NAME).h 51 | @echo "Building Target..." 52 | $(CC) $(CFLAGS) $(INCLUDES) -o $(TARGET_OUTPUT_NAME).$(OUT_EXT) $(TARGET_SOURCE_NAME).c 53 | @echo 54 | 55 | install: $(TARGET_OUTPUT_NAME).$(OUT_EXT) 56 | @echo "Copying Target to Root..." 57 | $(CP) $(TARGET_OUTPUT_NAME).$(OUT_EXT) ../$(TARGET_INSTALL_NAME).$(OUT_EXT) 58 | @echo 59 | 60 | clean: 61 | $(RM) $(TARGET_OUTPUT_NAME).$(OUT_EXT) 62 | -------------------------------------------------------------------------------- /docs/Debugging-Siddhi-Queries.md: -------------------------------------------------------------------------------- 1 | # Debug PySiddhi 2 | 3 | Siddhi Queries can be debugged at run time via PySiddhi. 4 | It suppots following features with its Python APIs. 5 | 6 | * Add Siddhi Debugger Callbacks 7 | * Acquiring and Releasing Breakpoints in Siddhi Queries 8 | * Querying details about Siddhi Query State 9 | * Debugging Multi-threaded Siddhi Apps 10 | 11 | # Using Breakpoints and Siddhi Debugger Callbacks 12 | Using Siddhi Debugger, it is possible to break the query execution on occurrences of designated events (input or output events) and analyze the state of the query. Placing a breakpoint would cause Siddhi Debugger Callback to be triggered whenever a breakpoint is reached. The following code snippet demonstrates a basic usage of Siddhi Debugger. 13 | 14 | ```python 15 | 16 | # Obtain siddhi debugger from Siddhi App Runtime. 17 | siddhiDebugger = siddhiAppRuntime.debug() 18 | 19 | # Place a breakpoint. 20 | siddhiDebugger.acquireBreakPoint("query 1", SiddhiDebugger.QueryTerminal.IN) 21 | 22 | # Setup a callback to receive debug events. 23 | class SiddhiDebuggerCallbackImpl(SiddhiDebuggerCallback): 24 | def debugEvent(self, event, queryName,queryTerminal, debugger): 25 | logging.info("Query: " + queryName + ":" + queryTerminal.name) 26 | logging.info(event) 27 | 28 | # Do assertions on event and check for special cases. 29 | 30 | # Obtain next debuggable element of breakpoint. 31 | # Alternatively can call debugger.play() to ignore pending 32 | # debuggable elements and continue from breakpoint. 33 | debugger.next() 34 | 35 | # Assign the debugger callback 36 | siddhiDebugger.setDebuggerCallback(SiddhiDebuggerCallbackImpl()) 37 | 38 | # Send test inputs using inputHandler 39 | inputHandler.send(["WSO2", 50.0, 60]) 40 | inputHandler.send(["WSO2", 70.0, 40]) 41 | ``` 42 | 43 | For the complete code on above example and many other examples refer [Siddhi Debugger Tests](https://github.com/siddhi-io/PySiddhi/blob/master/Tests/SiddhiCoreTests/TestDebugger.py). -------------------------------------------------------------------------------- /docs/Installation-Guide.md: -------------------------------------------------------------------------------- 1 | # Installation Guide 2 | 3 | The current version is tested with Microsoft Windows and Unix/Linux based operating systems. 4 | PySiddhi can be installed using one of the following methods. 5 | 6 | ## Install PySiddhi 7 | 8 | ### Prerequisites 9 | 10 | - The following dependencies should be installed prior to installation of library. 11 | 12 | **Linux** 13 | 14 | - Python 2.7 or 3.x 15 | - Cython
`sudo pip install cython` 16 | - Python Developer Package
`sudo apt-get install python-dev python3-dev python-dev` 17 | - Oracle Java 8 and set JAVA_HOME path 18 | - libboost for Python _(Only to build from Source)_
`sudo apt-get install libboost-python-dev` 19 | - Maven _(Only to build from Source)_ 20 | - g++ and other development tools _(Only to build from Source)_
21 | `sudo apt-get install build-essential g++ autotools-dev libicu-dev build-essential libbz2-dev libboost-all-dev` 22 | 23 | **macOS** 24 | 25 | - Install brew 26 | - Install python using brew 27 | - Cython
`sudo pip install cython` 28 | - Oracle Java 8 and set JAVA_HOME path 29 | - boost for python _(Only to build from Source)_
`brew install boost` 30 | - Maven _(Only to build from Source)_ 31 | 32 | **Windows** 33 | 34 | - Install Python 35 | - Cython
`sudo pip install cython` 36 | - Oracle Java 8 and set JAVA_HOME path 37 | - Install Visual Studio Build tools _(Only to build from Source)_ 38 | - Maven _(Only to build from Source)_ 39 | 40 | - Download siddhi-sdk release from [here](https://github.com/siddhi-io/siddhi-sdk/releases) and set the SIDDHISDK_HOME as an environment variable.
`export SIDDHISDK_HOME=""` 41 | - Download siddhi-python-api-proxy-5.1.0.jar from [here](https://github.com/siddhi-io/PySiddhi/releases) and copy to `/lib` directory 42 | 43 | ### Install PySiddhi via Python Package Management 44 | 45 | PySiddhi can be installed via PIP command as bellow. 46 | 47 | ``` 48 | pip install pysiddhi 49 | ``` 50 | 51 | ### Install PySiddhi from Online Code 52 | 53 | Using the following PIP command, PySiddhi can be directly installed from online code available in GitHub. 54 | ``` 55 | pip install git+https://github.com/siddhi-io/PySiddhi.git 56 | ``` 57 | *Note: In case of permission errors, use `sudo`* 58 | 59 | ### Install from Downloaded Code 60 | Switch to the branch `master` of PySiddhi. 61 | Navigate to source code root directory and execute the following PIP command. 62 | 63 | ``` 64 | pip install . 65 | ``` 66 | *Note the period (.) at end of command. In case of permission errors, use `sudo`* 67 | 68 | ## Uninstall PySiddhi 69 | If the library has been installed as explained above, it could be uninstalled using the following pip command. 70 | ``` 71 | pip uninstall pysiddhi 72 | ``` 73 | -------------------------------------------------------------------------------- /docs/Run-PySiddhi.md: -------------------------------------------------------------------------------- 1 | # Run PySiddhi 2 | 3 | The following is a sample demonstrating how to rung PySiddhi. 4 | 5 | ## Sample 6 | 7 | This sample demonstrating how to write a streaming query to detect stock records having volume less than 150. 8 | This code uses Siddhi 5.0 queries with PySiddhi. 9 | 10 | ```python 11 | from PySiddhi.DataTypes.LongType import LongType 12 | from PySiddhi.core.SiddhiManager import SiddhiManager 13 | from PySiddhi.core.query.output.callback.QueryCallback import QueryCallback 14 | from PySiddhi.core.util.EventPrinter import PrintEvent 15 | from time import sleep 16 | 17 | siddhiManager = SiddhiManager() 18 | # Siddhi Query to filter events with volume less than 150 as output 19 | siddhiApp = "define stream cseEventStream (symbol string, price float, volume long); " + \ 20 | "@info(name = 'query1') from cseEventStream[volume < 150] select symbol,price insert into outputStream;" 21 | 22 | # Generate runtime 23 | siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(siddhiApp) 24 | 25 | # Add listener to capture output events 26 | class QueryCallbackImpl(QueryCallback): 27 | def receive(self, timestamp, inEvents, outEvents): 28 | PrintEvent(timestamp, inEvents, outEvents) 29 | siddhiAppRuntime.addCallback("query1",QueryCallbackImpl()) 30 | 31 | # Retrieving input handler to push events into Siddhi 32 | inputHandler = siddhiAppRuntime.getInputHandler("cseEventStream") 33 | 34 | # Starting event processing 35 | siddhiAppRuntime.start() 36 | 37 | # Sending events to Siddhi 38 | inputHandler.send(["IBM",700.0,LongType(100)]) 39 | inputHandler.send(["WSO2", 60.5, LongType(200)]) 40 | inputHandler.send(["GOOG", 50, LongType(30)]) 41 | inputHandler.send(["IBM", 76.6, LongType(400)]) 42 | inputHandler.send(["WSO2", 45.6, LongType(50)]) 43 | 44 | # Wait for response 45 | sleep(10) 46 | 47 | siddhiManager.shutdown() 48 | 49 | ``` 50 | 51 | ## Explanation 52 | 53 | Above example is comprehensively described bellow: 54 | 55 | **Initialize libraries and imports** 56 | 57 | Add [this file](https://github.com/siddhi-io/PySiddhi/blob/master/log4j.xml) to working directory in order to enable log4j 58 | logging. Log4j is used by PrintEvent to generate output. 59 | 60 | ```python 61 | from PySiddhi.DataTypes.LongType import LongType 62 | from PySiddhi.core.SiddhiManager import SiddhiManager 63 | from PySiddhi.core.query.output.callback.QueryCallback import QueryCallback 64 | from PySiddhi.core.util.EventPrinter import PrintEvent 65 | from time import sleep 66 | ``` 67 | 68 | **Define filter using Siddhi query** 69 | 70 | ```python 71 | siddhiManager = SiddhiManager() 72 | # Siddhi Query to filter events with volume less than 150 as output 73 | siddhiApp = "define stream cseEventStream (symbol string, price float, volume long); " + \ 74 | "@info(name = 'query1') from cseEventStream[volume < 150] select symbol,price insert into outputStream;" 75 | 76 | # Generate runtime 77 | siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(siddhiApp) 78 | ``` 79 | For more details on Siddhi Query Language, refer [Siddhi Query Language Guide](https://siddhi-io.github.io/siddhi/documentation/siddhi-4.0/). 80 | 81 | **Define a listener for filtered events** 82 | 83 | ```python 84 | # Add listener to capture output events 85 | class QueryCallbackImpl(QueryCallback): 86 | def receive(self, timestamp, inEvents, outEvents): 87 | PrintEvent(timestamp, inEvents, outEvents) 88 | siddhiAppRuntime.addCallback("query1",QueryCallbackImpl()) 89 | ``` 90 | **Test filter using sample input events** 91 | 92 | ```python 93 | # Retrieving input handler to push events into Siddhi 94 | inputHandler = siddhiAppRuntime.getInputHandler("cseEventStream") 95 | 96 | # Starting event processing 97 | siddhiAppRuntime.start() 98 | 99 | # Sending events to Siddhi 100 | inputHandler.send(["IBM",700.0,LongType(100)]) 101 | inputHandler.send(["WSO2", 60.5, LongType(200)]) 102 | inputHandler.send(["GOOG", 50, LongType(30)]) 103 | inputHandler.send(["IBM", 76.6, LongType(400)]) 104 | inputHandler.send(["WSO2", 45.6, LongType(50)]) 105 | 106 | # Wait for response 107 | sleep(0.1) 108 | ``` 109 | **Shutdown the Siddhi Manager when processing is done** 110 | ``` 111 | siddhiManager.shutdown() 112 | ``` 113 | 114 | ## Expected Output 115 | 116 | The 3 events with volume less than 150 are printed in log. 117 | 118 | ```log 119 | INFO EventPrinter - Events{ @timestamp = 1497708406678, inEvents = [Event{timestamp=1497708406678, id=-1, data=[IBM, 700.0], isExpired=false}], RemoveEvents = null } 120 | INFO EventPrinter - Events{ @timestamp = 1497708406685, inEvents = [Event{timestamp=1497708406685, id=-1, data=[GOOG, 50], isExpired=false}], RemoveEvents = null } 121 | INFO EventPrinter - Events{ @timestamp = 1497708406687, inEvents = [Event{timestamp=1497708406687, id=-1, data=[WSO2, 45.6], isExpired=false}], RemoveEvents = null } 122 | ``` 123 | -------------------------------------------------------------------------------- /docs/Using-Siddhi-from-Python.md: -------------------------------------------------------------------------------- 1 | # Advanced Concepts of PySiddhi 2 | 3 | ## Key Points 4 | The PySiddhi API is a wrapper on Siddhi Java Library, exposing it's core features to Python. It is important to keep 5 | following points in mind when using PySiddhi API. 6 | 7 | * __It is a wrapper. Not a port.__ - Whenever you use the PySiddhi API, the [Siddhi Java Library](https://github.com/siddhi-io/siddhi) is loaded in background using Java Virtual Machine. 8 | * __The wrapper is focused on functionality provided by [siddhi-core](https://github.com/siddhi-io/siddhi/tree/master/modules/siddhi-core/src/main/java/io/siddhi/core)__ which is found in package `io.siddhi.core`. The future versions of API may have the ability to load Siddhi Extensions directly from Java Packages and use them in Siddhi Queries. However, the individual Java classes of extensions will not be wrapped. 9 | * __Only the classes that are required for API users are wrapped.__ Classes which are designed to be used by Siddhi Java Library for its internal work will not be wrapped. 10 | * __Python doesn't differentiate _Integer_ from _Long_. But Siddhi do.__ Python 3 does not differentiate _Integer_ and _Long_ Data Types. All Python _Integers_ fed into Siddhi (via _InputHandler_) are converted into Java _Integers_. To feed Java _Long_ to Siddhi (via _InputHandler_), use _[DataTypes.LongType](https://github.com/siddhi-io/PySiddhi/blob/master/PySiddhi/DataTypes/LongType.py)_. All _Long_ outputs received from Siddhi (via callbacks) will also be converted to _DataTypes.LongType_. 11 | - Example: `inputHandler.send(["IBM",700.0,LongType(100)])` 12 | * __Clean up everything when you are done.__ Remember to call *shutdown* of *SiddhiManager* and *SiddhiAppRuntime*. 13 | 14 | # Java Siddhi to PySiddhi Mappings 15 | 16 | The PySiddhi wrapper is focused on functionality provided by [siddhi-core](https://github.com/siddhi-io/siddhi/tree/master/modules/siddhi-core/src/main/java/io/siddhi/core). 17 | The classes in Java package `io.siddhi.core` are mapped to `PySiddhi.core` using hand written logic. These are not an auto-generated. 18 | The follow table demonstrates major mappings of PySiddhi. 19 | 20 | | Java Class | Python Import | 21 | | ------------- |---------------------| 22 | | [io.siddhi.core.SiddhiManager](https://github.com/siddhi-io/siddhi/tree/master/modules/siddhi-core/src/main/java/io/siddhi/core/SiddhiManager.java) | ```from PySiddhi.core.SiddhiManager import SiddhiManager```| 23 | | [io.siddhi.core.ExecutionPlanRuntime](https://github.com/siddhi-io/siddhi/tree/master/modules/siddhi-core/src/main/java/io/siddhi/core/SiddhiAppRuntime.java) | ```from PySiddhi.core.SiddhiAppRuntime import SiddhiAppRuntime```| 24 | | [io.siddhi.core.event.Event](https://github.com/siddhi-io/siddhi/blob/master/modules/siddhi-core/src/main/java/io/siddhi/core/event/Event.java)| ```from PySiddhi.core.event.Event import Event```| 25 | | [io.siddhi.core.event.ComplexEvent](https://github.com/siddhi-io/siddhi/blob/master/modules/siddhi-core/src/main/java/io/siddhi/core/event/ComplexEvent.java)| ```from PySiddhi.core.event.ComplexEvent import ComplexEvent```| 26 | | [io.siddhi.core.stream.input.InputHandler](https://github.com/siddhi-io/siddhi/tree/master/modules/siddhi-core/src/main/java/io/siddhi/core/stream/input/InputHandler.java) | ```from PySiddhi.core.stream.input.InputHandler import InputHandler``` | 27 | | [io.siddhi.core.stream.output.StreamCallback](https://github.com/siddhi-io/siddhi/tree/master/modules/siddhi-core/src/main/java/io/siddhi/core/stream/output/StreamCallback.java) | ```from PySiddhi.core.stream.output.StreamCallback import StreamCallback```| 28 | |[io.siddhi.core.query.output.callback.QueryCallback](https://github.com/siddhi-io/siddhi/tree/master/modules/siddhi-core/src/main/java/io/siddhi/core/query/output/callback/QueryCallback.java)| ```from PySiddhi.core.query.output.callback.QueryCallback import QueryCallback``` | 29 | |[io.siddhi.core.debugger.SiddhiDebugger](https://github.com/siddhi-io/siddhi/blob/master/modules/siddhi-core/src/main/java/io/siddhi/core/debugger/SiddhiDebugger.java)|```from PySiddhi.core.debugger.SiddhiDebugger import SiddhiDebugger```| 30 | |[io.siddhi.core.debugger.SiddhiDebuggerCallback](https://github.com/siddhi-io/siddhi/blob/master/modules/siddhi-core/src/main/java/io/siddhi/core/debugger/SiddhiDebuggerCallback.java) | ```from PySiddhi-3.core.debugger.SiddhiDebuggerCallback import SiddhiDebuggerCallback``` | 31 | |[io.siddhi.core.util.EventPrinter](https://github.com/siddhi-io/siddhi/tree/master/modules/siddhi-core/src/main/java/io/siddhi/core/util/EventPrinter.java) | ```import PySiddhi.core.util.EventPrinter```| -------------------------------------------------------------------------------- /docs/assets/javascripts/extra.js: -------------------------------------------------------------------------------- 1 | /* 2 | ~ Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved. 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | */ 16 | 17 | var logo = document.querySelector('.md-logo'); 18 | var logoTitle = logo.title; 19 | logo.setAttribute('href', 'https://siddhi.io/') 20 | 21 | var header = document.querySelector('.md-header-nav__title'); 22 | var headerContent = document.querySelectorAll('.md-header-nav__title span')[1].textContent; 23 | var url = document.querySelector('.md-nav__item a.md-nav__link').href 24 | header.innerHTML = '' + logoTitle + '' + 25 | '' + headerContent + '' 26 | 27 | 28 | /* 29 | * TOC position highlight on scroll 30 | */ 31 | 32 | var observeeList = document.querySelectorAll(".md-sidebar__inner > .md-nav--secondary .md-nav__link"); 33 | var listElems = document.querySelectorAll(".md-sidebar__inner > .md-nav--secondary > ul li"); 34 | var config = {attributes: true, childList: true, subtree: true}; 35 | 36 | var callback = function (mutationsList, observer) { 37 | for (var mutation of mutationsList) { 38 | if (mutation.type == 'attributes') { 39 | mutation.target.parentNode.setAttribute(mutation.attributeName, 40 | mutation.target.getAttribute(mutation.attributeName)); 41 | scrollerPosition(mutation); 42 | } 43 | } 44 | }; 45 | var observer = new MutationObserver(callback); 46 | 47 | listElems[0].classList.add('active'); 48 | 49 | for (var i = 0; i < observeeList.length; i++) { 50 | var el = observeeList[i]; 51 | 52 | observer.observe(el, config); 53 | 54 | el.onclick = function (e) { 55 | listElems.forEach(function (elm) { 56 | if (elm.classList) { 57 | elm.classList.remove('active'); 58 | } 59 | }); 60 | 61 | e.target.parentNode.classList.add('active'); 62 | } 63 | } 64 | 65 | function scrollerPosition(mutation) { 66 | var blurList = document.querySelectorAll(".md-sidebar__inner > .md-nav--secondary > ul li > .md-nav__link[data-md-state='blur']"); 67 | 68 | listElems.forEach(function (el) { 69 | if (el.classList) { 70 | el.classList.remove('active'); 71 | } 72 | }); 73 | 74 | if (blurList.length > 0) { 75 | if (mutation.target.getAttribute('data-md-state') === 'blur') { 76 | if (mutation.target.parentNode.querySelector('ul li')) { 77 | mutation.target.parentNode.querySelector('ul li').classList.add('active'); 78 | } else { 79 | setActive(mutation.target.parentNode); 80 | } 81 | } else { 82 | mutation.target.parentNode.classList.add('active'); 83 | } 84 | } else { 85 | if (listElems.length > 0) { 86 | listElems[0].classList.add('active'); 87 | } 88 | } 89 | } 90 | 91 | function setActive(parentNode, i) { 92 | i = i || 0; 93 | if (i === 5) { 94 | return; 95 | } 96 | if (parentNode.nextElementSibling) { 97 | parentNode.nextElementSibling.classList.add('active'); 98 | return; 99 | } 100 | setActive(parentNode.parentNode.parentNode.parentNode, ++i); 101 | } 102 | -------------------------------------------------------------------------------- /docs/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siddhi-io/PySiddhi/d58af41d243307f8f5bb27077467fa69866117fe/docs/images/favicon.ico -------------------------------------------------------------------------------- /docs/images/siddhi-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 47 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # PySiddhi 2 | 3 | ***PySiddhi*** is a Python wrapper for [Siddhi](https://siddhi-io.github.io/siddhi/). Which can listens to events from data streams, detects complex conditions 4 | described via a ***Streaming SQL language***, and triggers actions. It performs both ***Stream Processing*** and 5 | ***Complex Event Processing*** on streaming data. Its Siddhi core is written in Java library. 6 | 7 | - PySiddhi wraps [Siddhi 5](https://siddhi-io.github.io/siddhi/) 8 | 9 | ## Content 10 | 11 | * Introduction and Quick Demo (this page) 12 | * [Installation Guide](Installation-Guide.md) 13 | * [Run PySiddhi](Run-PySiddhi.md) 14 | * [Debug PySiddhi](Debugging-Siddhi-Queries.md) 15 | * [Advanced Concepts of PySiddhi](Using-Siddhi-from-Python.md) 16 | 17 | ## Features 18 | 19 | - [x] Basic functionality of Siddhi 5.x.x 20 | - [x] Siddhi Debugger 21 | - [x] Support to Siddhi Extensions Loading 22 | 23 | ## Installation 24 | 25 | PySiddhi can be installed using pip. 26 | 27 | ``` 28 | pip install pysiddhi 29 | ``` 30 | 31 | For detail insulation and prerequisite refer section on [Installation Guide](Installation-Guide). 32 | 33 | ## Quick Demo 34 | Following is a quick demo of how to use PySiddhi. For comprehensive demo please refer [Quick-Demo-PySiddhi](Run-PySiddhi.md) 35 | 36 | **Step 1** - Define filter using Siddhi Query. 37 | 38 | ```python 39 | siddhiManager = SiddhiManager() 40 | # Siddhi Query to filter events with volume less than 150 as output 41 | siddhiApp = "define stream cseEventStream (symbol string, price float, volume long);" + \ 42 | "@info(name = 'query1') " + \ 43 | "from cseEventStream[volume < 150] " + \ 44 | "select symbol, price " + \ 45 | "insert into outputStream;" 46 | 47 | # Generate runtime 48 | siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(siddhiApp) 49 | ``` 50 | For more details on Siddhi Query Language, refer [Siddhi Query Language Guide](https://siddhi-io.github.io/siddhi/). 51 | 52 | **Step 2** - Define a listener for filtered events. 53 | 54 | ```python 55 | # Add listener to capture output events 56 | class QueryCallbackImpl(QueryCallback): 57 | def receive(self, timestamp, inEvents, outEvents): 58 | PrintEvent(timestamp, inEvents, outEvents) 59 | siddhiAppRuntime.addCallback("query1",QueryCallbackImpl()) 60 | ``` 61 | **Step 3** - Test filter query using sample input events. 62 | 63 | ```python 64 | # Retrieving input handler to push events into Siddhi 65 | inputHandler = siddhiAppRuntime.getInputHandler("cseEventStream") 66 | 67 | # Starting event processing 68 | siddhiAppRuntime.start() 69 | 70 | # Sending events to Siddhi 71 | inputHandler.send(["IBM",700.0,LongType(100)]) 72 | inputHandler.send(["WSO2", 60.5, LongType(200)]) 73 | inputHandler.send(["GOOG", 50, LongType(30)]) 74 | inputHandler.send(["IBM", 76.6, LongType(400)]) 75 | inputHandler.send(["WSO2", 45.6, LongType(50)]) 76 | 77 | # Wait for response 78 | sleep(0.1) 79 | ``` 80 | **Output** 81 | 82 | The 3 events with volume less than 150 are printed in log. 83 | 84 | ```log 85 | INFO EventPrinter - Events{ @timestamp = 1497708406678, inEvents = [Event{timestamp=1497708406678, id=-1, data=[IBM, 700.0], isExpired=false}], RemoveEvents = null } 86 | INFO EventPrinter - Events{ @timestamp = 1497708406685, inEvents = [Event{timestamp=1497708406685, id=-1, data=[GOOG, 50], isExpired=false}], RemoveEvents = null } 87 | INFO EventPrinter - Events{ @timestamp = 1497708406687, inEvents = [Event{timestamp=1497708406687, id=-1, data=[WSO2, 45.6], isExpired=false}], RemoveEvents = null } 88 | ``` 89 | 90 | **Clean Up** - Remember to shutdown the Siddhi Manager when your done. 91 | 92 | ```python 93 | siddhiManager.shutdown() 94 | ``` 95 | 96 | ## Contribution 97 | 98 | _PySiddhi is initiated by a project for Google Summer of Code 2017 Program._ 99 | 100 | Contributed by: __Madhawa Vidanapathirana__
101 | Email: madhawavidanapathirana@gmail.com
102 | Organization: University of Moratuwa, Sri Lanka. 103 | 104 | ## Support and Contribution 105 | 106 | * We encourage users to ask questions and get support via StackOverflow, make sure to add the `siddhi` tag to the issue for better response. 107 | 108 | * If you find any issues related to the extension please report them on the issue tracker. 109 | 110 | * For production support and other contribution related information refer Siddhi Community documentation. 111 | 112 | -------------------------------------------------------------------------------- /issue_template.md: -------------------------------------------------------------------------------- 1 | **Description:** 2 | 3 | 4 | **Suggested Labels:** 5 | 6 | 7 | **Suggested Assignees:** 8 | 9 | 10 | **Affected Product Version:** 11 | 12 | **OS, DB, other environment details and versions:** 13 | 14 | **Steps to reproduce:** 15 | 16 | 17 | **Related Issues:** 18 | -------------------------------------------------------------------------------- /log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: PySiddhi 2 | site_description: Python Stream Processing and Complex Event Processing Engine 3 | repo_name: PySiddhi 4 | repo_url: https://github.com/siddhi-io/PySiddhi/ 5 | edit_uri: https://github.com/siddhi-io/PySiddhi/blob/master/ 6 | copyright: Siddhi - Documentation 7 | theme: 8 | name: material 9 | logo: images/siddhi-logo.svg 10 | favicon: images/favicon.ico 11 | palette: 12 | primary: teal 13 | accent: teal 14 | extra_css: 15 | - assets/stylesheets/extra.css 16 | extra_javascript: 17 | - assets/javascripts/extra.js 18 | extra: 19 | social: 20 | - type: github 21 | link: https://github.com/siddhi-io/siddhi 22 | - type: medium 23 | link: https://medium.com/siddhi-io 24 | - type: twitter 25 | link: https://twitter.com/siddhi_io 26 | - type: linkedin 27 | link: https://www.linkedin.com/groups/13553064 28 | google_analytics: 29 | - UA-103065-28 30 | - auto 31 | markdown_extensions: 32 | - markdown.extensions.admonition 33 | pages: 34 | - Information: index.md 35 | - Installation Guide: Installation-Guide.md 36 | - Run PySiddhi: Run-PySiddhi.md 37 | - Debug PySiddhi: Debugging-Siddhi-Queries.md 38 | - Advanced Concepts: Using-Siddhi-from-Python.md 39 | - License: license.md 40 | 41 | -------------------------------------------------------------------------------- /pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Purpose 2 | > Describe the problems, issues, or needs driving this feature/fix and include links to related issues in the following format: Resolves issue1, issue2, etc. 3 | 4 | ## Goals 5 | > Describe the solutions that this feature/fix will introduce to resolve the problems described above 6 | 7 | ## Approach 8 | > Describe how you are implementing the solutions. Include an animated GIF or screenshot if the change affects the UI (email documentation@wso2.com to review all UI text). Include a link to a Markdown file or Google doc if the feature write-up is too long to paste here. 9 | 10 | ## User stories 11 | > Summary of user stories addressed by this change> 12 | 13 | ## Release note 14 | > Brief description of the new feature or bug fix as it will appear in the release notes 15 | 16 | ## Documentation 17 | > Link(s) to product documentation that addresses the changes of this PR. If no doc impact, enter “N/A” plus brief explanation of why there’s no doc impact 18 | 19 | ## Training 20 | > Link to the PR for changes to the training content in https://github.com/wso2/WSO2-Training, if applicable 21 | 22 | ## Certification 23 | > Type “Sent” when you have provided new/updated certification questions, plus four answers for each question (correct answer highlighted in bold), based on this change. Certification questions/answers should be sent to certification@wso2.com and NOT pasted in this PR. If there is no impact on certification exams, type “N/A” and explain why. 24 | 25 | ## Marketing 26 | > Link to drafts of marketing content that will describe and promote this feature, including product page changes, technical articles, blog posts, videos, etc., if applicable 27 | 28 | ## Automation tests 29 | - Unit tests 30 | > Code coverage information 31 | - Integration tests 32 | > Details about the test cases and coverage 33 | 34 | ## Security checks 35 | - Followed secure coding standards in http://wso2.com/technical-reports/wso2-secure-engineering-guidelines? yes/no 36 | - Ran FindSecurityBugs plugin and verified report? yes/no 37 | - Confirmed that this PR doesn't commit any keys, passwords, tokens, usernames, or other secrets? yes/no 38 | 39 | ## Samples 40 | > Provide high-level details about the samples related to this feature 41 | 42 | ## Related PRs 43 | > List any other related PRs 44 | 45 | ## Migrations (if applicable) 46 | > Describe migration steps and platforms on which migration has been tested 47 | 48 | ## Test environment 49 | > List all JDK versions, operating systems, databases, and browser/versions on which this feature/fix was tested 50 | 51 | ## Learning 52 | > Describe the research phase and any blog posts, patterns, libraries, or add-ons you used to solve the problem. -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | python-tag = py2.py3 -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 2 | # 3 | # WSO2 Inc. licenses this file to you under the Apache License, 4 | # Version 2.0 (the "License"); you may not use this file except 5 | # in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | # KIND, either express or implied. See the License for the 14 | # specific language governing permissions and limitations 15 | # under the License. 16 | 17 | import os 18 | from subprocess import check_call 19 | from setuptools import setup, find_packages 20 | from setuptools.command.install import install 21 | 22 | 23 | class PostInstallCommand(install): 24 | """Post-installation for installation mode.""" 25 | 26 | def run(self): 27 | # Compile JAVA Code here 28 | if os.name == "nt": 29 | check_call("mvn clean install".split(), cwd="__PySiddhiProxy", 30 | shell=True) # shell=True is necessary for windows 31 | else: 32 | check_call("mvn clean install".split(), cwd="__PySiddhiProxy") # shell=True should be skipped for linux 33 | 34 | install.run(self) 35 | 36 | 37 | packages = find_packages() 38 | filtered_packages = [] 39 | for package in packages: 40 | if package.startswith("Tests"): 41 | continue 42 | filtered_packages.append(package) 43 | 44 | setup( 45 | name="PySiddhi", 46 | version="5.1.0", 47 | packages=filtered_packages, 48 | python_requires='>=2.7, >=3.6', 49 | install_requires=["requests","pyjnius", "future", "enum34 ; python_version<'4'"], 50 | package_data={ 51 | "PySiddhi": ["../__PySiddhiProxy/target/lib/*.jar", 52 | "../__PySiddhiProxy/target/*.jar", 53 | "../__PySiddhiProxy/*.so", 54 | "../__PySiddhiProxy/*.dylib"] 55 | }, 56 | 57 | # metadata for upload to PyPI 58 | author="WSO2", 59 | author_email="dev@wso2.org", 60 | description="Python wrapper for `Siddhi 5.x.x`.", 61 | license="Apache2", 62 | cmdclass={ 63 | 'install': PostInstallCommand, 64 | }, 65 | url="https://github.com/siddhi-io/PySiddhi", 66 | classifiers=[ 67 | 'Development Status :: 5 - Production/Stable', 68 | 'Intended Audience :: Developers', 69 | 'License :: OSI Approved :: Apache Software License', 70 | 'Natural Language :: English', 71 | 'Operating System :: Microsoft :: Windows', 72 | 'Operating System :: POSIX :: Linux', 73 | 'Operating System :: MacOS', 74 | 'Programming Language :: Python :: 2.7', 75 | 'Programming Language :: Python :: 3.3', 76 | 'Programming Language :: Python :: 3.4', 77 | 'Programming Language :: Python :: 3.5', 78 | 'Programming Language :: Python :: 3.6', 79 | 'Programming Language :: Python :: 3.7', 80 | 'Topic :: Software Development :: Libraries :: Java Libraries' 81 | ] 82 | ) 83 | --------------------------------------------------------------------------------