[STREAMPIPES-174] add demo processor in python
diff --git a/.idea/runConfigurations/processor_python.xml b/.idea/runConfigurations/processor_python.xml
new file mode 100644
index 0000000..305a93d
--- /dev/null
+++ b/.idea/runConfigurations/processor_python.xml
@@ -0,0 +1,21 @@
+<component name="ProjectRunConfigurationManager">
+ <configuration default="false" name="processor-python" type="Application" factoryName="Application">
+ <envs>
+ <env name="SP_DEBUG" value="true" />
+ <env name="SP_HOST" value="host.docker.internal" />
+ <env name="SP_PORT" value="8005" />
+ <env name="SP_PYTHON_ENDPOINT" value="localhost:5000" />
+ </envs>
+ <option name="MAIN_CLASS_NAME" value="org.apache.streampipes.processors.python.PythonProcessorInit" />
+ <module name="streampipes-processors-all-python" />
+ <extension name="coverage">
+ <pattern>
+ <option name="PATTERN" value="org.apache.streampipes.processors.python.*" />
+ <option name="ENABLED" value="true" />
+ </pattern>
+ </extension>
+ <method v="2">
+ <option name="Make" enabled="true" />
+ </method>
+ </configuration>
+</component>
\ No newline at end of file
diff --git a/.idea/runConfigurations/processor_python_main.xml b/.idea/runConfigurations/processor_python_main.xml
new file mode 100644
index 0000000..396a623
--- /dev/null
+++ b/.idea/runConfigurations/processor_python_main.xml
@@ -0,0 +1,28 @@
+<component name="ProjectRunConfigurationManager">
+ <configuration default="false" name="processor-python-main" type="PythonConfigurationType" factoryName="Python">
+ <module name="streampipes-processors-all-python" />
+ <option name="INTERPRETER_OPTIONS" value="" />
+ <option name="PARENT_ENVS" value="true" />
+ <envs>
+ <env name="PYTHONUNBUFFERED" value="1" />
+ <env name="SP_HOST" value="host.docker.internal" />
+ <env name="SP_PORT" value="5000" />
+ <env name="SP_DEBUG" value="true" />
+ <env name="SP_SERVICE_NAME" value="Python Processor" />
+ </envs>
+ <option name="SDK_HOME" value="$USER_HOME$/.virtualenvs/incubator-streampipes-extensions/bin/python" />
+ <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/streampipes-processors-all-python/python" />
+ <option name="IS_MODULE_SDK" value="true" />
+ <option name="ADD_CONTENT_ROOTS" value="true" />
+ <option name="ADD_SOURCE_ROOTS" value="true" />
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
+ <option name="SCRIPT_NAME" value="$PROJECT_DIR$/streampipes-processors-all-python/python/main.py" />
+ <option name="PARAMETERS" value="" />
+ <option name="SHOW_COMMAND_LINE" value="false" />
+ <option name="EMULATE_TERMINAL" value="false" />
+ <option name="MODULE_MODE" value="false" />
+ <option name="REDIRECT_INPUT" value="false" />
+ <option name="INPUT_FILE" value="" />
+ <method v="2" />
+ </configuration>
+</component>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 10a767b..8f1e772 100644
--- a/pom.xml
+++ b/pom.xml
@@ -59,6 +59,7 @@
<module>streampipes-pipeline-elements-all-flink</module>
<module>streampipes-processors-change-detection-jvm</module>
<module>streampipes-extensions-all-jvm</module>
+ <module>streampipes-processors-all-python</module>
</modules>
<properties>
diff --git a/streampipes-processors-all-python/Dockerfile b/streampipes-processors-all-python/Dockerfile
new file mode 100644
index 0000000..9b9b1ce
--- /dev/null
+++ b/streampipes-processors-all-python/Dockerfile
@@ -0,0 +1,52 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#---------------------------------------------------------------------------------------------------------
+# Stage 1: Python build
+#---------------------------------------------------------------------------------------------------------
+FROM python:3.7-slim-buster AS python-build
+RUN mkdir -p /svc/python
+COPY ./python /svc/python
+WORKDIR /svc/python
+RUN pip install --upgrade pip; \
+ pip install /svc/python/dist/apache_streampipes_python-0.68.0.dev1-py3-none-any.whl; \
+ pip install --no-cache-dir --compile -r /svc/python/requirements.txt
+
+#---------------------------------------------------------------------------------------------------------
+# Stage 2: Final image
+#---------------------------------------------------------------------------------------------------------
+FROM fogsyio/openjdk8-openj9-python:3.7-slim-buster
+
+EXPOSE 8090
+ENV CONSUL_LOCATION=consul
+
+RUN set -eux; \
+ \
+ apt-get update; \
+ apt-get install -y --no-install-recommends supervisor; \
+ \
+ apt-get clean; \
+ rm -rf /var/lib/apt/lists/*
+
+COPY supervisor.conf /etc/supervisor.conf
+
+# Copy from build stages
+COPY ./target /svc/java
+COPY --from=python-build /svc/python /svc/python
+COPY --from=python-build /usr/local/lib/python3.7/site-packages /usr/local/lib/python3.7/site-packages
+
+WORKDIR /svc
+
+CMD ["supervisord", "-c", "/etc/supervisor.conf"]
diff --git a/streampipes-processors-all-python/README.md b/streampipes-processors-all-python/README.md
new file mode 100644
index 0000000..05a421c
--- /dev/null
+++ b/streampipes-processors-all-python/README.md
@@ -0,0 +1,68 @@
+## [WIP] StreamPipes Data Processor in Python
+
+This module is currently under development:
+* [STREAMPIPES-174: New Python Wrapper](https://issues.apache.org/jira/projects/STREAMPIPES/issues/STREAMPIPES-174?filter=allopenissues)
+
+## Setup
+Clone core repository
+````bash
+git clone https://github.com/apache/incubator-streampipes
+````
+Build StreamPipes python wheel in `streampipes-python-wrapper` in core repository
+```bash
+cd incubator-streampipes/streampipes-wrapper-python
+./build-distribution
+```
+Copy wheel to `python/dist` directory
+```bash
+cp /path/to/incubator-streampipes/streampipes-wrapper-python/dist/apache_streampipes_python-0.68.0.dev1-py3-none-any.whl
+ ./python/dist
+```
+>**NOTE**: We recommend creating a virtualenv before installing the packages.
+
+Install StreamPipes python wheel
+```bash
+pip install ./python/dist/apache_streampipes_python-0.68.0.dev1-py3-none-any.whl
+```
+
+## Development
+Currently, we rely on Java as an interface to the backend, where we declare the `DataProcessorDescription` model and
+ in turn receive a `DataProcessorInvokation` upon pipeline start from the backend. Requests are then further routet
+ via `HTTP` requests to the Python-side in order to start/stop dedicated processors.
+
+Thus, start the Java main class `PythonProcessorInit.java` with the following environment variables:
+```bash
+SP_DEBUG=true
+SP_HOST=host.docker.internal
+SP_PORT=8005
+SP_PYTHON_ENDPOINT=localhost:5000
+```
+Then start the python `main.py` with the following environment variables:
+```bash
+PYTHONUNBUFFERED=1
+SP_HOST=host.docker.internal
+SP_PORT=5000
+SP_DEBUG=true
+SP_SERVICE_NAME=Python Processor
+```
+
+## Build Docker image
+Maven package from root
+````bash
+# root folder
+mvn clean package
+````
+Build Docker image
+````bash
+docker build -t apachestreampipes/processors-python:0.68.0-SNAPSHOT .
+````
+
+Run Docker container
+>*NOTE*: make sure that you have StreamPipes core services (backend etc) including consul up and running
+```bash
+docker run -ti \
+ --rm \
+ --net=spnet \
+ --name processors-python \
+ apachestreampipes/processors-python:0.68.0-SNAPSHOT
+```
\ No newline at end of file
diff --git a/streampipes-processors-all-python/pom.xml b/streampipes-processors-all-python/pom.xml
new file mode 100644
index 0000000..2968f68
--- /dev/null
+++ b/streampipes-processors-all-python/pom.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>streampipes-extensions</artifactId>
+ <groupId>org.apache.streampipes</groupId>
+ <version>0.68.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>streampipes-processors-all-python</artifactId>
+ <properties>
+ <sp.version>0.68.0-SNAPSHOT</sp.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.streampipes</groupId>
+ <artifactId>streampipes-commons</artifactId>
+ <version>${sp.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.streampipes</groupId>
+ <artifactId>streampipes-wrapper-standalone</artifactId>
+ <version>${sp.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.streampipes</groupId>
+ <artifactId>streampipes-sdk</artifactId>
+ <version>${sp.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.streampipes</groupId>
+ <artifactId>streampipes-container-standalone</artifactId>
+ <version>${sp.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.streampipes</groupId>
+ <artifactId>streampipes-config</artifactId>
+ <version>${sp.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.streampipes</groupId>
+ <artifactId>streampipes-dataformat-json</artifactId>
+ <version>${sp.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.streampipes</groupId>
+ <artifactId>streampipes-dataformat-cbor</artifactId>
+ <version>${sp.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.streampipes</groupId>
+ <artifactId>streampipes-dataformat-smile</artifactId>
+ <version>${sp.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.streampipes</groupId>
+ <artifactId>streampipes-dataformat-fst</artifactId>
+ <version>${sp.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.streampipes</groupId>
+ <artifactId>streampipes-messaging-jms</artifactId>
+ <version>${sp.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.streampipes</groupId>
+ <artifactId>streampipes-messaging-kafka</artifactId>
+ <version>${sp.version}</version>
+ </dependency>
+ </dependencies>
+
+ <repositories>
+ <repository>
+ <id>apache.snapshots</id>
+ <name>Apache Snapshot Repository</name>
+ <url>https://repository.apache.org/snapshots</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ </repository>
+ </repositories>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <classifier>embed</classifier>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ <finalName>streampipes-processors-all-python</finalName>
+
+ </build>
+
+</project>
\ No newline at end of file
diff --git a/streampipes-processors-all-python/python/donothing.py b/streampipes-processors-all-python/python/donothing.py
new file mode 100644
index 0000000..fea2d83
--- /dev/null
+++ b/streampipes-processors-all-python/python/donothing.py
@@ -0,0 +1,34 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+from streampipes.core import EventProcessor
+
+
+class DoNothing(EventProcessor):
+ """
+ DoNothing processor
+
+ This processor does nothing and only forwards the input event to the output
+ """
+
+ def on_invocation(self):
+ pass
+
+ def on_event(self, event):
+ return event
+
+ def on_detach(self):
+ pass
\ No newline at end of file
diff --git a/streampipes-processors-all-python/python/greeter.py b/streampipes-processors-all-python/python/greeter.py
new file mode 100644
index 0000000..eed25ec
--- /dev/null
+++ b/streampipes-processors-all-python/python/greeter.py
@@ -0,0 +1,38 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+from streampipes.core import EventProcessor
+
+
+class Greeter(EventProcessor):
+ """
+ Greeter processor
+
+ This processor uses a user-defined greeting text and appends it to the event stream.
+ """
+ greeting = None
+
+ def on_invocation(self):
+ # extract greeting text from static property
+ self.greeting = self.static_properties.get('greeting')
+
+ def on_event(self, event):
+ # dict key must match the append property specified in the java part
+ event['greeting'] = self.greeting
+ return event
+
+ def on_detach(self):
+ pass
diff --git a/streampipes-processors-all-python/python/main.py b/streampipes-processors-all-python/python/main.py
new file mode 100644
index 0000000..cef3fc6
--- /dev/null
+++ b/streampipes-processors-all-python/python/main.py
@@ -0,0 +1,73 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+from streampipes.declarer import DeclarerSingleton
+from streampipes.model.pipeline_element_config import Config
+from streampipes.submitter import StandaloneModelSubmitter
+
+from donothing import DoNothing
+from greeter import Greeter
+
+
+def main():
+
+ config = Config(app_id='pe/org.apache.streampipes.processors.python')
+
+ config.register(type='host',
+ env_key='SP_HOST',
+ default='processor-python',
+ description='processor hostname')
+
+ config.register(type='port',
+ env_key='SP_PORT',
+ default=5000,
+ description='processor port')
+
+ config.register(type='service',
+ env_key='SP_SERVICE_NAME',
+ default='Python Processor',
+ description='processor service name')
+
+ config.register(type='location',
+ env_key='SP_PYTHON_ENDPOINT',
+ default='localhost:5000',
+ description='python endpoint')
+
+
+ # dict with processor id and processor class
+ # key: must match the id in the java part
+ processors = {
+ 'org.apache.streampipes.processors.python.greeter': Greeter,
+ 'org.apache.streampipes.processors.python.donothing': DoNothing,
+ }
+
+ # Declarer
+ # add the dict of processors to the Declarer
+ # This is an abstract class that holds the specified processors
+ DeclarerSingleton.add(processors=processors)
+
+ # StandaloneModelSubmitter
+ # Initializes the REST api
+ # StandaloneModelSubmitter.init(config=config)
+
+ # init_debug(config=config) is only used to start web server on correct port to mock future method. While we are
+ # already able to register the service and config in Consul, the REST endpoint exposed does not provide any
+ # description of the processors at this point - this is still done in the declareModel() in Java
+ StandaloneModelSubmitter.init_debug(config=config)
+
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/streampipes-processors-all-python/python/requirements.txt b/streampipes-processors-all-python/python/requirements.txt
new file mode 100644
index 0000000..ebad30e
--- /dev/null
+++ b/streampipes-processors-all-python/python/requirements.txt
@@ -0,0 +1,19 @@
+-f /svc/python/dist/apache_streampipes_python-0.68.0.dev1-py3-none-any.whl
+certifi==2020.6.20
+chardet==3.0.4
+click==7.1.2
+config==0.5.0.post0
+confluent-kafka==1.4.2
+Flask==1.1.2
+Flask-Classful==0.14.2
+Flask-Negotiate==0.1.0
+idna==2.10
+itsdangerous==1.1.0
+Jinja2==2.11.2
+MarkupSafe==1.1.1
+python-consul==1.1.0
+requests==2.24.0
+six==1.15.0
+urllib3==1.25.10
+waitress==1.4.4
+Werkzeug==1.0.1
diff --git a/streampipes-processors-all-python/src/main/java/org/apache/streampipes/processors/python/PythonProcessorInit.java b/streampipes-processors-all-python/src/main/java/org/apache/streampipes/processors/python/PythonProcessorInit.java
new file mode 100644
index 0000000..02dbf91
--- /dev/null
+++ b/streampipes-processors-all-python/src/main/java/org/apache/streampipes/processors/python/PythonProcessorInit.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.streampipes.processors.python;
+
+import org.apache.streampipes.container.init.DeclarersSingleton;
+import org.apache.streampipes.container.standalone.init.StandaloneModelSubmitter;
+import org.apache.streampipes.processors.python.config.Config;
+import org.apache.streampipes.processors.python.donothing.PythonDoNothingProcessor;
+import org.apache.streampipes.processors.python.greeter.PythonGreeterProcessor;
+
+
+public class PythonProcessorInit extends StandaloneModelSubmitter {
+ public static void main(String[] args) {
+
+ // Add processor controller description
+ DeclarersSingleton.getInstance()
+ .add(new PythonGreeterProcessor())
+ .add(new PythonDoNothingProcessor());
+
+ // start webserver
+ new PythonProcessorInit().init(Config.INSTANCE);
+ }
+}
diff --git a/streampipes-processors-all-python/src/main/java/org/apache/streampipes/processors/python/config/Config.java b/streampipes-processors-all-python/src/main/java/org/apache/streampipes/processors/python/config/Config.java
new file mode 100644
index 0000000..d6b07fb
--- /dev/null
+++ b/streampipes-processors-all-python/src/main/java/org/apache/streampipes/processors/python/config/Config.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.streampipes.processors.python.config;
+
+import org.apache.streampipes.config.SpConfig;
+import org.apache.streampipes.container.model.PeConfig;
+
+public enum Config implements PeConfig {
+
+ INSTANCE;
+
+ private final String SERVICE_ID = "pe/org.apache.streampipes.processor.python";
+ private final SpConfig config;
+
+ Config() {
+ config = SpConfig.getSpConfig(SERVICE_ID);
+ config.register(ConfigKeys.HOST, "processors-python", "hostname");
+ config.register(ConfigKeys.PORT, 8090, "port");
+ config.register(ConfigKeys.SERVICE_NAME, "Processors Python", "service name");
+ config.register(ConfigKeys.PYTHON_ENDPOINT, "localhost:5000", "python endpoint");
+ }
+
+ public String getHost() {
+ return config.getString(ConfigKeys.HOST);
+ }
+
+ public int getPort() {
+ return config.getInteger(ConfigKeys.PORT);
+ }
+
+ public String getPythonEndpointUrl() {
+ return "http://" + config.getString(ConfigKeys.PYTHON_ENDPOINT) + "/";
+ }
+
+ @Override
+ public String getId() {
+ return SERVICE_ID;
+ }
+
+ @Override
+ public String getName() {
+ return config.getString(ConfigKeys.SERVICE_NAME);
+ }
+
+}
diff --git a/streampipes-processors-all-python/src/main/java/org/apache/streampipes/processors/python/config/ConfigKeys.java b/streampipes-processors-all-python/src/main/java/org/apache/streampipes/processors/python/config/ConfigKeys.java
new file mode 100644
index 0000000..f79fbf7
--- /dev/null
+++ b/streampipes-processors-all-python/src/main/java/org/apache/streampipes/processors/python/config/ConfigKeys.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.streampipes.processors.python.config;
+
+public class ConfigKeys {
+ final static String HOST = "SP_HOST";
+ final static String PORT = "SP_PORT";
+ final static String SERVICE_NAME = "SP_SERVICE_NAME";
+ final static String PYTHON_ENDPOINT = "SP_PYTHON_ENDPOINT";
+}
\ No newline at end of file
diff --git a/streampipes-processors-all-python/src/main/java/org/apache/streampipes/processors/python/donothing/PythonDoNothingProcessor.java b/streampipes-processors-all-python/src/main/java/org/apache/streampipes/processors/python/donothing/PythonDoNothingProcessor.java
new file mode 100644
index 0000000..42ac539
--- /dev/null
+++ b/streampipes-processors-all-python/src/main/java/org/apache/streampipes/processors/python/donothing/PythonDoNothingProcessor.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.streampipes.processors.python.donothing;
+
+import com.google.gson.JsonObject;
+import org.apache.streampipes.commons.exceptions.SpRuntimeException;
+import org.apache.streampipes.model.graph.DataProcessorDescription;
+import org.apache.streampipes.sdk.builder.ProcessingElementBuilder;
+import org.apache.streampipes.sdk.builder.StreamRequirementsBuilder;
+import org.apache.streampipes.sdk.helpers.Locales;
+import org.apache.streampipes.sdk.helpers.OutputStrategies;
+import org.apache.streampipes.sdk.helpers.SupportedFormats;
+import org.apache.streampipes.sdk.helpers.SupportedProtocols;
+import org.apache.streampipes.wrapper.context.EventProcessorRuntimeContext;
+import org.apache.streampipes.wrapper.standalone.ProcessorParams;
+import org.apache.streampipes.wrapper.standalone.StreamPipesExternalDataProcessor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class PythonDoNothingProcessor extends StreamPipesExternalDataProcessor {
+
+ public static final String PROCESSOR_ID = "org.apache.streampipes.processors.python.donothing";
+
+ @Override
+ public DataProcessorDescription declareModel() {
+ return ProcessingElementBuilder.create(PROCESSOR_ID)
+ .withLocales(Locales.EN)
+ .requiredStream(StreamRequirementsBuilder.any())
+ // Append greeting to event stream
+ .outputStrategy(OutputStrategies.keep())
+ // NOTE: currently one Kafka transport protocol is supported
+ .supportedProtocols(SupportedProtocols.kafka())
+ .supportedFormats(SupportedFormats.jsonFormat())
+ .build();
+ }
+
+ @Override
+ public void onInvocation(ProcessorParams parameters, EventProcessorRuntimeContext runtimeContext) throws SpRuntimeException {
+ Map<String, String> staticPropertyMap = new HashMap<>();
+ JsonObject minimalInvocationGraph = createMinimalInvocationGraph(staticPropertyMap);
+ // send invocation request to python
+ invoke(minimalInvocationGraph);
+ }
+
+ @Override
+ public void onDetach() throws SpRuntimeException {
+ detach();
+ }
+}
diff --git a/streampipes-processors-all-python/src/main/java/org/apache/streampipes/processors/python/greeter/PythonGreeterProcessor.java b/streampipes-processors-all-python/src/main/java/org/apache/streampipes/processors/python/greeter/PythonGreeterProcessor.java
new file mode 100644
index 0000000..445a095
--- /dev/null
+++ b/streampipes-processors-all-python/src/main/java/org/apache/streampipes/processors/python/greeter/PythonGreeterProcessor.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.streampipes.processors.python.greeter;
+
+import com.google.gson.JsonObject;
+import org.apache.streampipes.commons.exceptions.SpRuntimeException;
+import org.apache.streampipes.model.graph.DataProcessorDescription;
+import org.apache.streampipes.sdk.builder.ProcessingElementBuilder;
+import org.apache.streampipes.sdk.builder.StreamRequirementsBuilder;
+import org.apache.streampipes.sdk.helpers.*;
+import org.apache.streampipes.vocabulary.SO;
+import org.apache.streampipes.wrapper.context.EventProcessorRuntimeContext;
+import org.apache.streampipes.wrapper.standalone.ProcessorParams;
+import org.apache.streampipes.wrapper.standalone.StreamPipesExternalDataProcessor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class PythonGreeterProcessor extends StreamPipesExternalDataProcessor {
+
+ private static final String GREETING_KEY = "greeting-key";
+ public static final String PROCESSOR_ID = "org.apache.streampipes.processors.python.greeter";
+
+ @Override
+ public DataProcessorDescription declareModel() {
+ return ProcessingElementBuilder.create(PROCESSOR_ID)
+ .withLocales(Locales.EN)
+ .requiredStream(StreamRequirementsBuilder.any())
+ // create a simple text parameter
+ .requiredTextParameter(Labels.withId(GREETING_KEY), "greeting")
+ // append greeting to event stream
+ .outputStrategy(OutputStrategies.append(
+ EpProperties.stringEp(Labels.empty(),"greeting", SO.Text)))
+ // NOTE: currently one Kafka transport protocol is supported
+ .supportedProtocols(SupportedProtocols.kafka())
+ .supportedFormats(SupportedFormats.jsonFormat())
+ .build();
+ }
+
+ @Override
+ public void onInvocation(ProcessorParams parameters, EventProcessorRuntimeContext runtimeContext) throws SpRuntimeException {
+
+ // extract static properties and add to map to build minimal invocation graph
+ Map<String, String> staticPropertyMap = new HashMap<>();
+ staticPropertyMap.put("greeting", parameters.extractor().singleValueParameter(GREETING_KEY, String.class));
+
+ JsonObject minimalInvocationGraph = createMinimalInvocationGraph(staticPropertyMap);
+
+ // send invocation request to python
+ invoke(minimalInvocationGraph);
+ }
+
+ @Override
+ public void onDetach() throws SpRuntimeException {
+ // send detach request to python to stop processor with invocationId
+ detach();
+ }
+}
diff --git a/streampipes-processors-all-python/src/main/resources/org.apache.streampipes.processors.python.donothing/strings.en b/streampipes-processors-all-python/src/main/resources/org.apache.streampipes.processors.python.donothing/strings.en
new file mode 100644
index 0000000..49db16e
--- /dev/null
+++ b/streampipes-processors-all-python/src/main/resources/org.apache.streampipes.processors.python.donothing/strings.en
@@ -0,0 +1,2 @@
+org.apache.streampipes.processors.python.donothing.title=DoNothing Python
+org.apache.streampipes.processors.python.donothing.description=DoNothing Description
diff --git a/streampipes-processors-all-python/src/main/resources/org.apache.streampipes.processors.python.greeter/strings.en b/streampipes-processors-all-python/src/main/resources/org.apache.streampipes.processors.python.greeter/strings.en
new file mode 100644
index 0000000..66cf82e
--- /dev/null
+++ b/streampipes-processors-all-python/src/main/resources/org.apache.streampipes.processors.python.greeter/strings.en
@@ -0,0 +1,5 @@
+org.apache.streampipes.processors.python.greeter.title=Python Greeter
+org.apache.streampipes.processors.python.greeter.description=Python Greeter Description
+
+greeting-key.title=Greeting
+greeting-key.description=Specifies the greeting you want to send
\ No newline at end of file
diff --git a/streampipes-processors-all-python/supervisor.conf b/streampipes-processors-all-python/supervisor.conf
new file mode 100644
index 0000000..c53f839
--- /dev/null
+++ b/streampipes-processors-all-python/supervisor.conf
@@ -0,0 +1,33 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+[supervisord]
+nodaemon=true
+user=root
+
+[program:streampipesjava]
+directory=/svc/java
+command=/bin/bash -c "java -jar streampipes-processors-all-python.jar"
+stdout_logfile=/dev/stdout
+stdout_logfile_maxbytes=0
+stderr_logfile=/dev/stderr
+stderr_logfile_maxbytes=0
+
+[program:streampipespython]
+directory=/svc/python
+command=/bin/bash -c "python main.py"
+stdout_logfile=/dev/stdout
+stdout_logfile_maxbytes=0
+stderr_logfile=/dev/stderr
+stderr_logfile_maxbytes=0