streampipes-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From zehn...@apache.org
Subject [incubator-streampipes-extensions] branch dev updated: STREAMPIPES-3: Rename project namespace to Apache coordinates
Date Wed, 11 Dec 2019 22:55:23 GMT
This is an automated email from the ASF dual-hosted git repository.

zehnder pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes-extensions.git


The following commit(s) were added to refs/heads/dev by this push:
     new bee1503  STREAMPIPES-3: Rename project namespace to Apache coordinates
bee1503 is described below

commit bee15037048e4821eb1a7a547f61cac94bd4bf45
Author: Dominik Riemer <riemer@fzi.de>
AuthorDate: Wed Dec 11 23:44:46 2019 +0100

    STREAMPIPES-3: Rename project namespace to Apache coordinates
---
 .spignore                                          |  14 +-
 pom.xml                                            |  36 +-
 streampipes-connect-adapters/pom.xml               |   4 +-
 .../streampipes-connect-adapter/pom.xml            |   6 +-
 .../streampipes/connect/ConnectAdapterInit.java    |  92 ++++
 .../streampipes/connect/adapters/PullAdapter.java  | 100 ++++
 .../connect/adapters/PullRestAdapter.java          |  71 +++
 .../adapters/coindesk/CoindeskBitcoinAdapter.java  | 124 +++++
 .../connect/adapters/coindesk/Currency.java        |  26 +
 .../connect/adapters/coindesk/model/Bpi.java       |  60 +++
 .../adapters/coindesk/model/CoindeskRawModel.java  |  70 +++
 .../connect/adapters/coindesk/model/EUR.java       |  80 +++
 .../connect/adapters/coindesk/model/GBP.java       |  80 +++
 .../connect/adapters/coindesk/model/Time.java      |  60 +++
 .../connect/adapters/coindesk/model/USD.java       |  80 +++
 .../connect/adapters/gdelt/GdeltAdapter.java       | 188 +++++++
 .../connect/adapters/iex/IexCloudAdapter.java      |  55 ++
 .../connect/adapters/iex/IexCloudNewsAdapter.java  | 137 +++++
 .../connect/adapters/iex/IexCloudStockAdapter.java | 111 ++++
 .../connect/adapters/iex/model/IexNewsData.java    | 120 +++++
 .../connect/adapters/iex/model/IexStockData.java   | 410 +++++++++++++++
 .../connect/adapters/influxdb/InfluxDbClient.java  | 321 ++++++++++++
 .../adapters/influxdb/InfluxDbSetAdapter.java      | 177 +++++++
 .../adapters/influxdb/InfluxDbStreamAdapter.java   | 211 ++++++++
 .../streampipes/connect/adapters/mysql/Column.java |  76 +++
 .../connect/adapters/mysql/MySqlAdapter.java       | 259 ++++++++++
 .../connect/adapters/mysql/MySqlClient.java        | 206 ++++++++
 .../connect/adapters/mysql/MySqlSetAdapter.java    | 200 +++++++
 .../connect/adapters/mysql/MySqlStreamAdapter.java | 199 +++++++
 .../trafficcamera/CameraDataHttpExecutor.java      |  39 ++
 .../trafficcamera/CameraFeatureTransformer.java    |  66 +++
 .../trafficcamera/CameraInfoHttpExecutor.java      |  47 ++
 .../trafficcamera/NswTrafficCameraAdapter.java     | 152 ++++++
 .../trafficcamera/TrafficCameraSensorNames.java    |  42 ++
 .../nswaustralia/trafficcamera/model/Feature.java  |  69 +++
 .../trafficcamera/model/FeatureCollection.java     |  62 +++
 .../nswaustralia/trafficcamera/model/Geometry.java |  52 ++
 .../trafficcamera/model/Properties.java            |  80 +++
 .../nswaustralia/trafficcamera/model/Rights.java   |  50 ++
 .../connect/adapters/opcua/OpcNode.java            |  59 +++
 .../streampipes/connect/adapters/opcua/OpcUa.java  | 311 +++++++++++
 .../connect/adapters/opcua/OpcUaAdapter.java       | 258 +++++++++
 .../connect/adapters/opcua/OpcUaTest.java          | 341 ++++++++++++
 .../connect/adapters/opcua/OpcUaTypes.java         |  44 ++
 .../plc4x/passive/Plc4xPassiveAdapter.java         | 117 +++++
 .../connect/adapters/plc4x/s7/Plc4xS7Adapter.java  | 265 ++++++++++
 .../connect/adapters/ros/RosBridgeAdapter.java     | 274 ++++++++++
 .../adapters/sensemap/OpenSenseMapAdapter.java     | 403 +++++++++++++++
 .../connect/adapters/sensemap/SensorNames.java     | 137 +++++
 .../adapters/sensemap/model/CurrentLocation.java   |  62 +++
 .../connect/adapters/sensemap/model/Geometry.java  |  62 +++
 .../adapters/sensemap/model/LastMeasurement.java   |  50 ++
 .../connect/adapters/sensemap/model/Loc.java       |  50 ++
 .../connect/adapters/sensemap/model/SenseBox.java  | 122 +++++
 .../connect/adapters/sensemap/model/Sensor.java    |  90 ++++
 .../adapters/simulator/RandomDataSetAdapter.java   |  90 ++++
 .../adapters/simulator/RandomDataSimulator.java    |  87 ++++
 .../simulator/RandomDataSimulatorUtils.java        |  46 ++
 .../simulator/RandomDataStreamAdapter.java         |  86 +++
 .../connect/adapters/slack/SlackAdapter.java       | 106 ++++
 .../connect/adapters/slack/SlackConsumer.java      |  77 +++
 .../connect/adapters/ti/TISensorTag.java           | 229 ++++++++
 .../adapters/wikipedia/WikipediaAdapter.java       | 144 ++++++
 .../wikipedia/WikipediaEditedArticlesAdapter.java  |  57 ++
 .../wikipedia/WikipediaModelConverter.java         |  56 ++
 .../wikipedia/WikipediaNewArticlesAdapter.java     |  59 +++
 .../adapters/wikipedia/WikipediaSseConsumer.java   |  59 +++
 .../connect/adapters/wikipedia/model/Length.java   |  50 ++
 .../connect/adapters/wikipedia/model/Meta.java     | 120 +++++
 .../connect/adapters/wikipedia/model/Revision.java |  50 ++
 .../adapters/wikipedia/model/WikipediaModel.java   | 210 ++++++++
 .../streampipes/connect/config/ConfigKeys.java     |  31 ++
 .../connect/config/ConnectWorkerConfig.java        |  88 ++++
 .../connect/protocol/set/FileProtocol.java         | 200 +++++++
 .../connect/protocol/set/HttpProtocol.java         | 172 ++++++
 .../connect/protocol/stream/BrokerProtocol.java    |  69 +++
 .../protocol/stream/FileStreamProtocol.java        | 232 +++++++++
 .../connect/protocol/stream/HDFSProtocol.java      | 319 ++++++++++++
 .../protocol/stream/HttpStreamProtocol.java        | 176 +++++++
 .../connect/protocol/stream/KafkaProtocol.java     | 238 +++++++++
 .../connect/protocol/stream/MqttConfig.java        |  61 +++
 .../connect/protocol/stream/MqttConsumer.java      |  78 +++
 .../connect/protocol/stream/MqttProtocol.java      | 161 ++++++
 .../connect/protocol/stream/PullProtocol.java      |  97 ++++
 .../connect/protocol/stream/WebsocketClient.java   |  92 ++++
 .../connect/protocol/stream/WebsocketProtocol.java | 101 ++++
 .../protocol/stream/pulsar/PulsarConsumer.java     |  88 ++++
 .../protocol/stream/pulsar/PulsarProtocol.java     | 149 ++++++
 .../protocol/stream/pulsar/PulsarUtils.java        |  33 ++
 .../streampipes/connect/ConnectAdapterInit.java    |  94 ----
 .../streampipes/connect/adapters/PullAdapter.java  | 100 ----
 .../connect/adapters/PullRestAdapter.java          |  71 ---
 .../adapters/coindesk/CoindeskBitcoinAdapter.java  | 124 -----
 .../connect/adapters/coindesk/Currency.java        |  26 -
 .../connect/adapters/coindesk/model/Bpi.java       |  60 ---
 .../adapters/coindesk/model/CoindeskRawModel.java  |  70 ---
 .../connect/adapters/coindesk/model/EUR.java       |  80 ---
 .../connect/adapters/coindesk/model/GBP.java       |  80 ---
 .../connect/adapters/coindesk/model/Time.java      |  60 ---
 .../connect/adapters/coindesk/model/USD.java       |  80 ---
 .../connect/adapters/gdelt/GdeltAdapter.java       | 188 -------
 .../connect/adapters/iex/IexCloudAdapter.java      |  55 --
 .../connect/adapters/iex/IexCloudNewsAdapter.java  | 137 -----
 .../connect/adapters/iex/IexCloudStockAdapter.java | 111 ----
 .../connect/adapters/iex/model/IexNewsData.java    | 120 -----
 .../connect/adapters/iex/model/IexStockData.java   | 410 ---------------
 .../connect/adapters/influxdb/InfluxDbClient.java  | 321 ------------
 .../adapters/influxdb/InfluxDbSetAdapter.java      | 177 -------
 .../adapters/influxdb/InfluxDbStreamAdapter.java   | 211 --------
 .../streampipes/connect/adapters/mysql/Column.java |  76 ---
 .../connect/adapters/mysql/MySqlAdapter.java       | 259 ----------
 .../connect/adapters/mysql/MySqlClient.java        | 206 --------
 .../connect/adapters/mysql/MySqlSetAdapter.java    | 200 -------
 .../connect/adapters/mysql/MySqlStreamAdapter.java | 199 -------
 .../trafficcamera/CameraDataHttpExecutor.java      |  39 --
 .../trafficcamera/CameraFeatureTransformer.java    |  66 ---
 .../trafficcamera/CameraInfoHttpExecutor.java      |  47 --
 .../trafficcamera/NswTrafficCameraAdapter.java     | 152 ------
 .../trafficcamera/TrafficCameraSensorNames.java    |  42 --
 .../nswaustralia/trafficcamera/model/Feature.java  |  69 ---
 .../trafficcamera/model/FeatureCollection.java     |  62 ---
 .../nswaustralia/trafficcamera/model/Geometry.java |  52 --
 .../trafficcamera/model/Properties.java            |  80 ---
 .../nswaustralia/trafficcamera/model/Rights.java   |  50 --
 .../connect/adapters/opcua/OpcNode.java            |  59 ---
 .../streampipes/connect/adapters/opcua/OpcUa.java  | 311 -----------
 .../connect/adapters/opcua/OpcUaAdapter.java       | 260 ----------
 .../connect/adapters/opcua/OpcUaTest.java          | 341 ------------
 .../connect/adapters/opcua/OpcUaTypes.java         |  44 --
 .../plc4x/passive/Plc4xPassiveAdapter.java         | 117 -----
 .../connect/adapters/plc4x/s7/Plc4xS7Adapter.java  | 265 ----------
 .../connect/adapters/ros/RosBridgeAdapter.java     | 274 ----------
 .../adapters/sensemap/OpenSenseMapAdapter.java     | 403 ---------------
 .../connect/adapters/sensemap/SensorNames.java     | 137 -----
 .../adapters/sensemap/model/CurrentLocation.java   |  62 ---
 .../connect/adapters/sensemap/model/Geometry.java  |  62 ---
 .../adapters/sensemap/model/LastMeasurement.java   |  50 --
 .../connect/adapters/sensemap/model/Loc.java       |  50 --
 .../connect/adapters/sensemap/model/SenseBox.java  | 122 -----
 .../connect/adapters/sensemap/model/Sensor.java    |  90 ----
 .../adapters/simulator/RandomDataSetAdapter.java   |  90 ----
 .../adapters/simulator/RandomDataSimulator.java    |  87 ----
 .../simulator/RandomDataSimulatorUtils.java        |  46 --
 .../simulator/RandomDataStreamAdapter.java         |  86 ---
 .../connect/adapters/slack/SlackAdapter.java       | 106 ----
 .../connect/adapters/slack/SlackConsumer.java      |  77 ---
 .../connect/adapters/ti/TISensorTag.java           | 229 --------
 .../adapters/wikipedia/WikipediaAdapter.java       | 144 ------
 .../wikipedia/WikipediaEditedArticlesAdapter.java  |  57 --
 .../wikipedia/WikipediaModelConverter.java         |  56 --
 .../wikipedia/WikipediaNewArticlesAdapter.java     |  59 ---
 .../adapters/wikipedia/WikipediaSseConsumer.java   |  59 ---
 .../connect/adapters/wikipedia/model/Length.java   |  50 --
 .../connect/adapters/wikipedia/model/Meta.java     | 120 -----
 .../connect/adapters/wikipedia/model/Revision.java |  50 --
 .../adapters/wikipedia/model/WikipediaModel.java   | 210 --------
 .../org/streampipes/connect/config/ConfigKeys.java |  31 --
 .../connect/config/ConnectWorkerConfig.java        |  88 ----
 .../connect/protocol/set/FileProtocol.java         | 200 -------
 .../connect/protocol/set/HttpProtocol.java         | 172 ------
 .../connect/protocol/stream/BrokerProtocol.java    |  69 ---
 .../protocol/stream/FileStreamProtocol.java        | 232 ---------
 .../connect/protocol/stream/HDFSProtocol.java      | 319 ------------
 .../protocol/stream/HttpStreamProtocol.java        | 176 -------
 .../connect/protocol/stream/KafkaProtocol.java     | 238 ---------
 .../connect/protocol/stream/MqttConfig.java        |  61 ---
 .../connect/protocol/stream/MqttConsumer.java      |  78 ---
 .../connect/protocol/stream/MqttProtocol.java      | 161 ------
 .../connect/protocol/stream/PullProtocol.java      |  97 ----
 .../connect/protocol/stream/WebsocketClient.java   |  92 ----
 .../connect/protocol/stream/WebsocketProtocol.java | 101 ----
 .../protocol/stream/pulsar/PulsarConsumer.java     |  88 ----
 .../protocol/stream/pulsar/PulsarProtocol.java     | 149 ------
 .../protocol/stream/pulsar/PulsarUtils.java        |  33 --
 .../connect/adapters/PullAdapterTest.java          |  53 ++
 .../streampipes/connect/adapters/generic/Mock.java |  26 +
 .../connect/adapters/generic/UtilTest.java         |  68 +++
 .../generic/elements/AddTimestampTest.java         |  40 ++
 .../generic/elements/DuplicateFilterTest.java      | 128 +++++
 .../generic/protocol/set/HttpProtocolTest.java     | 122 +++++
 .../generic/protocol/stream/HttpProtocolTest.java  | 172 ++++++
 .../adapters/sensemap/OpenSenseMapAdapterTest.java | 133 +++++
 .../connect/adapters/sensemap/SensorNamesTest.java |  56 ++
 .../connect/adapters/ti/TISensorTagTest.java       |  61 +++
 .../connect/adapters/PullAdapterTest.java          |  53 --
 .../streampipes/connect/adapters/generic/Mock.java |  26 -
 .../connect/adapters/generic/UtilTest.java         |  68 ---
 .../generic/elements/AddTimestampTest.java         |  40 --
 .../generic/elements/DuplicateFilterTest.java      | 128 -----
 .../generic/protocol/set/HttpProtocolTest.java     | 122 -----
 .../generic/protocol/stream/HttpProtocolTest.java  | 172 ------
 .../adapters/sensemap/OpenSenseMapAdapterTest.java | 133 -----
 .../connect/adapters/sensemap/SensorNamesTest.java |  57 --
 .../connect/adapters/ti/TISensorTagTest.java       |  61 ---
 streampipes-pipeline-elements-all-jvm/pom.xml      |  20 +-
 .../pe/jvm/AllPipelineElementsInit.java            | 125 +++++
 .../pe/jvm/config/AllPipelineElementsConfig.java   |  86 +++
 .../streampipes/pe/jvm/config/ConfigKeys.java      |  26 +
 .../pe/jvm/AllPipelineElementsInit.java            | 125 -----
 .../pe/jvm/config/AllPipelineElementsConfig.java   |  86 ---
 .../org/streampipes/pe/jvm/config/ConfigKeys.java  |  26 -
 .../pom.xml                                        |   2 +-
 .../pe/simulator/StreamPipesSimulationRunner.java  | 114 ++++
 .../pe/simulator/TopicAwareWorkflow.java           |  37 ++
 .../pe/simulator/StreamPipesSimulationRunner.java  | 114 ----
 .../pe/simulator/TopicAwareWorkflow.java           |  37 --
 streampipes-pipeline-elements-shared/pom.xml       |   2 +-
 .../pe/shared/PlaceholderExtractor.java            |  76 +++
 .../pe/shared/PlaceholderExtractor.java            |  76 ---
 streampipes-processors-aggregation-flink/pom.xml   |  24 +-
 .../flink/AbstractAggregationProgram.java          |  42 ++
 .../aggregation/flink/AggregationFlinkInit.java    |  55 ++
 .../flink/config/AggregationFlinkConfig.java       |  97 ++++
 .../aggregation/flink/config/ConfigKeys.java       |  30 ++
 .../flink/processor/aggregation/Aggregation.java   |  88 ++++
 .../aggregation/AggregationController.java         | 145 ++++++
 .../aggregation/AggregationParameters.java         |  83 +++
 .../processor/aggregation/AggregationProgram.java  |  84 +++
 .../processor/aggregation/AggregationType.java     |  26 +
 .../processor/aggregation/CountAggregation.java    |  52 ++
 .../processor/aggregation/TimeAggregation.java     |  52 ++
 .../processor/aggregation/config/aggregation.md    |   0
 .../flink/processor/count/CountController.java     |  87 ++++
 .../flink/processor/count/CountMapper.java         |  37 ++
 .../flink/processor/count/CountParameters.java     |  50 ++
 .../flink/processor/count/CountProgram.java        |  51 ++
 .../flink/processor/count/CountTrigger.java        |  45 ++
 .../flink/processor/count/TimeWindowConverter.java |  35 ++
 .../flink/processor/count/Tuple2MapMapper.java     |  38 ++
 .../processor/eventcount/EventCountController.java |  77 +++
 .../processor/eventcount/EventCountMapper.java     |  28 +
 .../eventcount/EventCountOutputMapper.java         |  38 ++
 .../processor/eventcount/EventCountParameters.java |  42 ++
 .../processor/eventcount/EventCountProgram.java    |  39 ++
 .../flink/processor/rate/EventRate.java            |  39 ++
 .../flink/processor/rate/EventRateController.java  |  68 +++
 .../flink/processor/rate/EventRateParameter.java   |  37 ++
 .../flink/processor/rate/EventRateProgram.java     |  50 ++
 .../flink/AbstractAggregationProgram.java          |  42 --
 .../aggregation/flink/AggregationFlinkInit.java    |  55 --
 .../flink/config/AggregationFlinkConfig.java       |  97 ----
 .../aggregation/flink/config/ConfigKeys.java       |  30 --
 .../flink/processor/aggregation/Aggregation.java   |  88 ----
 .../aggregation/AggregationController.java         | 147 ------
 .../aggregation/AggregationParameters.java         |  83 ---
 .../processor/aggregation/AggregationProgram.java  |  85 ---
 .../processor/aggregation/AggregationType.java     |  26 -
 .../processor/aggregation/CountAggregation.java    |  52 --
 .../processor/aggregation/TimeAggregation.java     |  52 --
 .../flink/processor/count/CountController.java     |  87 ----
 .../flink/processor/count/CountMapper.java         |  37 --
 .../flink/processor/count/CountParameters.java     |  50 --
 .../flink/processor/count/CountProgram.java        |  51 --
 .../flink/processor/count/CountTrigger.java        |  45 --
 .../flink/processor/count/TimeWindowConverter.java |  35 --
 .../flink/processor/count/Tuple2MapMapper.java     |  38 --
 .../processor/eventcount/EventCountController.java |  77 ---
 .../processor/eventcount/EventCountMapper.java     |  28 -
 .../eventcount/EventCountOutputMapper.java         |  38 --
 .../processor/eventcount/EventCountParameters.java |  42 --
 .../processor/eventcount/EventCountProgram.java    |  39 --
 .../flink/processor/rate/EventRate.java            |  39 --
 .../flink/processor/rate/EventRateController.java  |  68 ---
 .../flink/processor/rate/EventRateParameter.java   |  37 --
 .../flink/processor/rate/EventRateProgram.java     |  50 --
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  35 ++
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  11 +
 .../documentation.md                               |   0
 .../strings.en                                     |   8 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   5 +
 .../strings.en                                     |  35 --
 .../strings.en                                     |  11 -
 .../strings.en                                     |   8 -
 .../strings.en                                     |   5 -
 .../processor/aggregation/AggregationTestData.java |  67 +++
 .../aggregation/TestTimeAggregationProgram.java    |  75 +++
 .../flink/processor/count/TestCountProgram.java    | 129 +++++
 .../flink/processor/rate/TestRateProgram.java      | 121 +++++
 .../processor/aggregation/AggregationTestData.java |  67 ---
 .../aggregation/TestTimeAggregationProgram.java    |  75 ---
 .../flink/processor/count/TestCountProgram.java    | 129 -----
 .../flink/processor/rate/TestRateProgram.java      | 121 -----
 streampipes-processors-enricher-flink/pom.xml      |  22 +-
 .../enricher/flink/AbstractEnricherProgram.java    |  42 ++
 .../enricher/flink/EnricherFlinkInit.java          |  57 ++
 .../enricher/flink/config/ConfigKeys.java          |  30 ++
 .../enricher/flink/config/EnricherFlinkConfig.java |  95 ++++
 .../flink/processor/math/mathop/MathOp.java        |  50 ++
 .../processor/math/mathop/MathOpController.java    | 104 ++++
 .../processor/math/mathop/MathOpParameters.java    |  55 ++
 .../flink/processor/math/mathop/MathOpProgram.java |  37 ++
 .../flink/processor/math/operation/Operation.java  |  26 +
 .../math/operation/OperationAddition.java          |  27 +
 .../processor/math/operation/OperationDivide.java  |  27 +
 .../processor/math/operation/OperationModulo.java  |  27 +
 .../math/operation/OperationMultiply.java          |  27 +
 .../math/operation/OperationSubtracting.java       |  27 +
 .../processor/math/staticmathop/StaticMathOp.java  |  50 ++
 .../math/staticmathop/StaticMathOpController.java  | 100 ++++
 .../math/staticmathop/StaticMathOpParameters.java  |  55 ++
 .../math/staticmathop/StaticMathOpProgram.java     |  37 ++
 .../processor/timestamp/TimestampController.java   |  68 +++
 .../processor/timestamp/TimestampEnricher.java     |  41 ++
 .../processor/timestamp/TimestampParameters.java   |  38 ++
 .../processor/timestamp/TimestampProgram.java      |  37 ++
 .../flink/processor/trigonometry/Operation.java    |  25 +
 .../flink/processor/trigonometry/Trigonometry.java |  53 ++
 .../trigonometry/TrigonometryController.java       |  82 +++
 .../trigonometry/TrigonometryParameters.java       |  48 ++
 .../trigonometry/TrigonometryProgram.java          |  35 ++
 .../urldereferencing/UrlDereferencing.java         |  59 +++
 .../UrlDereferencingController.java                |  75 +++
 .../UrlDereferencingParameter.java                 |  42 ++
 .../urldereferencing/UrlDereferencingProgram.java  |  37 ++
 .../enricher/flink/AbstractEnricherProgram.java    |  42 --
 .../enricher/flink/EnricherFlinkInit.java          |  57 --
 .../enricher/flink/config/ConfigKeys.java          |  30 --
 .../enricher/flink/config/EnricherFlinkConfig.java |  95 ----
 .../flink/processor/math/mathop/MathOp.java        |  50 --
 .../processor/math/mathop/MathOpController.java    | 104 ----
 .../processor/math/mathop/MathOpParameters.java    |  55 --
 .../flink/processor/math/mathop/MathOpProgram.java |  37 --
 .../flink/processor/math/operation/Operation.java  |  26 -
 .../math/operation/OperationAddition.java          |  27 -
 .../processor/math/operation/OperationDivide.java  |  27 -
 .../processor/math/operation/OperationModulo.java  |  27 -
 .../math/operation/OperationMultiply.java          |  27 -
 .../math/operation/OperationSubtracting.java       |  27 -
 .../processor/math/staticmathop/StaticMathOp.java  |  50 --
 .../math/staticmathop/StaticMathOpController.java  | 100 ----
 .../math/staticmathop/StaticMathOpParameters.java  |  55 --
 .../math/staticmathop/StaticMathOpProgram.java     |  37 --
 .../processor/timestamp/TimestampController.java   |  68 ---
 .../processor/timestamp/TimestampEnricher.java     |  41 --
 .../processor/timestamp/TimestampParameters.java   |  38 --
 .../processor/timestamp/TimestampProgram.java      |  39 --
 .../flink/processor/trigonometry/Operation.java    |  25 -
 .../flink/processor/trigonometry/Trigonometry.java |  53 --
 .../trigonometry/TrigonometryController.java       |  82 ---
 .../trigonometry/TrigonometryParameters.java       |  48 --
 .../trigonometry/TrigonometryProgram.java          |  35 --
 .../urldereferencing/UrlDereferencing.java         |  59 ---
 .../UrlDereferencingController.java                |  75 ---
 .../UrlDereferencingParameter.java                 |  42 --
 .../urldereferencing/UrlDereferencingProgram.java  |  37 --
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  11 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  10 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   9 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   5 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   2 +
 .../strings.en                                     |  11 -
 .../strings.en                                     |  10 -
 .../strings.en                                     |   9 -
 .../strings.en                                     |   5 -
 .../strings.en                                     |   2 -
 streampipes-processors-enricher-jvm/pom.xml        |  22 +-
 .../processors/enricher/jvm/EnricherJvmInit.java   |  47 ++
 .../processors/enricher/jvm/config/ConfigKeys.java |  26 +
 .../enricher/jvm/config/EnricherJvmConfig.java     |  87 ++++
 .../jvm/processor/sizemeasure/SizeMeasure.java     |  66 +++
 .../sizemeasure/SizeMeasureController.java         |  68 +++
 .../sizemeasure/SizeMeasureParameters.java         |  33 ++
 .../processors/enricher/jvm/EnricherJvmInit.java   |  47 --
 .../processors/enricher/jvm/config/ConfigKeys.java |  26 -
 .../enricher/jvm/config/EnricherJvmConfig.java     |  87 ----
 .../jvm/processor/sizemeasure/SizeMeasure.java     |  66 ---
 .../sizemeasure/SizeMeasureController.java         |  68 ---
 .../sizemeasure/SizeMeasureParameters.java         |  33 --
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   5 +
 .../strings.en                                     |   5 -
 streampipes-processors-filters-jvm/pom.xml         |  22 +-
 .../processors/filters/jvm/FiltersJvmInit.java     |  57 ++
 .../processors/filters/jvm/config/ConfigKeys.java  |  27 +
 .../filters/jvm/config/FiltersJvmConfig.java       |  89 ++++
 .../filters/jvm/processor/compose/Compose.java     |  70 +++
 .../jvm/processor/compose/ComposeController.java   |  68 +++
 .../jvm/processor/compose/ComposeParameters.java   |  37 ++
 .../processor/numericalfilter/NumericalFilter.java |  69 +++
 .../numericalfilter/NumericalFilterController.java |  91 ++++
 .../numericalfilter/NumericalFilterParameters.java |  49 ++
 .../numericalfilter/NumericalOperator.java         |  24 +
 .../jvm/processor/projection/Projection.java       |  47 ++
 .../processor/projection/ProjectionController.java |  63 +++
 .../processor/projection/ProjectionParameters.java |  38 ++
 .../jvm/processor/textfilter/StringOperator.java   |  23 +
 .../jvm/processor/textfilter/TextFilter.java       |  57 ++
 .../processor/textfilter/TextFilterController.java |  78 +++
 .../processor/textfilter/TextFilterParameters.java |  49 ++
 .../processor/threshold/ThresholdDetection.java    |  73 +++
 .../threshold/ThresholdDetectionController.java    |  92 ++++
 .../threshold/ThresholdDetectionOperator.java      |  24 +
 .../threshold/ThresholdDetectionParameters.java    |  49 ++
 .../processors/filters/jvm/FiltersJvmInit.java     |  57 --
 .../processors/filters/jvm/config/ConfigKeys.java  |  27 -
 .../filters/jvm/config/FiltersJvmConfig.java       |  89 ----
 .../filters/jvm/processor/compose/Compose.java     |  70 ---
 .../jvm/processor/compose/ComposeController.java   |  68 ---
 .../jvm/processor/compose/ComposeParameters.java   |  37 --
 .../processor/numericalfilter/NumericalFilter.java |  69 ---
 .../numericalfilter/NumericalFilterController.java |  91 ----
 .../numericalfilter/NumericalFilterParameters.java |  49 --
 .../numericalfilter/NumericalOperator.java         |  24 -
 .../jvm/processor/projection/Projection.java       |  47 --
 .../processor/projection/ProjectionController.java |  63 ---
 .../processor/projection/ProjectionParameters.java |  38 --
 .../jvm/processor/textfilter/StringOperator.java   |  23 -
 .../jvm/processor/textfilter/TextFilter.java       |  57 --
 .../processor/textfilter/TextFilterController.java |  78 ---
 .../processor/textfilter/TextFilterParameters.java |  49 --
 .../processor/threshold/ThresholdDetection.java    |  73 ---
 .../threshold/ThresholdDetectionController.java    |  92 ----
 .../threshold/ThresholdDetectionOperator.java      |  24 -
 .../threshold/ThresholdDetectionParameters.java    |  49 --
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   2 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  11 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   2 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  11 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  11 +
 .../strings.en                                     |   2 -
 .../strings.en                                     |  11 -
 .../strings.en                                     |   2 -
 .../strings.en                                     |  11 -
 .../strings.en                                     |  11 -
 streampipes-processors-filters-siddhi/pom.xml      |  24 +-
 .../processors/siddhi/FiltersSiddhiInit.java       |  51 ++
 .../processors/siddhi/config/ConfigKeys.java       |  27 +
 .../siddhi/config/FilterSiddhiConfig.java          |  89 ++++
 .../processors/siddhi/filter/NumericalFilter.java  |  37 ++
 .../siddhi/filter/NumericalFilterController.java   |  82 +++
 .../siddhi/filter/NumericalFilterParameters.java   |  49 ++
 .../siddhi/filter/NumericalOperator.java           |  23 +
 .../processors/siddhi/frequency/Frequency.java     |  36 ++
 .../siddhi/frequency/FrequencyController.java      |  64 +++
 .../siddhi/frequency/FrequencyParameters.java      |  50 ++
 .../siddhi/frequencychange/FrequencyChange.java    |  36 ++
 .../frequencychange/FrequencyChangeController.java |  68 +++
 .../frequencychange/FrequencyChangeParameters.java |  61 +++
 .../processors/siddhi/sequence/Sequence.java       |  43 ++
 .../siddhi/sequence/SequenceController.java        |  65 +++
 .../siddhi/sequence/SequenceParameters.java        |  40 ++
 .../processors/siddhi/stop/StreamStop.java         |  45 ++
 .../siddhi/stop/StreamStopController.java          |  73 +++
 .../siddhi/stop/StreamStopParameters.java          |  40 ++
 .../streampipes/processors/siddhi/trend/Trend.java |  78 +++
 .../processors/siddhi/trend/TrendController.java   |  82 +++
 .../processors/siddhi/trend/TrendOperator.java     |  23 +
 .../processors/siddhi/trend/TrendParameters.java   |  63 +++
 .../processors/siddhi/FiltersSiddhiInit.java       |  51 --
 .../processors/siddhi/config/ConfigKeys.java       |  27 -
 .../siddhi/config/FilterSiddhiConfig.java          |  89 ----
 .../processors/siddhi/filter/NumericalFilter.java  |  37 --
 .../siddhi/filter/NumericalFilterController.java   |  82 ---
 .../siddhi/filter/NumericalFilterParameters.java   |  49 --
 .../siddhi/filter/NumericalOperator.java           |  23 -
 .../processors/siddhi/frequency/Frequency.java     |  36 --
 .../siddhi/frequency/FrequencyController.java      |  64 ---
 .../siddhi/frequency/FrequencyParameters.java      |  50 --
 .../siddhi/frequencychange/FrequencyChange.java    |  36 --
 .../frequencychange/FrequencyChangeController.java |  68 ---
 .../frequencychange/FrequencyChangeParameters.java |  61 ---
 .../processors/siddhi/sequence/Sequence.java       |  43 --
 .../siddhi/sequence/SequenceController.java        |  65 ---
 .../siddhi/sequence/SequenceParameters.java        |  40 --
 .../processors/siddhi/stop/StreamStop.java         |  45 --
 .../siddhi/stop/StreamStopController.java          |  73 ---
 .../siddhi/stop/StreamStopParameters.java          |  40 --
 .../streampipes/processors/siddhi/trend/Trend.java |  78 ---
 .../processors/siddhi/trend/TrendController.java   |  82 ---
 .../processors/siddhi/trend/TrendOperator.java     |  23 -
 .../processors/siddhi/trend/TrendParameters.java   |  63 ---
 .../documentation.md                               |   0
 .../strings.en                                     |   8 +
 .../documentation.md                               |   0
 .../strings.en                                     |  11 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  14 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  11 +
 .../documentation.md                               |   0
 .../strings.en                                     |   5 +
 .../documentation.md                               |   0
 .../strings.en                                     |   8 +
 .../strings.en                                     |   8 -
 .../strings.en                                     |  11 -
 .../strings.en                                     |  14 -
 .../strings.en                                     |  11 -
 .../strings.en                                     |   5 -
 .../strings.en                                     |   8 -
 .../siddhi/trend/TestTrendProcessor.java           | 150 ++++++
 .../siddhi/trend/TestTrendProcessor.java           | 150 ------
 streampipes-processors-geo-flink/pom.xml           |  22 +-
 .../processor/geo/flink/AbstractGeoProgram.java    |  42 ++
 .../processor/geo/flink/GeoFlinkInit.java          |  49 ++
 .../processor/geo/flink/config/ConfigKeys.java     |  30 ++
 .../processor/geo/flink/config/GeoFlinkConfig.java |  94 ++++
 .../flink/processor/gridenricher/CellOption.java   | 132 +++++
 .../processor/gridenricher/EnrichmentSettings.java |  83 +++
 .../gridenricher/SpatialGridCalculator.java        |  65 +++
 .../gridenricher/SpatialGridConstants.java         |  31 ++
 .../gridenricher/SpatialGridEnricher.java          |  60 +++
 .../SpatialGridEnrichmentController.java           |  97 ++++
 .../SpatialGridEnrichmentParameters.java           |  36 ++
 .../gridenricher/SpatialGridEnrichmentProgram.java |  35 ++
 .../processor/geo/flink/AbstractGeoProgram.java    |  42 --
 .../processor/geo/flink/GeoFlinkInit.java          |  49 --
 .../processor/geo/flink/config/ConfigKeys.java     |  30 --
 .../processor/geo/flink/config/GeoFlinkConfig.java |  94 ----
 .../flink/processor/gridenricher/CellOption.java   | 132 -----
 .../processor/gridenricher/EnrichmentSettings.java |  83 ---
 .../gridenricher/SpatialGridCalculator.java        |  65 ---
 .../gridenricher/SpatialGridConstants.java         |  31 --
 .../gridenricher/SpatialGridEnricher.java          |  60 ---
 .../SpatialGridEnrichmentController.java           |  97 ----
 .../SpatialGridEnrichmentParameters.java           |  36 --
 .../gridenricher/SpatialGridEnrichmentProgram.java |  35 --
 .../documentation.md                               |   0
 .../strings.en                                     |  14 +
 .../org.streampipes.processor.geo.flink/strings.en |  14 -
 streampipes-processors-geo-jvm/pom.xml             |  22 +-
 .../streampipes/processors/geo/jvm/GeoJvmInit.java |  55 ++
 .../processors/geo/jvm/config/ConfigKeys.java      |  28 +
 .../processors/geo/jvm/config/GeoJvmConfig.java    |  93 ++++
 .../distancecalculator/DistanceCalculator.java     |  69 +++
 .../DistanceCalculatorController.java              |  81 +++
 .../DistanceCalculatorParameters.java              |  59 +++
 .../processor/geocoder/GoogleMapsGeocoding.java    |  81 +++
 .../geocoder/GoogleMapsGeocodingController.java    |  71 +++
 .../geocoder/GoogleMapsGeocodingParameters.java    |  42 ++
 .../processor/revgeocoder/ReverseGeocoding.java    |  72 +++
 .../revgeocoder/ReverseGeocodingController.java    |  73 +++
 .../revgeocoder/ReverseGeocodingParameters.java    |  42 ++
 .../jvm/processor/revgeocoder/geocode/GeoName.java | 129 +++++
 .../revgeocoder/geocode/ReverseGeoCode.java        | 128 +++++
 .../revgeocoder/geocode/kdtree/KDNode.java         |  57 ++
 .../geocode/kdtree/KDNodeComparator.java           |  60 +++
 .../revgeocoder/geocode/kdtree/KDTree.java         |  92 ++++
 .../staticgeocoder/StaticGoogleMapsGeocoder.java   |  75 +++
 .../StaticGoogleMapsGeocodingController.java       |  69 +++
 .../StaticGoogleMapsGeocodingParameters.java       |  42 ++
 .../streampipes/processors/geo/jvm/GeoJvmInit.java |  55 --
 .../processors/geo/jvm/config/ConfigKeys.java      |  28 -
 .../processors/geo/jvm/config/GeoJvmConfig.java    |  93 ----
 .../distancecalculator/DistanceCalculator.java     |  69 ---
 .../DistanceCalculatorController.java              |  81 ---
 .../DistanceCalculatorParameters.java              |  59 ---
 .../processor/geocoder/GoogleMapsGeocoding.java    |  81 ---
 .../geocoder/GoogleMapsGeocodingController.java    |  71 ---
 .../geocoder/GoogleMapsGeocodingParameters.java    |  42 --
 .../processor/revgeocoder/ReverseGeocoding.java    |  72 ---
 .../revgeocoder/ReverseGeocodingController.java    |  73 ---
 .../revgeocoder/ReverseGeocodingParameters.java    |  42 --
 .../jvm/processor/revgeocoder/geocode/GeoName.java | 129 -----
 .../revgeocoder/geocode/ReverseGeoCode.java        | 128 -----
 .../revgeocoder/geocode/kdtree/KDNode.java         |  57 --
 .../geocode/kdtree/KDNodeComparator.java           |  60 ---
 .../revgeocoder/geocode/kdtree/KDTree.java         |  92 ----
 .../staticgeocoder/StaticGoogleMapsGeocoder.java   |  75 ---
 .../StaticGoogleMapsGeocodingController.java       |  69 ---
 .../StaticGoogleMapsGeocodingParameters.java       |  42 --
 .../documentation.md                               |   0
 .../strings.en                                     |   5 +
 .../documentation.md                               |   0
 .../strings.en                                     |   9 +
 .../documentation.md                               |   0
 .../strings.en                                     |   6 +
 .../documentation.md                               |   0
 .../strings.en                                     |  17 +
 .../strings.en                                     |   5 -
 .../strings.en                                     |   9 -
 .../strings.en                                     |   6 -
 .../strings.en                                     |  17 -
 .../pom.xml                                        |  22 +-
 .../jvm/ImageProcessingJvmInit.java                |  55 ++
 .../imageprocessing/jvm/config/ConfigKeys.java     |  27 +
 .../jvm/config/ImageProcessingJvmConfig.java       |  92 ++++
 .../jvm/processor/commons/ImageTransformer.java    |  91 ++++
 .../processor/commons/PlainImageTransformer.java   |  53 ++
 .../jvm/processor/commons/RequiredBoxStream.java   |  42 ++
 .../GenericImageClassification.java                | 103 ++++
 .../GenericImageClassificationController.java      |  65 +++
 .../GenericImageClassificationParameters.java      |  35 ++
 .../jvm/processor/imagecropper/ImageCropper.java   |  72 +++
 .../imagecropper/ImageCropperController.java       |  66 +++
 .../imagecropper/ImageCropperParameters.java       |  28 +
 .../processor/imageenrichment/BoxCoordinates.java  |  57 ++
 .../processor/imageenrichment/ImageEnricher.java   |  81 +++
 .../imageenrichment/ImageEnrichmentController.java |  66 +++
 .../imageenrichment/ImageEnrichmentParameters.java |  77 +++
 .../jvm/processor/qrreader/QrCodeReader.java       |  96 ++++
 .../processor/qrreader/QrCodeReaderController.java |  76 +++
 .../processor/qrreader/QrCodeReaderParameters.java |  48 ++
 .../jvm/ImageProcessingJvmInit.java                |  55 --
 .../imageprocessing/jvm/config/ConfigKeys.java     |  27 -
 .../jvm/config/ImageProcessingJvmConfig.java       |  92 ----
 .../jvm/processor/commons/ImageTransformer.java    |  91 ----
 .../processor/commons/PlainImageTransformer.java   |  53 --
 .../jvm/processor/commons/RequiredBoxStream.java   |  42 --
 .../GenericImageClassification.java                | 103 ----
 .../GenericImageClassificationController.java      |  65 ---
 .../GenericImageClassificationParameters.java      |  35 --
 .../jvm/processor/imagecropper/ImageCropper.java   |  72 ---
 .../imagecropper/ImageCropperController.java       |  66 ---
 .../imagecropper/ImageCropperParameters.java       |  28 -
 .../processor/imageenrichment/BoxCoordinates.java  |  57 --
 .../processor/imageenrichment/ImageEnricher.java   |  81 ---
 .../imageenrichment/ImageEnrichmentController.java |  66 ---
 .../imageenrichment/ImageEnrichmentParameters.java |  77 ---
 .../jvm/processor/qrreader/QrCodeReader.java       |  96 ----
 .../processor/qrreader/QrCodeReaderController.java |  76 ---
 .../processor/qrreader/QrCodeReaderParameters.java |  48 --
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   4 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   8 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   8 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  14 +
 .../strings.en                                     |   4 -
 .../strings.en                                     |   8 -
 .../strings.en                                     |   8 -
 .../strings.en                                     |  14 -
 .../pom.xml                                        |  24 +-
 .../flink/AbstractPatternDetectionProgram.java     |  49 ++
 .../detection/flink/PatternDetectionFlinkInit.java |  55 ++
 .../pattern/detection/flink/config/ConfigKeys.java |  30 ++
 .../flink/config/PatternDetectionFlinkConfig.java  |  97 ++++
 .../detection/flink/processor/absence/Absence.java |  21 +
 .../flink/processor/absence/AbsenceController.java |  78 +++
 .../flink/processor/absence/AbsenceParameters.java |  54 ++
 .../flink/processor/absence/AbsenceProgram.java    | 125 +++++
 .../pattern/detection/flink/processor/and/And.java |  21 +
 .../flink/processor/and/AndController.java         |  80 +++
 .../flink/processor/and/AndParameters.java         |  58 +++
 .../detection/flink/processor/and/AndProgram.java  |  74 +++
 .../detection/flink/processor/and/TimeUnit.java    |  22 +
 .../flink/processor/and/TimeUnitConverter.java     |  34 ++
 .../flink/processor/common/TimestampExtractor.java |  35 ++
 .../processor/peak/PeakDetectionCalculator.java    | 134 +++++
 .../processor/peak/PeakDetectionController.java    |  91 ++++
 .../processor/peak/PeakDetectionParameters.java    |  84 +++
 .../flink/processor/peak/PeakDetectionProgram.java |  72 +++
 .../processor/peak/utils/SlidingBatchWindow.java   |  53 ++
 .../flink/processor/sequence/EventStorage.java     |  41 ++
 .../flink/processor/sequence/Sequence.java         |  85 +++
 .../processor/sequence/SequenceController.java     |  65 +++
 .../processor/sequence/SequenceParameters.java     |  42 ++
 .../flink/processor/sequence/SequenceProgram.java  |  49 ++
 .../flink/AbstractPatternDetectionProgram.java     |  49 --
 .../detection/flink/PatternDetectionFlinkInit.java |  55 --
 .../pattern/detection/flink/config/ConfigKeys.java |  30 --
 .../flink/config/PatternDetectionFlinkConfig.java  |  97 ----
 .../detection/flink/processor/absence/Absence.java |  21 -
 .../flink/processor/absence/AbsenceController.java |  78 ---
 .../flink/processor/absence/AbsenceParameters.java |  54 --
 .../flink/processor/absence/AbsenceProgram.java    | 125 -----
 .../pattern/detection/flink/processor/and/And.java |  21 -
 .../flink/processor/and/AndController.java         |  80 ---
 .../flink/processor/and/AndParameters.java         |  58 ---
 .../detection/flink/processor/and/AndProgram.java  |  74 ---
 .../detection/flink/processor/and/TimeUnit.java    |  22 -
 .../flink/processor/and/TimeUnitConverter.java     |  34 --
 .../flink/processor/common/TimestampExtractor.java |  35 --
 .../processor/peak/PeakDetectionCalculator.java    | 134 -----
 .../processor/peak/PeakDetectionController.java    |  91 ----
 .../processor/peak/PeakDetectionParameters.java    |  84 ---
 .../flink/processor/peak/PeakDetectionProgram.java |  72 ---
 .../processor/peak/utils/SlidingBatchWindow.java   |  53 --
 .../flink/processor/sequence/EventStorage.java     |  41 --
 .../flink/processor/sequence/Sequence.java         |  85 ---
 .../processor/sequence/SequenceController.java     |  65 ---
 .../processor/sequence/SequenceParameters.java     |  42 --
 .../flink/processor/sequence/SequenceProgram.java  |  49 --
 .../documentation.md                               |   0
 .../strings.en                                     |   8 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  14 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  23 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   8 +
 .../strings.en                                     |   8 -
 .../strings.en                                     |  14 -
 .../strings.en                                     |  23 -
 .../strings.en                                     |   8 -
 .../detection/processor/absence/TestAbsence.java   | 116 +++++
 .../pattern/detection/processor/and/TestAnd.java   | 128 +++++
 .../detection/processor/absence/TestAbsence.java   | 116 -----
 .../pattern/detection/processor/and/TestAnd.java   | 128 -----
 streampipes-processors-statistics-flink/pom.xml    |  22 +-
 .../flink/AbstractStatisticsProgram.java           |  42 ++
 .../statistics/flink/StatisticsFlinkInit.java      |  51 ++
 .../statistics/flink/config/ConfigKeys.java        |  30 ++
 .../flink/config/StatisticsFlinkConfig.java        |  98 ++++
 .../flink/extensions/MapKeySelector.java           |  42 ++
 .../flink/extensions/SlidingBatchWindow.java       |  50 ++
 .../flink/extensions/SlidingEventTimeWindow.java   |  79 +++
 .../flink/extensions/TimestampMappingFunction.java |  28 +
 .../stat/summary/StatisticsSummaryCalculator.java  |  63 +++
 .../stat/summary/StatisticsSummaryController.java  | 101 ++++
 .../stat/summary/StatisticsSummaryParameters.java  |  38 ++
 .../stat/summary/StatisticsSummaryProgram.java     |  39 ++
 .../window/StatisticsSummaryCalculatorWindow.java  |  68 +++
 .../window/StatisticsSummaryControllerWindow.java  | 109 ++++
 .../window/StatisticsSummaryParametersWindow.java  |  70 +++
 .../StatisticsSummaryParamsSerializable.java       |  62 +++
 .../window/StatisticsSummaryProgramWindow.java     |  74 +++
 .../flink/AbstractStatisticsProgram.java           |  42 --
 .../statistics/flink/StatisticsFlinkInit.java      |  51 --
 .../statistics/flink/config/ConfigKeys.java        |  30 --
 .../flink/config/StatisticsFlinkConfig.java        |  98 ----
 .../flink/extensions/MapKeySelector.java           |  42 --
 .../flink/extensions/SlidingBatchWindow.java       |  50 --
 .../flink/extensions/SlidingEventTimeWindow.java   |  79 ---
 .../flink/extensions/TimestampMappingFunction.java |  28 -
 .../stat/summary/StatisticsSummaryCalculator.java  |  63 ---
 .../stat/summary/StatisticsSummaryController.java  | 101 ----
 .../stat/summary/StatisticsSummaryParameters.java  |  38 --
 .../stat/summary/StatisticsSummaryProgram.java     |  39 --
 .../window/StatisticsSummaryCalculatorWindow.java  |  68 ---
 .../window/StatisticsSummaryControllerWindow.java  | 109 ----
 .../window/StatisticsSummaryParametersWindow.java  |  70 ---
 .../StatisticsSummaryParamsSerializable.java       |  62 ---
 .../window/StatisticsSummaryProgramWindow.java     |  74 ---
 .../icon.png                                       | Bin
 .../strings.en                                     |  18 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   5 +
 .../strings.en                                     |  18 -
 .../strings.en                                     |   5 -
 streampipes-processors-text-mining-flink/pom.xml   |  24 +-
 .../flink/AbstractTextMiningProgram.java           |  42 ++
 .../textmining/flink/TextMiningFlinkInit.java      |  45 ++
 .../textmining/flink/config/ConfigKeys.java        |  30 ++
 .../flink/config/TextMiningFlinkConfig.java        |  98 ++++
 .../flink/processor/entity/EntityExtraction.java   |  60 +++
 .../processor/entity/EntityExtractionModel.java    |  42 ++
 .../processor/language/LanguageDetection.java      |  75 +++
 .../language/LanguageDetectionController.java      |  64 +++
 .../language/LanguageDetectionParameters.java      |  37 ++
 .../language/LanguageDetectionProgram.java         |  39 ++
 .../processor/sentiment/SentimentDetection.java    |  21 +
 .../sentiment/SentimentDetectionController.java    |  21 +
 .../sentiment/SentimentDetectionParameters.java    |  21 +
 .../sentiment/SentimentDetectionProgram.java       |  21 +
 .../textmining/flink/processor/wordcount/Word.java |  54 ++
 .../processor/wordcount/WordCountController.java   |  73 +++
 .../processor/wordcount/WordCountParameters.java   |  43 ++
 .../processor/wordcount/WordCountProgram.java      |  48 ++
 .../flink/processor/wordcount/WordSplitter.java    |  43 ++
 .../processor/wordcount/WordToEventConverter.java  |  33 ++
 .../flink/AbstractTextMiningProgram.java           |  42 --
 .../textmining/flink/TextMiningFlinkInit.java      |  45 --
 .../textmining/flink/config/ConfigKeys.java        |  30 --
 .../flink/config/TextMiningFlinkConfig.java        |  98 ----
 .../flink/processor/entity/EntityExtraction.java   |  60 ---
 .../processor/entity/EntityExtractionModel.java    |  42 --
 .../processor/language/LanguageDetection.java      |  75 ---
 .../language/LanguageDetectionController.java      |  64 ---
 .../language/LanguageDetectionParameters.java      |  37 --
 .../language/LanguageDetectionProgram.java         |  39 --
 .../processor/sentiment/SentimentDetection.java    |  21 -
 .../sentiment/SentimentDetectionController.java    |  21 -
 .../sentiment/SentimentDetectionParameters.java    |  21 -
 .../sentiment/SentimentDetectionProgram.java       |  21 -
 .../textmining/flink/processor/wordcount/Word.java |  54 --
 .../processor/wordcount/WordCountController.java   |  73 ---
 .../processor/wordcount/WordCountParameters.java   |  43 --
 .../processor/wordcount/WordCountProgram.java      |  48 --
 .../flink/processor/wordcount/WordSplitter.java    |  43 --
 .../processor/wordcount/WordToEventConverter.java  |  33 --
 .../documentation.md                               |   0
 .../strings.en                                     |   7 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  10 +
 .../strings.en                                     |   7 -
 .../strings.en                                     |  10 -
 streampipes-processors-text-mining-jvm/pom.xml     |  22 +-
 .../textmining/jvm/TextMiningJvmInit.java          |  58 +++
 .../textmining/jvm/config/ConfigKeys.java          |  28 +
 .../textmining/jvm/config/TextMiningJvmConfig.java |  92 ++++
 .../textmining/jvm/processor/TextMiningUtil.java   |  49 ++
 .../textmining/jvm/processor/chunker/Chunker.java  |  87 ++++
 .../jvm/processor/chunker/ChunkerController.java   |  79 +++
 .../jvm/processor/chunker/ChunkerParameters.java   |  42 ++
 .../jvm/processor/language/LanguageDetection.java  |  72 +++
 .../language/LanguageDetectionController.java      |  72 +++
 .../language/LanguageDetectionParameters.java      |  36 ++
 .../jvm/processor/namefinder/NameFinder.java       |  90 ++++
 .../processor/namefinder/NameFinderController.java |  95 ++++
 .../processor/namefinder/NameFinderParameters.java |  41 ++
 .../jvm/processor/partofspeech/PartOfSpeech.java   |  74 +++
 .../partofspeech/PartOfSpeechController.java       |  73 +++
 .../partofspeech/PartOfSpeechParameters.java       |  36 ++
 .../sentencedetection/SentenceDetection.java       |  72 +++
 .../SentenceDetectionController.java               |  62 +++
 .../SentenceDetectionParameters.java               |  36 ++
 .../jvm/processor/tokenizer/Tokenizer.java         |  69 +++
 .../processor/tokenizer/TokenizerController.java   |  66 +++
 .../processor/tokenizer/TokenizerParameters.java   |  36 ++
 .../textmining/jvm/TextMiningJvmInit.java          |  58 ---
 .../textmining/jvm/config/ConfigKeys.java          |  28 -
 .../textmining/jvm/config/TextMiningJvmConfig.java |  92 ----
 .../textmining/jvm/processor/TextMiningUtil.java   |  49 --
 .../textmining/jvm/processor/chunker/Chunker.java  |  87 ----
 .../jvm/processor/chunker/ChunkerController.java   |  79 ---
 .../jvm/processor/chunker/ChunkerParameters.java   |  42 --
 .../jvm/processor/language/LanguageDetection.java  |  72 ---
 .../language/LanguageDetectionController.java      |  72 ---
 .../language/LanguageDetectionParameters.java      |  36 --
 .../jvm/processor/namefinder/NameFinder.java       |  90 ----
 .../processor/namefinder/NameFinderController.java |  95 ----
 .../processor/namefinder/NameFinderParameters.java |  41 --
 .../jvm/processor/partofspeech/PartOfSpeech.java   |  74 ---
 .../partofspeech/PartOfSpeechController.java       |  73 ---
 .../partofspeech/PartOfSpeechParameters.java       |  36 --
 .../sentencedetection/SentenceDetection.java       |  72 ---
 .../SentenceDetectionController.java               |  62 ---
 .../SentenceDetectionParameters.java               |  36 --
 .../jvm/processor/tokenizer/Tokenizer.java         |  69 ---
 .../processor/tokenizer/TokenizerController.java   |  66 ---
 .../processor/tokenizer/TokenizerParameters.java   |  36 --
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  14 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  11 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  11 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  11 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   5 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   8 +
 .../strings.en                                     |  14 -
 .../strings.en                                     |  11 -
 .../strings.en                                     |  11 -
 .../strings.en                                     |  11 -
 .../strings.en                                     |   5 -
 .../strings.en                                     |   8 -
 .../pom.xml                                        |  26 +-
 .../flink/AbstractFlinkTransformationProgram.java  |  42 ++
 .../flink/TransformationFlinkInit.java             |  59 +++
 .../transformation/flink/config/ConfigKeys.java    |  30 ++
 .../flink/config/TransformationFlinkConfig.java    |  97 ++++
 .../boilerplate/BoilerplateController.java         |  91 ++++
 .../boilerplate/BoilerplateParameters.java         |  48 ++
 .../processor/boilerplate/BoilerplateProgram.java  |  41 ++
 .../processor/boilerplate/BoilerplateRemover.java  |  92 ++++
 .../flink/processor/boilerplate/ExtractorMode.java |  28 +
 .../flink/processor/boilerplate/OutputMode.java    |  25 +
 .../flink/processor/converter/FieldConverter.java  |  57 ++
 .../converter/FieldConverterController.java        |  82 +++
 .../converter/FieldConverterParameters.java        |  42 ++
 .../processor/converter/FieldConverterProgram.java |  38 ++
 .../flink/processor/hasher/FieldHasher.java        |  45 ++
 .../processor/hasher/FieldHasherController.java    |  69 +++
 .../processor/hasher/FieldHasherParameters.java    |  44 ++
 .../flink/processor/hasher/FieldHasherProgram.java |  45 ++
 .../processor/hasher/algorithm/HashAlgorithm.java  |  26 +
 .../hasher/algorithm/HashAlgorithmType.java        |  33 ++
 .../hasher/algorithm/Md5HashAlgorithm.java         |  32 ++
 .../hasher/algorithm/Sha1HashAlgorithm.java        |  32 ++
 .../hasher/algorithm/Sha2HashAlgorithm.java        |  32 ++
 .../flink/processor/mapper/FieldMapper.java        |  56 ++
 .../processor/mapper/FieldMapperController.java    |  88 ++++
 .../processor/mapper/FieldMapperParameters.java    |  43 ++
 .../flink/processor/mapper/FieldMapperProgram.java |  39 ++
 .../MeasurementUnitConverter.java                  |  57 ++
 .../MeasurementUnitConverterController.java        | 126 +++++
 .../MeasurementUnitConverterParameters.java        |  51 ++
 .../MeasurementUnitConverterProgram.java           |  42 ++
 .../flink/processor/rename/FieldRenamer.java       |  47 ++
 .../processor/rename/FieldRenamerController.java   |  67 +++
 .../processor/rename/FieldRenamerParameters.java   |  52 ++
 .../processor/rename/FieldRenamerProgram.java      |  41 ++
 .../flink/AbstractFlinkTransformationProgram.java  |  42 --
 .../flink/TransformationFlinkInit.java             |  59 ---
 .../transformation/flink/config/ConfigKeys.java    |  30 --
 .../flink/config/TransformationFlinkConfig.java    |  97 ----
 .../boilerplate/BoilerplateController.java         |  91 ----
 .../boilerplate/BoilerplateParameters.java         |  48 --
 .../processor/boilerplate/BoilerplateProgram.java  |  41 --
 .../processor/boilerplate/BoilerplateRemover.java  |  92 ----
 .../flink/processor/boilerplate/ExtractorMode.java |  28 -
 .../flink/processor/boilerplate/OutputMode.java    |  25 -
 .../flink/processor/converter/FieldConverter.java  |  57 --
 .../converter/FieldConverterController.java        |  82 ---
 .../converter/FieldConverterParameters.java        |  42 --
 .../processor/converter/FieldConverterProgram.java |  40 --
 .../flink/processor/hasher/FieldHasher.java        |  45 --
 .../processor/hasher/FieldHasherController.java    |  69 ---
 .../processor/hasher/FieldHasherParameters.java    |  44 --
 .../flink/processor/hasher/FieldHasherProgram.java |  46 --
 .../processor/hasher/algorithm/HashAlgorithm.java  |  26 -
 .../hasher/algorithm/HashAlgorithmType.java        |  33 --
 .../hasher/algorithm/Md5HashAlgorithm.java         |  32 --
 .../hasher/algorithm/Sha1HashAlgorithm.java        |  32 --
 .../hasher/algorithm/Sha2HashAlgorithm.java        |  32 --
 .../flink/processor/mapper/FieldMapper.java        |  56 --
 .../processor/mapper/FieldMapperController.java    |  88 ----
 .../processor/mapper/FieldMapperParameters.java    |  43 --
 .../flink/processor/mapper/FieldMapperProgram.java |  39 --
 .../MeasurementUnitConverter.java                  |  57 --
 .../MeasurementUnitConverterController.java        | 126 -----
 .../MeasurementUnitConverterParameters.java        |  51 --
 .../MeasurementUnitConverterProgram.java           |  42 --
 .../flink/processor/rename/FieldRenamer.java       |  47 --
 .../processor/rename/FieldRenamerController.java   |  67 ---
 .../processor/rename/FieldRenamerParameters.java   |  52 --
 .../processor/rename/FieldRenamerProgram.java      |  43 --
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   8 +
 .../documentation.md                               |   0
 .../strings.en                                     |   8 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   8 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   8 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   8 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  11 +
 .../strings.en                                     |   8 -
 .../strings.en                                     |   8 -
 .../strings.en                                     |   8 -
 .../strings.en                                     |   8 -
 .../strings.en                                     |   8 -
 .../strings.en                                     |  11 -
 .../processor/converter/TestConverterProgram.java  |  86 +++
 .../flink/processor/hasher/TestFieldHasher.java    | 120 +++++
 .../hasher/TestFieldHasherController.java          |  37 ++
 .../processor/hasher/TestFieldHasherProgram.java   |  76 +++
 .../processor/hasher/TestFieldHasherUtils.java     |  44 ++
 .../flink/processor/rename/TestRenameProgram.java  |  93 ++++
 .../transformation/flink/utils/DummyCollector.java |  47 ++
 .../processor/converter/TestConverterProgram.java  |  86 ---
 .../flink/processor/hasher/TestFieldHasher.java    | 121 -----
 .../hasher/TestFieldHasherController.java          |  37 --
 .../processor/hasher/TestFieldHasherProgram.java   |  76 ---
 .../processor/hasher/TestFieldHasherUtils.java     |  44 --
 .../flink/processor/rename/TestRenameProgram.java  |  93 ----
 .../transformation/flink/utils/DummyCollector.java |  47 --
 streampipes-processors-transformation-jvm/pom.xml  |  24 +-
 .../transformation/jvm/TransformationJvmInit.java  |  72 +++
 .../transformation/jvm/config/ConfigKeys.java      |  27 +
 .../jvm/config/TransformationJvmConfig.java        |  89 ++++
 .../jvm/processor/array/count/CountArray.java      |  58 +++
 .../array/count/CountArrayController.java          |  65 +++
 .../array/count/CountArrayParameters.java          |  37 ++
 .../jvm/processor/array/split/SplitArray.java      |  85 +++
 .../array/split/SplitArrayController.java          |  91 ++++
 .../array/split/SplitArrayParameters.java          |  43 ++
 .../booloperator/counter/BooleanCounter.java       |  93 ++++
 .../counter/BooleanCounterController.java          |  79 +++
 .../counter/BooleanCounterParameters.java          |  48 ++
 .../booloperator/inverter/BooleanInverter.java     |  55 ++
 .../inverter/BooleanInverterController.java        |  59 +++
 .../inverter/BooleanInverterParameters.java        |  35 ++
 .../timekeeping/BooleanTimekeeping.java            |  95 ++++
 .../timekeeping/BooleanTimekeepingController.java  |  89 ++++
 .../timekeeping/BooleanTimekeepingParameters.java  |  47 ++
 .../processor/booloperator/timer/BooleanTimer.java |  85 +++
 .../booloperator/timer/BooleanTimerController.java |  90 ++++
 .../booloperator/timer/BooleanTimerParameters.java |  47 ++
 .../csvmetadata/CsvMetadataEnrichment.java         | 121 +++++
 .../CsvMetadataEnrichmentController.java           | 175 +++++++
 .../CsvMetadataEnrichmentParameters.java           |  58 +++
 .../csvmetadata/CsvMetadataEnrichmentUtils.java    |  60 +++
 .../jvm/processor/task/TaskDuration.java           |  78 +++
 .../jvm/processor/task/TaskDurationController.java |  85 +++
 .../jvm/processor/task/TaskDurationParameters.java |  48 ++
 .../processor/timestampextractor/OutputFields.java |  46 ++
 .../timestampextractor/TimestampExtractor.java     | 102 ++++
 .../TimestampExtractorController.java              | 110 ++++
 .../TimestampExtractorParameters.java              |  45 ++
 .../transformtoboolean/TransformToBoolean.java     |  79 +++
 .../TransformToBooleanController.java              | 107 ++++
 .../TransformToBooleanParameters.java              |  36 ++
 .../value/change/ChangedValueDetection.java        |  61 +++
 .../change/ChangedValueDetectionController.java    |  64 +++
 .../change/ChangedValueDetectionParameters.java    |  41 ++
 .../value/duration/CalculateDuration.java          |  71 +++
 .../duration/CalculateDurationController.java      |  86 +++
 .../duration/CalculateDurationParameters.java      |  57 ++
 .../transformation/jvm/TransformationJvmInit.java  |  72 ---
 .../transformation/jvm/config/ConfigKeys.java      |  27 -
 .../jvm/config/TransformationJvmConfig.java        |  89 ----
 .../jvm/processor/array/count/CountArray.java      |  58 ---
 .../array/count/CountArrayController.java          |  65 ---
 .../array/count/CountArrayParameters.java          |  37 --
 .../jvm/processor/array/split/SplitArray.java      |  85 ---
 .../array/split/SplitArrayController.java          |  91 ----
 .../array/split/SplitArrayParameters.java          |  43 --
 .../booloperator/counter/BooleanCounter.java       |  93 ----
 .../counter/BooleanCounterController.java          |  79 ---
 .../counter/BooleanCounterParameters.java          |  48 --
 .../booloperator/inverter/BooleanInverter.java     |  55 --
 .../inverter/BooleanInverterController.java        |  59 ---
 .../inverter/BooleanInverterParameters.java        |  35 --
 .../timekeeping/BooleanTimekeeping.java            |  96 ----
 .../timekeeping/BooleanTimekeepingController.java  |  89 ----
 .../timekeeping/BooleanTimekeepingParameters.java  |  47 --
 .../processor/booloperator/timer/BooleanTimer.java |  85 ---
 .../booloperator/timer/BooleanTimerController.java |  90 ----
 .../booloperator/timer/BooleanTimerParameters.java |  47 --
 .../csvmetadata/CsvMetadataEnrichment.java         | 121 -----
 .../CsvMetadataEnrichmentController.java           | 175 -------
 .../CsvMetadataEnrichmentParameters.java           |  58 ---
 .../csvmetadata/CsvMetadataEnrichmentUtils.java    |  60 ---
 .../jvm/processor/task/TaskDuration.java           |  78 ---
 .../jvm/processor/task/TaskDurationController.java |  85 ---
 .../jvm/processor/task/TaskDurationParameters.java |  48 --
 .../processor/timestampextractor/OutputFields.java |  46 --
 .../timestampextractor/TimestampExtractor.java     | 102 ----
 .../TimestampExtractorController.java              | 110 ----
 .../TimestampExtractorParameters.java              |  45 --
 .../transformtoboolean/TransformToBoolean.java     |  79 ---
 .../TransformToBooleanController.java              | 107 ----
 .../TransformToBooleanParameters.java              |  36 --
 .../value/change/ChangedValueDetection.java        |  61 ---
 .../change/ChangedValueDetectionController.java    |  64 ---
 .../change/ChangedValueDetectionParameters.java    |  41 --
 .../value/duration/CalculateDuration.java          |  71 ---
 .../duration/CalculateDurationController.java      |  86 ---
 .../duration/CalculateDurationParameters.java      |  57 --
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   8 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   5 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  14 +
 .../time_measure_example.png                       | Bin
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  10 +
 .../documentation.md                               |   0
 .../strings.en                                     |   5 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   5 +
 .../documentation.md                               |   0
 .../strings.en                                     |  15 +
 .../documentation.md                               |   0
 .../strings.en                                     |  11 +
 .../documentation.md                               |   0
 .../strings.en                                     |   8 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   8 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  17 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   5 +
 .../strings.en                                     |   8 -
 .../strings.en                                     |   5 -
 .../strings.en                                     |  14 -
 .../strings.en                                     |  10 -
 .../strings.en                                     |   5 -
 .../strings.en                                     |   5 -
 .../strings.en                                     |  15 -
 .../strings.en                                     |  11 -
 .../strings.en                                     |   8 -
 .../strings.en                                     |   8 -
 .../strings.en                                     |  17 -
 .../strings.en                                     |   5 -
 streampipes-sinks-brokers-jvm/pom.xml              |  24 +-
 .../sinks/brokers/jvm/BrokersJvmInit.java          |  59 +++
 .../sinks/brokers/jvm/bufferrest/BufferRest.java   |  84 +++
 .../jvm/bufferrest/BufferRestController.java       |  71 +++
 .../jvm/bufferrest/BufferRestParameters.java       |  50 ++
 .../jvm/bufferrest/buffer/BufferListener.java      |  23 +
 .../jvm/bufferrest/buffer/MessageBuffer.java       |  80 +++
 .../sinks/brokers/jvm/config/BrokersJvmConfig.java |  89 ++++
 .../sinks/brokers/jvm/config/ConfigKeys.java       |  27 +
 .../sinks/brokers/jvm/jms/JmsController.java       |  73 +++
 .../sinks/brokers/jvm/jms/JmsParameters.java       |  48 ++
 .../sinks/brokers/jvm/jms/JmsPublisher.java        |  64 +++
 .../sinks/brokers/jvm/kafka/KafkaController.java   |  73 +++
 .../sinks/brokers/jvm/kafka/KafkaParameters.java   |  48 ++
 .../sinks/brokers/jvm/kafka/KafkaPublisher.java    |  59 +++
 .../sinks/brokers/jvm/pulsar/Pulsar.java           |  85 +++
 .../sinks/brokers/jvm/pulsar/PulsarController.java |  66 +++
 .../sinks/brokers/jvm/pulsar/PulsarParameters.java |  48 ++
 .../brokers/jvm/rabbitmq/RabbitMqConsumer.java     |  65 +++
 .../brokers/jvm/rabbitmq/RabbitMqController.java   |  90 ++++
 .../brokers/jvm/rabbitmq/RabbitMqParameters.java   |  68 +++
 .../brokers/jvm/rabbitmq/RabbitMqPublisher.java    | 118 +++++
 .../sinks/brokers/jvm/rest/RestController.java     |  61 +++
 .../sinks/brokers/jvm/rest/RestParameters.java     |  36 ++
 .../sinks/brokers/jvm/rest/RestPublisher.java      |  70 +++
 .../sinks/brokers/jvm/BrokersJvmInit.java          |  59 ---
 .../sinks/brokers/jvm/bufferrest/BufferRest.java   |  84 ---
 .../jvm/bufferrest/BufferRestController.java       |  71 ---
 .../jvm/bufferrest/BufferRestParameters.java       |  50 --
 .../jvm/bufferrest/buffer/BufferListener.java      |  23 -
 .../jvm/bufferrest/buffer/MessageBuffer.java       |  80 ---
 .../sinks/brokers/jvm/config/BrokersJvmConfig.java |  89 ----
 .../sinks/brokers/jvm/config/ConfigKeys.java       |  27 -
 .../sinks/brokers/jvm/jms/JmsController.java       |  73 ---
 .../sinks/brokers/jvm/jms/JmsParameters.java       |  48 --
 .../sinks/brokers/jvm/jms/JmsPublisher.java        |  64 ---
 .../sinks/brokers/jvm/kafka/KafkaController.java   |  73 ---
 .../sinks/brokers/jvm/kafka/KafkaParameters.java   |  48 --
 .../sinks/brokers/jvm/kafka/KafkaPublisher.java    |  59 ---
 .../sinks/brokers/jvm/pulsar/Pulsar.java           |  85 ---
 .../sinks/brokers/jvm/pulsar/PulsarController.java |  66 ---
 .../sinks/brokers/jvm/pulsar/PulsarParameters.java |  48 --
 .../brokers/jvm/rabbitmq/RabbitMqConsumer.java     |  65 ---
 .../brokers/jvm/rabbitmq/RabbitMqController.java   |  90 ----
 .../brokers/jvm/rabbitmq/RabbitMqParameters.java   |  68 ---
 .../brokers/jvm/rabbitmq/RabbitMqPublisher.java    | 118 -----
 .../sinks/brokers/jvm/rest/RestController.java     |  61 ---
 .../sinks/brokers/jvm/rest/RestParameters.java     |  36 --
 .../sinks/brokers/jvm/rest/RestPublisher.java      |  70 ---
 .../documentation.md                               |   0
 .../strings.en                                     |   8 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   8 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   8 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  11 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   8 +
 .../documentation.md                               |   0
 .../strings.en                                     |   5 +
 .../strings.en                                     |   8 -
 .../strings.en                                     |   8 -
 .../strings.en                                     |   8 -
 .../strings.en                                     |  11 -
 .../strings.en                                     |   8 -
 .../strings.en                                     |   5 -
 streampipes-sinks-databases-flink/pom.xml          |  22 +-
 .../sinks/databases/flink/DatabasesFlinkInit.java  |  49 ++
 .../sinks/databases/flink/config/ConfigKeys.java   |  33 ++
 .../flink/config/DatabasesFlinkConfig.java         | 112 ++++
 .../elasticsearch/ElasticSearchController.java     |  68 +++
 .../elasticsearch/ElasticSearchParameters.java     |  42 ++
 .../flink/elasticsearch/ElasticSearchProgram.java  |  85 +++
 .../ElasticsearchIndexRequestBuilder.java          |  53 ++
 .../elastic/ActionRequestFailureHandler.java       |  78 +++
 .../elastic/BulkProcessorIndexer.java              |  55 ++
 .../elastic/Elasticsearch6ApiCallBridge.java       | 116 +++++
 .../elastic/ElasticsearchApiCallBridge.java        |  94 ++++
 .../elasticsearch/elastic/ElasticsearchSink.java   |  90 ++++
 .../elastic/ElasticsearchSinkBase.java             | 437 ++++++++++++++++
 .../elastic/ElasticsearchSinkFunction.java         |  71 +++
 .../elasticsearch/elastic/NoOpFailureHandler.java  |  38 ++
 .../elasticsearch/elastic/RequestIndexer.java      |  37 ++
 .../sinks/databases/flink/DatabasesFlinkInit.java  |  49 --
 .../sinks/databases/flink/config/ConfigKeys.java   |  33 --
 .../flink/config/DatabasesFlinkConfig.java         | 112 ----
 .../elasticsearch/ElasticSearchController.java     |  68 ---
 .../elasticsearch/ElasticSearchParameters.java     |  42 --
 .../flink/elasticsearch/ElasticSearchProgram.java  |  85 ---
 .../ElasticsearchIndexRequestBuilder.java          |  53 --
 .../elastic/ActionRequestFailureHandler.java       |  78 ---
 .../elastic/BulkProcessorIndexer.java              |  55 --
 .../elastic/Elasticsearch6ApiCallBridge.java       | 116 -----
 .../elastic/ElasticsearchApiCallBridge.java        |  94 ----
 .../elasticsearch/elastic/ElasticsearchSink.java   |  90 ----
 .../elastic/ElasticsearchSinkBase.java             | 437 ----------------
 .../elastic/ElasticsearchSinkFunction.java         |  71 ---
 .../elasticsearch/elastic/NoOpFailureHandler.java  |  38 --
 .../elasticsearch/elastic/RequestIndexer.java      |  37 --
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   8 +
 .../strings.en                                     |   8 -
 streampipes-sinks-databases-jvm/pom.xml            |  24 +-
 .../sinks/databases/jvm/DatabasesJvmInit.java      |  57 ++
 .../sinks/databases/jvm/config/ConfigKeys.java     |  27 +
 .../databases/jvm/config/DatabasesJvmConfig.java   |  89 ++++
 .../sinks/databases/jvm/couchdb/CouchDb.java       |  58 +++
 .../databases/jvm/couchdb/CouchDbController.java   |  79 +++
 .../databases/jvm/couchdb/CouchDbParameters.java   |  60 +++
 .../sinks/databases/jvm/influxdb/InfluxDb.java     |  64 +++
 .../databases/jvm/influxdb/InfluxDbClient.java     | 195 +++++++
 .../databases/jvm/influxdb/InfluxDbController.java |  96 ++++
 .../databases/jvm/influxdb/InfluxDbParameters.java |  94 ++++
 .../sinks/databases/jvm/iotdb/IotDb.java           | 197 +++++++
 .../sinks/databases/jvm/iotdb/IotDbController.java |  85 +++
 .../sinks/databases/jvm/iotdb/IotDbParameters.java |  72 +++
 .../sinks/databases/jvm/jdbcclient/JdbcClient.java | 574 +++++++++++++++++++++
 .../sinks/databases/jvm/opcua/OpcUa.java           | 157 ++++++
 .../sinks/databases/jvm/opcua/OpcUaParameters.java |  99 ++++
 .../sinks/databases/jvm/opcua/UpcUaController.java |  90 ++++
 .../sinks/databases/jvm/postgresql/PostgreSql.java |  68 +++
 .../jvm/postgresql/PostgreSqlController.java       |  82 +++
 .../jvm/postgresql/PostgreSqlParameters.java       |  66 +++
 .../sinks/databases/jvm/DatabasesJvmInit.java      |  57 --
 .../sinks/databases/jvm/config/ConfigKeys.java     |  27 -
 .../databases/jvm/config/DatabasesJvmConfig.java   |  89 ----
 .../sinks/databases/jvm/couchdb/CouchDb.java       |  58 ---
 .../databases/jvm/couchdb/CouchDbController.java   |  79 ---
 .../databases/jvm/couchdb/CouchDbParameters.java   |  60 ---
 .../sinks/databases/jvm/influxdb/InfluxDb.java     |  65 ---
 .../databases/jvm/influxdb/InfluxDbClient.java     | 195 -------
 .../databases/jvm/influxdb/InfluxDbController.java |  96 ----
 .../databases/jvm/influxdb/InfluxDbParameters.java |  94 ----
 .../sinks/databases/jvm/iotdb/IotDb.java           | 197 -------
 .../sinks/databases/jvm/iotdb/IotDbController.java |  85 ---
 .../sinks/databases/jvm/iotdb/IotDbParameters.java |  72 ---
 .../sinks/databases/jvm/jdbcclient/JdbcClient.java | 574 ---------------------
 .../sinks/databases/jvm/opcua/OpcUa.java           | 158 ------
 .../sinks/databases/jvm/opcua/OpcUaParameters.java |  99 ----
 .../sinks/databases/jvm/opcua/UpcUaController.java |  90 ----
 .../sinks/databases/jvm/postgresql/PostgreSql.java |  68 ---
 .../jvm/postgresql/PostgreSqlController.java       |  82 ---
 .../jvm/postgresql/PostgreSqlParameters.java       |  66 ---
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  11 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  29 ++
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  20 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  17 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  21 +
 .../strings.en                                     |  11 -
 .../strings.en                                     |  29 --
 .../strings.en                                     |  20 -
 .../strings.en                                     |  17 -
 .../strings.en                                     |  21 -
 streampipes-sinks-internal-jvm/pom.xml             |  22 +-
 .../sinks/internal/jvm/SinksInternalJvmInit.java   |  53 ++
 .../sinks/internal/jvm/config/ConfigKeys.java      |  41 ++
 .../jvm/config/SinksInternalJvmConfig.java         | 160 ++++++
 .../sinks/internal/jvm/dashboard/Dashboard.java    |  98 ++++
 .../jvm/dashboard/DashboardController.java         |  60 +++
 .../internal/jvm/dashboard/DashboardModel.java     |  71 +++
 .../jvm/dashboard/DashboardParameters.java         |  56 ++
 .../sinks/internal/jvm/datalake/DataLake.java      | 104 ++++
 .../internal/jvm/datalake/DataLakeController.java  |  91 ++++
 .../internal/jvm/datalake/DataLakeParameters.java  | 106 ++++
 .../internal/jvm/datalake/InfluxDbClient.java      | 211 ++++++++
 .../jvm/notification/NotificationController.java   |  66 +++
 .../jvm/notification/NotificationParameters.java   |  42 ++
 .../jvm/notification/NotificationProducer.java     |  68 +++
 .../sinks/internal/jvm/SinksInternalJvmInit.java   |  53 --
 .../sinks/internal/jvm/config/ConfigKeys.java      |  41 --
 .../jvm/config/SinksInternalJvmConfig.java         | 160 ------
 .../sinks/internal/jvm/dashboard/Dashboard.java    |  98 ----
 .../jvm/dashboard/DashboardController.java         |  60 ---
 .../internal/jvm/dashboard/DashboardModel.java     |  71 ---
 .../jvm/dashboard/DashboardParameters.java         |  56 --
 .../sinks/internal/jvm/datalake/DataLake.java      | 105 ----
 .../internal/jvm/datalake/DataLakeController.java  |  91 ----
 .../internal/jvm/datalake/DataLakeParameters.java  | 106 ----
 .../internal/jvm/datalake/InfluxDbClient.java      | 211 --------
 .../jvm/notification/NotificationController.java   |  66 ---
 .../jvm/notification/NotificationParameters.java   |  42 --
 .../jvm/notification/NotificationProducer.java     |  68 ---
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   5 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   8 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   8 +
 .../strings.en                                     |   5 -
 .../strings.en                                     |   8 -
 .../strings.en                                     |   8 -
 streampipes-sinks-notifications-jvm/pom.xml        |  22 +-
 .../jvm/SinksNotificationsJvmInit.java             |  53 ++
 .../sinks/notifications/jvm/config/ConfigKeys.java |  41 ++
 .../jvm/config/SinksNotificationsJvmConfig.java    | 131 +++++
 .../notifications/jvm/email/EmailController.java   |  69 +++
 .../notifications/jvm/email/EmailParameters.java   |  48 ++
 .../notifications/jvm/email/EmailPublisher.java    | 113 ++++
 .../jvm/onesignal/OneSignalController.java         |  68 +++
 .../jvm/onesignal/OneSignalParameters.java         |  45 ++
 .../jvm/onesignal/OneSignalProducer.java           |  80 +++
 .../notifications/jvm/slack/SlackNotification.java |  57 ++
 .../jvm/slack/SlackNotificationController.java     | 112 ++++
 .../jvm/slack/SlackNotificationParameters.java     |  63 +++
 .../jvm/SinksNotificationsJvmInit.java             |  53 --
 .../sinks/notifications/jvm/config/ConfigKeys.java |  41 --
 .../jvm/config/SinksNotificationsJvmConfig.java    | 131 -----
 .../notifications/jvm/email/EmailController.java   |  69 ---
 .../notifications/jvm/email/EmailParameters.java   |  48 --
 .../notifications/jvm/email/EmailPublisher.java    | 113 ----
 .../jvm/onesignal/OneSignalController.java         |  68 ---
 .../jvm/onesignal/OneSignalParameters.java         |  45 --
 .../jvm/onesignal/OneSignalProducer.java           |  80 ---
 .../notifications/jvm/slack/SlackNotification.java |  57 --
 .../jvm/slack/SlackNotificationController.java     | 112 ----
 .../jvm/slack/SlackNotificationParameters.java     |  63 ---
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  11 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  11 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |  11 +
 .../strings.en                                     |  11 -
 .../strings.en                                     |  11 -
 .../strings.en                                     |  11 -
 streampipes-sources-vehicle-simulator/pom.xml      |  26 +-
 .../vehicle/simulator/VehicleSimulatorInit.java    |  33 ++
 .../vehicle/simulator/config/ConfigKeys.java       |  30 ++
 .../simulator/config/VehicleSimulatorConfig.java   |  97 ++++
 .../simulator/simulator/VehicleDataSimulator.java  |  69 +++
 .../vehicle/simulator/vehicle/VehicleSource.java   |  42 ++
 .../simulator/vehicle/streams/VehicleStream.java   |  59 +++
 .../vehicle/simulator/VehicleSimulatorInit.java    |  33 --
 .../vehicle/simulator/config/ConfigKeys.java       |  30 --
 .../simulator/config/VehicleSimulatorConfig.java   |  97 ----
 .../simulator/simulator/VehicleDataSimulator.java  |  69 ---
 .../vehicle/simulator/vehicle/VehicleSource.java   |  42 --
 .../simulator/vehicle/streams/VehicleStream.java   |  59 ---
 .../main/resources/streampipesVehicleWorkflow.json |   2 +-
 streampipes-sources-watertank-simulator/pom.xml    |  28 +-
 .../simulator/WatertankSimulatorInit.java          |  34 ++
 .../watertank/simulator/config/ConfigKeys.java     |  30 ++
 .../simulator/config/WatertankSimulatorConfig.java |  97 ++++
 .../simulator/utils/WatertankDataSimulator.java    |  76 +++
 .../simulator/vocabulary/WaterTankVocabulary.java  |  38 ++
 .../simulator/watertank/WaterTankSource.java       |  45 ++
 .../watertank/streams/FlowRate1Stream.java         |  82 +++
 .../watertank/streams/FlowRate2Stream.java         |  93 ++++
 .../watertank/streams/PressureTankStream.java      |  65 +++
 .../watertank/streams/WaterLevel1Stream.java       |  84 +++
 .../watertank/streams/WaterLevel2Stream.java       |  70 +++
 .../simulator/WatertankSimulatorInit.java          |  34 --
 .../watertank/simulator/config/ConfigKeys.java     |  30 --
 .../simulator/config/WatertankSimulatorConfig.java |  97 ----
 .../simulator/utils/WatertankDataSimulator.java    |  76 ---
 .../simulator/vocabulary/WaterTankVocabulary.java  |  38 --
 .../simulator/watertank/WaterTankSource.java       |  45 --
 .../watertank/streams/FlowRate1Stream.java         |  82 ---
 .../watertank/streams/FlowRate2Stream.java         |  93 ----
 .../watertank/streams/PressureTankStream.java      |  65 ---
 .../watertank/streams/WaterLevel1Stream.java       |  84 ---
 .../watertank/streams/WaterLevel2Stream.java       |  70 ---
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   2 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   2 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   2 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   2 +
 .../documentation.md                               |   0
 .../icon.png                                       | Bin
 .../strings.en                                     |   2 +
 .../strings.en                                     |   2 -
 .../strings.en                                     |   2 -
 .../strings.en                                     |   2 -
 .../strings.en                                     |   2 -
 .../strings.en                                     |   2 -
 .../streampipesFestoFlowRateWorkflow.json          |   2 +-
 .../streampipesFestoLevel101Workflow.json          |   2 +-
 .../streampipesFestoLevel102Workflow.json          |   2 +-
 .../streampipesFestoPressureWorkflow.json          |   2 +-
 .../streampipesSiemensFlowRateWorkflow.json        |   2 +-
 1430 files changed, 41701 insertions(+), 41721 deletions(-)

diff --git a/.spignore b/.spignore
index 2dc8caa..09bf0f8 100644
--- a/.spignore
+++ b/.spignore
@@ -1,7 +1,7 @@
-org.streampipes.processors.aggregation.flink.count
-org.streampipes.processor.imageclassification.jvm.image-cropper
-org.streampipes.processors.pattern-detection.flink.sequence
-org.streampipes.processors.pattern-detection.flink.absence
-org.streampipes.processors.pattern-detection.flink.and
-org.streampipes.processors.pattern-detection.flink.increase
-org.streampipes.processors.statistics.flink.statistics-summary
\ No newline at end of file
+org.apache.streampipes.processors.aggregation.flink.count
+org.apache.streampipes.processor.imageclassification.jvm.image-cropper
+org.apache.streampipes.processors.pattern-detection.flink.sequence
+org.apache.streampipes.processors.pattern-detection.flink.absence
+org.apache.streampipes.processors.pattern-detection.flink.and
+org.apache.streampipes.processors.pattern-detection.flink.increase
+org.apache.streampipes.processors.statistics.flink.statistics-summary
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index ab77bc3..17d50b0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
-        <groupId>org.streampipes</groupId>
+        <groupId>org.apache.streampipes</groupId>
         <artifactId>streampipes-parent</artifactId>
         <version>0.65.1-SNAPSHOT</version>
     </parent>
@@ -91,77 +91,77 @@
         <dependencies>
             <!-- StreamPipes dependencies -->
             <dependency>
-                <groupId>org.streampipes</groupId>
+                <groupId>org.apache.streampipes</groupId>
                 <artifactId>streampipes-commons</artifactId>
                 <version>${streampipes.version}</version>
             </dependency>
             <dependency>
-                <groupId>org.streampipes</groupId>
+                <groupId>org.apache.streampipes</groupId>
                 <artifactId>streampipes-config</artifactId>
                 <version>${streampipes.version}</version>
             </dependency>
             <dependency>
-                <groupId>org.streampipes</groupId>
+                <groupId>org.apache.streampipes</groupId>
                 <artifactId>streampipes-container-standalone</artifactId>
                 <version>${streampipes.version}</version>
             </dependency>
             <dependency>
-                <groupId>org.streampipes</groupId>
+                <groupId>org.apache.streampipes</groupId>
                 <artifactId>streampipes-dataformat-json</artifactId>
                 <version>${streampipes.version}</version>
             </dependency>
             <dependency>
-                <groupId>org.streampipes</groupId>
+                <groupId>org.apache.streampipes</groupId>
                 <artifactId>streampipes-dataformat-cbor</artifactId>
                 <version>${streampipes.version}</version>
             </dependency>
             <dependency>
-                <groupId>org.streampipes</groupId>
+                <groupId>org.apache.streampipes</groupId>
                 <artifactId>streampipes-dataformat-smile</artifactId>
                 <version>${streampipes.version}</version>
             </dependency>
             <dependency>
-                <groupId>org.streampipes</groupId>
+                <groupId>org.apache.streampipes</groupId>
                 <artifactId>streampipes-dataformat-fst</artifactId>
                 <version>${streampipes.version}</version>
             </dependency>
             <dependency>
-                <groupId>org.streampipes</groupId>
+                <groupId>org.apache.streampipes</groupId>
                 <artifactId>streampipes-measurement-units</artifactId>
                 <version>${streampipes.version}</version>
             </dependency>
             <dependency>
-                <groupId>org.streampipes</groupId>
+                <groupId>org.apache.streampipes</groupId>
                 <artifactId>streampipes-messaging-jms</artifactId>
                 <version>${streampipes.version}</version>
             </dependency>
             <dependency>
-                <groupId>org.streampipes</groupId>
+                <groupId>org.apache.streampipes</groupId>
                 <artifactId>streampipes-messaging-kafka</artifactId>
                 <version>${streampipes.version}</version>
             </dependency>
             <dependency>
-                <groupId>org.streampipes</groupId>
+                <groupId>org.apache.streampipes</groupId>
                 <artifactId>streampipes-sdk</artifactId>
                 <version>${streampipes.version}</version>
             </dependency>
             <dependency>
-                <groupId>org.streampipes</groupId>
+                <groupId>org.apache.streampipes</groupId>
                 <artifactId>streampipes-sources</artifactId>
                 <version>${streampipes.version}</version>
             </dependency>
             <dependency>
-                <groupId>org.streampipes</groupId>
+                <groupId>org.apache.streampipes</groupId>
                 <artifactId>streampipes-wrapper-siddhi</artifactId>
                 <version>${streampipes.version}</version>
             </dependency>
             <dependency>
-                <groupId>org.streampipes</groupId>
+                <groupId>org.apache.streampipes</groupId>
                 <artifactId>streampipes-wrapper-standalone</artifactId>
                 <version>${streampipes.version}</version>
             </dependency>
             <dependency>
-                <groupId>org.streampipes</groupId>
+                <groupId>org.apache.streampipes</groupId>
                 <artifactId>streampipes-wrapper-flink</artifactId>
                 <version>${streampipes.version}</version>
                 <exclusions>
@@ -327,7 +327,7 @@
                 <version>${flink.version}</version>
             </dependency>
             <dependency>
-                <groupId>org.streampipes</groupId>
+                <groupId>org.apache.streampipes</groupId>
                 <artifactId>streampipes-test-utils</artifactId>
                 <version>${streampipes.version}</version>
                 <scope>test</scope>
@@ -546,7 +546,7 @@
                 </configuration>
             </plugin>
             <!--            <plugin>-->
-            <!--                <groupId>org.streampipes</groupId>-->
+            <!--                <groupId>org.apache.streampipes</groupId>-->
             <!--                <artifactId>streampipes-maven-plugin</artifactId>-->
             <!--                <version>1.0-SNAPSHOT</version>-->
             <!--            </plugin>-->
diff --git a/streampipes-connect-adapters/pom.xml b/streampipes-connect-adapters/pom.xml
index 6782d6f..8225cb9 100644
--- a/streampipes-connect-adapters/pom.xml
+++ b/streampipes-connect-adapters/pom.xml
@@ -21,7 +21,7 @@
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
-        <groupId>org.streampipes</groupId>
+        <groupId>org.apache.streampipes</groupId>
         <artifactId>streampipes-extensions</artifactId>
         <version>0.65.1-SNAPSHOT</version>
         <relativePath>..</relativePath>
@@ -63,7 +63,7 @@
         <dependencies>
             <!-- StreamPipes dependencies -->
             <dependency>
-                <groupId>org.streampipes</groupId>
+                <groupId>org.apache.streampipes</groupId>
                 <artifactId>streampipes-connect-container-worker</artifactId>
                 <version>${streampipes.version}</version>
             </dependency>
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/pom.xml b/streampipes-connect-adapters/streampipes-connect-adapter/pom.xml
index 21e61b6..a64a0b4 100644
--- a/streampipes-connect-adapters/streampipes-connect-adapter/pom.xml
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/pom.xml
@@ -20,7 +20,7 @@
 <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-connect-adapters</artifactId>
-        <groupId>org.streampipes</groupId>
+        <groupId>org.apache.streampipes</groupId>
         <version>0.65.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
@@ -31,7 +31,7 @@
     <dependencies>
         <!-- StreamPipes dependencies -->
         <dependency>
-            <groupId>org.streampipes</groupId>
+            <groupId>org.apache.streampipes</groupId>
             <artifactId>streampipes-connect-container-worker</artifactId>
         </dependency>
 
@@ -138,7 +138,7 @@
                             <goal>repackage</goal>
                         </goals>
                         <configuration>
-                            <mainClass>org.streampipes.connect.ConnectAdapterInit</mainClass>
+                            <mainClass>org.apache.streampipes.connect.ConnectAdapterInit</mainClass>
                         </configuration>
                     </execution>
                 </executions>
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/ConnectAdapterInit.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/ConnectAdapterInit.java
new file mode 100644
index 0000000..00d2572
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/ConnectAdapterInit.java
@@ -0,0 +1,92 @@
+/*
+ * 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.connect;
+
+import org.apache.streampipes.connect.adapters.ti.TISensorTag;
+import org.apache.streampipes.connect.protocol.set.HttpProtocol;
+import org.apache.streampipes.connect.adapters.coindesk.CoindeskBitcoinAdapter;
+import org.apache.streampipes.connect.adapters.gdelt.GdeltAdapter;
+import org.apache.streampipes.connect.adapters.iex.IexCloudNewsAdapter;
+import org.apache.streampipes.connect.adapters.iex.IexCloudStockAdapter;
+import org.apache.streampipes.connect.adapters.influxdb.InfluxDbSetAdapter;
+import org.apache.streampipes.connect.adapters.influxdb.InfluxDbStreamAdapter;
+import org.apache.streampipes.connect.adapters.mysql.MySqlSetAdapter;
+import org.apache.streampipes.connect.adapters.mysql.MySqlStreamAdapter;
+import org.apache.streampipes.connect.adapters.opcua.OpcUaAdapter;
+import org.apache.streampipes.connect.adapters.plc4x.s7.Plc4xS7Adapter;
+import org.apache.streampipes.connect.adapters.ros.RosBridgeAdapter;
+import org.apache.streampipes.connect.adapters.simulator.RandomDataSetAdapter;
+import org.apache.streampipes.connect.adapters.simulator.RandomDataStreamAdapter;
+import org.apache.streampipes.connect.adapters.slack.SlackAdapter;
+import org.apache.streampipes.connect.adapters.wikipedia.WikipediaEditedArticlesAdapter;
+import org.apache.streampipes.connect.adapters.wikipedia.WikipediaNewArticlesAdapter;
+import org.apache.streampipes.connect.config.ConnectWorkerConfig;
+import org.apache.streampipes.connect.container.worker.init.AdapterWorkerContainer;
+import org.apache.streampipes.connect.init.AdapterDeclarerSingleton;
+import org.apache.streampipes.connect.protocol.set.FileProtocol;
+import org.apache.streampipes.connect.protocol.stream.FileStreamProtocol;
+import org.apache.streampipes.connect.protocol.stream.HDFSProtocol;
+import org.apache.streampipes.connect.protocol.stream.HttpStreamProtocol;
+import org.apache.streampipes.connect.protocol.stream.KafkaProtocol;
+import org.apache.streampipes.connect.protocol.stream.MqttProtocol;
+import org.apache.streampipes.connect.protocol.stream.pulsar.PulsarProtocol;
+
+public class ConnectAdapterInit extends AdapterWorkerContainer {
+
+  public static void main(String[] args) {
+    AdapterDeclarerSingleton
+            .getInstance()
+
+            // Protocols
+            .add(new FileProtocol())
+            .add(new HttpProtocol())
+            .add(new FileStreamProtocol())
+            .add(new HDFSProtocol())
+            .add(new KafkaProtocol())
+            .add(new MqttProtocol())
+            .add(new HttpStreamProtocol())
+            .add(new PulsarProtocol())
+
+            // Specific Adapters
+            .add(new GdeltAdapter())
+            .add(new CoindeskBitcoinAdapter())
+            .add(new IexCloudNewsAdapter())
+            .add(new IexCloudStockAdapter())
+            .add(new MySqlStreamAdapter())
+            .add(new MySqlSetAdapter())
+            .add(new RandomDataSetAdapter())
+            .add(new RandomDataStreamAdapter())
+            .add(new SlackAdapter())
+            .add(new WikipediaEditedArticlesAdapter())
+            .add(new WikipediaNewArticlesAdapter())
+            .add(new RosBridgeAdapter())
+            .add(new OpcUaAdapter())
+            .add(new InfluxDbStreamAdapter())
+            .add(new InfluxDbSetAdapter())
+            .add(new TISensorTag())
+            .add(new Plc4xS7Adapter());
+
+    String workerUrl = ConnectWorkerConfig.INSTANCE.getConnectContainerWorkerUrl();
+    String masterUrl = ConnectWorkerConfig.INSTANCE.getConnectContainerMasterUrl();
+    Integer workerPort = ConnectWorkerConfig.INSTANCE.getConnectContainerWorkerPort();
+
+    new ConnectAdapterInit().init(workerUrl, masterUrl, workerPort);
+
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/PullAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/PullAdapter.java
new file mode 100644
index 0000000..30cc9b5
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/PullAdapter.java
@@ -0,0 +1,100 @@
+/*
+ * 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.connect.adapters;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.model.specific.SpecificDataStreamAdapter;
+import org.apache.streampipes.connect.adapter.util.PollingSettings;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+
+import java.util.concurrent.*;
+
+
+public abstract class PullAdapter extends SpecificDataStreamAdapter {
+
+    protected static Logger logger = LoggerFactory.getLogger(PullAdapter.class);
+    private ScheduledExecutorService scheduler;
+    private ScheduledExecutorService errorThreadscheduler;
+
+
+    public PullAdapter() {
+        super();
+    }
+
+    public PullAdapter(SpecificAdapterStreamDescription adapterDescription) {
+        super(adapterDescription);
+    }
+
+    protected abstract void pullData();
+
+    protected abstract PollingSettings getPollingInterval();
+
+    @Override
+    public void startAdapter() throws AdapterException {
+        before();
+
+        final Runnable errorThread = () -> {
+            executeAdpaterLogic();
+        };
+
+        scheduler = Executors.newScheduledThreadPool(1);
+        scheduler.schedule(errorThread, 0, TimeUnit.MILLISECONDS);
+
+    }
+
+    private void executeAdpaterLogic() {
+        final Runnable task = () -> {
+
+            pullData();
+
+        };
+
+        scheduler = Executors.newScheduledThreadPool(1);
+        ScheduledFuture<?> handle = scheduler.scheduleAtFixedRate(task, 1,
+                getPollingInterval().getValue(), getPollingInterval().getTimeUnit());
+
+        try {
+            handle.get();
+        } catch (ExecutionException | InterruptedException e) {
+            logger.error("Error", e);
+        }
+    }
+
+    @Override
+    public void stopAdapter() throws AdapterException {
+        after();
+        scheduler.shutdownNow();
+    }
+
+    /**
+     * Called before adapter is started (e.g. initialize connections)
+     */
+    protected void before() throws AdapterException {
+
+    }
+
+    /**
+     * Called before adapter is stopped (e.g. shutdown connections)
+     */
+    protected void after() throws AdapterException {
+
+    }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/PullRestAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/PullRestAdapter.java
new file mode 100644
index 0000000..0638ab2
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/PullRestAdapter.java
@@ -0,0 +1,71 @@
+/*
+ * 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.connect.adapters;
+
+import com.google.gson.Gson;
+import org.apache.http.client.fluent.Request;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+
+public abstract class PullRestAdapter extends PullAdapter {
+
+    public PullRestAdapter() {
+        super();
+    }
+
+    public PullRestAdapter(SpecificAdapterStreamDescription adapterDescription) {
+        super(adapterDescription);
+    }
+
+    protected static String getDataFromEndpointString(String url) throws AdapterException {
+        String result = null;
+
+
+        logger.info("Started Request to open sensemap endpoint: " + url);
+        try {
+            result = Request.Get(url)
+                    .connectTimeout(1000)
+                    .socketTimeout(100000)
+                    .execute().returnContent().asString();
+
+
+            if (result.startsWith("ï")) {
+                result = result.substring(3);
+            }
+
+            logger.info("Received data from request");
+
+        } catch (Exception e) {
+            String errorMessage = "Error while connecting to the open sensemap api";
+            logger.error(errorMessage, e);
+            throw new AdapterException(errorMessage);
+        }
+
+        return result;
+    }
+
+    protected static <T> T getDataFromEndpoint(String url, Class<T> clazz) throws AdapterException {
+
+        String rawJson = getDataFromEndpointString(url);
+        T all = new Gson().fromJson(rawJson, clazz);
+
+        return all;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/CoindeskBitcoinAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/CoindeskBitcoinAdapter.java
new file mode 100644
index 0000000..9bb047e
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/CoindeskBitcoinAdapter.java
@@ -0,0 +1,124 @@
+/*
+ * 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.connect.adapters.coindesk;
+
+import com.google.gson.Gson;
+import org.apache.http.client.fluent.Request;
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.exception.ParseException;
+import org.apache.streampipes.connect.adapter.sdk.ParameterExtractor;
+import org.apache.streampipes.connect.adapter.util.PollingSettings;
+import org.apache.streampipes.connect.adapters.PullAdapter;
+import org.apache.streampipes.connect.adapters.coindesk.model.CoindeskRawModel;
+import org.apache.streampipes.model.AdapterType;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.sdk.builder.adapter.GuessSchemaBuilder;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataStreamAdapterBuilder;
+import org.apache.streampipes.sdk.helpers.EpProperties;
+import org.apache.streampipes.sdk.helpers.Labels;
+import org.apache.streampipes.sdk.helpers.Options;
+import org.apache.streampipes.vocabulary.SO;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+public class CoindeskBitcoinAdapter extends PullAdapter {
+
+  public static final String ID = "http://streampipes.org/adapter/specific/coindesk/bitcoin";
+
+  private static final String CoindeskUrl = "https://api.coindesk.com/v1/bpi/currentprice.json";
+
+  private Currency currency;
+
+  public CoindeskBitcoinAdapter() {
+
+  }
+
+  public CoindeskBitcoinAdapter(SpecificAdapterStreamDescription adapterDescription) {
+    super(adapterDescription);
+    ParameterExtractor extractor = new ParameterExtractor(adapterDescription.getConfig());
+    this.currency = Currency.valueOf(extractor.selectedSingleValueOption("currency"));
+
+  }
+
+  @Override
+  protected void pullData() {
+    try {
+      String response = Request.Get(CoindeskUrl).execute().returnContent().asString();
+      CoindeskRawModel rawModel = new Gson().fromJson(response, CoindeskRawModel.class);
+
+      long timestamp = System.currentTimeMillis();
+      Double rate;
+      if (currency == Currency.EUR) {
+        rate = rawModel.getBpi().getEUR().getRateFloat();
+      } else if (currency == Currency.GBP) {
+        rate = rawModel.getBpi().getGBP().getRateFloat();
+      } else {
+        rate = rawModel.getBpi().getUSD().getRateFloat();
+      }
+
+      Map<String, Object> outMap = new HashMap<>();
+      outMap.put("timestamp", timestamp);
+      outMap.put("rate", rate);
+
+      adapterPipeline.process(outMap);
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+  }
+
+  @Override
+  protected PollingSettings getPollingInterval() {
+    return PollingSettings.from(TimeUnit.SECONDS, 60);
+  }
+
+  @Override
+  public SpecificAdapterStreamDescription declareModel() {
+    return SpecificDataStreamAdapterBuilder.create(ID, "Coindesk Bitcoin Stream", "The current " +
+            "bitcoin price from the Coindesk API.")
+            .iconUrl("coindesk.png")
+            .category(AdapterType.Finance)
+            .requiredSingleValueSelection(Labels.from("currency", "Currency", "The currency of the" +
+                    " bitcoin rate"), Options.from("USD", "EUR", "GBP"))
+            .build();
+  }
+
+  @Override
+  public Adapter getInstance(SpecificAdapterStreamDescription adapterDescription) {
+    return new CoindeskBitcoinAdapter(adapterDescription);
+  }
+
+  @Override
+  public GuessSchema getSchema(SpecificAdapterStreamDescription adapterDescription) throws AdapterException, ParseException {
+    return GuessSchemaBuilder.create()
+            .property(EpProperties.timestampProperty("timestamp"))
+            .property(EpProperties.doubleEp(Labels.from("rate-field", "Rate", "The current " +
+                    "bitcoin rate"), "rate", SO.Price))
+            .build();
+  }
+
+  @Override
+  public String getId() {
+    return ID;
+  }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/Currency.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/Currency.java
new file mode 100644
index 0000000..1e62334
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/Currency.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.connect.adapters.coindesk;
+
+public enum Currency {
+  EUR,
+  GBP,
+  USD;
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/model/Bpi.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/model/Bpi.java
new file mode 100644
index 0000000..5ec9fa3
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/model/Bpi.java
@@ -0,0 +1,60 @@
+/*
+ * 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.connect.adapters.coindesk.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class Bpi {
+
+    @SerializedName("EUR")
+    private EUR mEUR;
+    @SerializedName("GBP")
+    private GBP mGBP;
+    @SerializedName("USD")
+    private USD mUSD;
+
+    public EUR getEUR() {
+        return mEUR;
+    }
+
+    public void setEUR(EUR eUR) {
+        mEUR = eUR;
+    }
+
+    public GBP getGBP() {
+        return mGBP;
+    }
+
+    public void setGBP(GBP gBP) {
+        mGBP = gBP;
+    }
+
+    public USD getUSD() {
+        return mUSD;
+    }
+
+    public void setUSD(USD uSD) {
+        mUSD = uSD;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/model/CoindeskRawModel.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/model/CoindeskRawModel.java
new file mode 100644
index 0000000..ad68f36
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/model/CoindeskRawModel.java
@@ -0,0 +1,70 @@
+/*
+ * 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.connect.adapters.coindesk.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class CoindeskRawModel {
+
+    @SerializedName("bpi")
+    private Bpi mBpi;
+    @SerializedName("chartName")
+    private String mChartName;
+    @SerializedName("disclaimer")
+    private String mDisclaimer;
+    @SerializedName("time")
+    private Time mTime;
+
+    public Bpi getBpi() {
+        return mBpi;
+    }
+
+    public void setBpi(Bpi bpi) {
+        mBpi = bpi;
+    }
+
+    public String getChartName() {
+        return mChartName;
+    }
+
+    public void setChartName(String chartName) {
+        mChartName = chartName;
+    }
+
+    public String getDisclaimer() {
+        return mDisclaimer;
+    }
+
+    public void setDisclaimer(String disclaimer) {
+        mDisclaimer = disclaimer;
+    }
+
+    public Time getTime() {
+        return mTime;
+    }
+
+    public void setTime(Time time) {
+        mTime = time;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/model/EUR.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/model/EUR.java
new file mode 100644
index 0000000..6d4c54e
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/model/EUR.java
@@ -0,0 +1,80 @@
+
+/*
+ * 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.connect.adapters.coindesk.model;
+
+import javax.annotation.Generated;
+import com.google.gson.annotations.SerializedName;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class EUR {
+
+    @SerializedName("code")
+    private String mCode;
+    @SerializedName("description")
+    private String mDescription;
+    @SerializedName("rate")
+    private String mRate;
+    @SerializedName("rate_float")
+    private Double mRateFloat;
+    @SerializedName("symbol")
+    private String mSymbol;
+
+    public String getCode() {
+        return mCode;
+    }
+
+    public void setCode(String code) {
+        mCode = code;
+    }
+
+    public String getDescription() {
+        return mDescription;
+    }
+
+    public void setDescription(String description) {
+        mDescription = description;
+    }
+
+    public String getRate() {
+        return mRate;
+    }
+
+    public void setRate(String rate) {
+        mRate = rate;
+    }
+
+    public Double getRateFloat() {
+        return mRateFloat;
+    }
+
+    public void setRateFloat(Double rateFloat) {
+        mRateFloat = rateFloat;
+    }
+
+    public String getSymbol() {
+        return mSymbol;
+    }
+
+    public void setSymbol(String symbol) {
+        mSymbol = symbol;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/model/GBP.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/model/GBP.java
new file mode 100644
index 0000000..9b6f0e6
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/model/GBP.java
@@ -0,0 +1,80 @@
+/*
+ * 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.connect.adapters.coindesk.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class GBP {
+
+    @SerializedName("code")
+    private String mCode;
+    @SerializedName("description")
+    private String mDescription;
+    @SerializedName("rate")
+    private String mRate;
+    @SerializedName("rate_float")
+    private Double mRateFloat;
+    @SerializedName("symbol")
+    private String mSymbol;
+
+    public String getCode() {
+        return mCode;
+    }
+
+    public void setCode(String code) {
+        mCode = code;
+    }
+
+    public String getDescription() {
+        return mDescription;
+    }
+
+    public void setDescription(String description) {
+        mDescription = description;
+    }
+
+    public String getRate() {
+        return mRate;
+    }
+
+    public void setRate(String rate) {
+        mRate = rate;
+    }
+
+    public Double getRateFloat() {
+        return mRateFloat;
+    }
+
+    public void setRateFloat(Double rateFloat) {
+        mRateFloat = rateFloat;
+    }
+
+    public String getSymbol() {
+        return mSymbol;
+    }
+
+    public void setSymbol(String symbol) {
+        mSymbol = symbol;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/model/Time.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/model/Time.java
new file mode 100644
index 0000000..ecf6a48
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/model/Time.java
@@ -0,0 +1,60 @@
+/*
+ * 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.connect.adapters.coindesk.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class Time {
+
+    @SerializedName("updated")
+    private String mUpdated;
+    @SerializedName("updatedISO")
+    private String mUpdatedISO;
+    @SerializedName("updateduk")
+    private String mUpdateduk;
+
+    public String getUpdated() {
+        return mUpdated;
+    }
+
+    public void setUpdated(String updated) {
+        mUpdated = updated;
+    }
+
+    public String getUpdatedISO() {
+        return mUpdatedISO;
+    }
+
+    public void setUpdatedISO(String updatedISO) {
+        mUpdatedISO = updatedISO;
+    }
+
+    public String getUpdateduk() {
+        return mUpdateduk;
+    }
+
+    public void setUpdateduk(String updateduk) {
+        mUpdateduk = updateduk;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/model/USD.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/model/USD.java
new file mode 100644
index 0000000..3f8c92f
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/coindesk/model/USD.java
@@ -0,0 +1,80 @@
+/*
+ * 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.connect.adapters.coindesk.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class USD {
+
+    @SerializedName("code")
+    private String mCode;
+    @SerializedName("description")
+    private String mDescription;
+    @SerializedName("rate")
+    private String mRate;
+    @SerializedName("rate_float")
+    private Double mRateFloat;
+    @SerializedName("symbol")
+    private String mSymbol;
+
+    public String getCode() {
+        return mCode;
+    }
+
+    public void setCode(String code) {
+        mCode = code;
+    }
+
+    public String getDescription() {
+        return mDescription;
+    }
+
+    public void setDescription(String description) {
+        mDescription = description;
+    }
+
+    public String getRate() {
+        return mRate;
+    }
+
+    public void setRate(String rate) {
+        mRate = rate;
+    }
+
+    public Double getRateFloat() {
+        return mRateFloat;
+    }
+
+    public void setRateFloat(Double rateFloat) {
+        mRateFloat = rateFloat;
+    }
+
+    public String getSymbol() {
+        return mSymbol;
+    }
+
+    public void setSymbol(String symbol) {
+        mSymbol = symbol;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/gdelt/GdeltAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/gdelt/GdeltAdapter.java
new file mode 100644
index 0000000..8a825d1
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/gdelt/GdeltAdapter.java
@@ -0,0 +1,188 @@
+/*
+ * 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.connect.adapters.gdelt;
+
+import com.opencsv.CSVReader;
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.util.PollingSettings;
+import org.apache.streampipes.connect.adapters.PullAdapter;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.model.schema.EventProperty;
+import org.apache.streampipes.model.schema.EventSchema;
+import org.apache.streampipes.sdk.builder.PrimitivePropertyBuilder;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataStreamAdapterBuilder;
+import org.apache.streampipes.sdk.utils.Datatypes;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.zip.ZipInputStream;
+
+public class GdeltAdapter extends PullAdapter {
+
+    public static final String ID = "http://streampipes.org/adapter/specific/gdelt";
+    private String url = "http://data.gdeltproject.org/gdeltv2/lastupdate.txt";
+
+    public GdeltAdapter() {
+        super();
+    }
+
+    public GdeltAdapter(SpecificAdapterStreamDescription adapterDescription) {
+        super(adapterDescription);
+    }
+
+    @Override
+    protected PollingSettings getPollingInterval() {
+        return PollingSettings.from(TimeUnit.MINUTES, 15);
+    }
+
+    @Override
+    public SpecificAdapterStreamDescription declareModel() {
+        SpecificAdapterStreamDescription description = SpecificDataStreamAdapterBuilder.create(ID, "GDELT", "Global Database of Society")
+                .iconUrl("gdelt.png")
+                .build();
+        description.setAppId(ID);
+        return  description;
+    }
+
+    public List<Map<String, Object>> getEvents() {
+
+        List<Map<String, Object>> eventResults = new ArrayList<>();
+        return eventResults;
+    }
+
+    @Override
+    protected void pullData() {
+        try {
+            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new URL(url).openStream()));
+            String firstLine = bufferedReader.readLine();
+            String[] parts = firstLine.split(" ");
+            URL zipFileUrl = new URL(parts[2]);
+            bufferedReader.close();
+            ZipInputStream zipInputStream = new ZipInputStream(zipFileUrl.openStream());
+            BufferedReader zipBufferedReader = new BufferedReader(new InputStreamReader(zipInputStream));
+            zipInputStream.getNextEntry();
+            CSVReader csvReader = new CSVReader(zipBufferedReader, '\t', '"');
+            String[] nextRecord;
+            while ((nextRecord = csvReader.readNext()) != null) {
+
+                Map<String, Object> event = new HashMap<>();
+
+                event.put("global_event_id", nextRecord[0]);
+                event.put("day", nextRecord[1]);
+                event.put("month_year", nextRecord[2]);
+                event.put("year", nextRecord[3]);
+                event.put("fraction_date", nextRecord[4]);
+
+                event.put("actor_1_code", nextRecord[5]);
+                event.put("actor_1_name", nextRecord[6]);
+                event.put("actor_1_country_code", nextRecord[7]);
+                event.put("actor_1_known_group_code", nextRecord[8]);
+                event.put("actor_1_ethnic_code", nextRecord[9]);
+                event.put("actor_1_religion_1_code", nextRecord[10]);
+                event.put("actor_1_religion_2_code", nextRecord[11]);
+                event.put("actor_1_type_1_code", nextRecord[12]);
+                event.put("actor_1_type_2_code", nextRecord[13]);
+                event.put("actor_1_type_3_code", nextRecord[14]);
+
+                event.put("actor_2_code", nextRecord[15]);
+                event.put("actor_2_name", nextRecord[16]);
+                event.put("actor_2_country_code", nextRecord[17]);
+                event.put("actor_2_known_group_code", nextRecord[18]);
+                event.put("actor_2_ethnic_code", nextRecord[19]);
+                event.put("actor_2_religion_1_code", nextRecord[20]);
+                event.put("actor_2_religion_2_code", nextRecord[21]);
+                event.put("actor_2_type_1_code", nextRecord[22]);
+                event.put("actor_2_type_2_code", nextRecord[23]);
+                event.put("actor_2_type_3_code", nextRecord[24]);
+
+                event.put("source_url", nextRecord[60]);
+                adapterPipeline.process(event);
+
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    @Override
+    public void stopAdapter() throws AdapterException {
+
+    }
+
+    @Override
+    public Adapter getInstance(SpecificAdapterStreamDescription adapterDescription) {
+        return new GdeltAdapter(adapterDescription);
+    }
+
+    @Override
+    public GuessSchema getSchema(SpecificAdapterStreamDescription adapterDescription) {
+        GuessSchema guessSchema = new GuessSchema();
+        EventSchema eventSchema = new EventSchema();
+
+        List<EventProperty> allProperties = new ArrayList<>();
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.Integer, "global_event_id").label("Global Event ID").description("Globally unique identifier").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.Integer, "day").label("Day").description("Date the event took place in YYYYMMDD format").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.Integer, "month_year").label("MonthYear").description("Date the event took place in YYYYMM format").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.Integer, "year").label("Year").description("Date the event took place in YYYY format").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.Float, "fraction_date").label("FractionDate").description("Date the event took place in YYYY.FFFF format (where FFFF is the percentage of the year completed)").build());
+
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_1_code").label("Actor1Code").description("The complete raw CAMEO code for Actor1").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_1_name").label("Actor1Name").description("The actual name of the Actor1").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_1_country_code").label("Actor1CountryCode").description("The 3-character CAMEO code for the country affiliation of Actor1").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_1_known_group_code").label("Actor1KnownGroupCode").description("The CAMEO code if Actor 1 is a known IGO/NGO/rebel organization").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_1_ethnic_code").label("Actor1EthnicCode").description("The CAMEO code if the source document specifies the ethnic affiliation of Actor1").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_1_religion_1_code").label("Actor1Religion1Code").description("The CAMEO code if the source document specifies the religious affiliation of Actor1").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_1_religion_2_code").label("Actor1Religion2Code").description("The CAMEO code if the source document specifies multiple religious affiliations of Actor1").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_1_type_1_code").label("Actor1Type1Code").description("The 3-character CAMEO code of the CAMEO “type” or “role” of Actor1").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_1_type_2_code").label("Actor1Type2Code").description("The 3-character CAMEO code of the CAMEO “type” or “role” of Actor1").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_1_type_3_code").label("Actor1Type3Code").description("The 3-character CAMEO code of the CAMEO “type” or “role” of Actor1").build());
+
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_2_code").label("Actor2Code").description("The complete raw CAMEO code for Actor2").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_2_name").label("Actor2Name").description("The actual name of the Actor2").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_2_country_code").label("Actor2CountryCode").description("The 3-character CAMEO code for the country affiliation of Actor2").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_2_known_group_code").label("Actor2KnownGroupCode").description("The CAMEO code if Actor 1 is a known IGO/NGO/rebel organization").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_2_ethnic_code").label("Actor2EthnicCode").description("The CAMEO code if the source document specifies the ethnic affiliation of Actor2").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_2_religion_1_code").label("Actor2Religion1Code").description("The CAMEO code if the source document specifies the religious affiliation of Actor2").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_2_religion_2_code").label("Actor2Religion2Code").description("The CAMEO code if the source document specifies multiple religious affiliations of Actor2").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_2_type_1_code").label("Actor2Type1Code").description("The 3-character CAMEO code of the CAMEO “type” or “role” of Actor2").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_2_type_2_code").label("Actor2Type2Code").description("The 3-character CAMEO code of the CAMEO “type” or “role” of Actor2").build());
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "actor_2_type_3_code").label("Actor2Type3Code").description("The 3-character CAMEO code of the CAMEO “type” or “role” of Actor2").build());
+
+        allProperties.add(PrimitivePropertyBuilder.create(Datatypes.String, "source_url").label("URL").description("The url of the source of the article").build());
+
+        eventSchema.setEventProperties(allProperties);
+        guessSchema.setEventSchema(eventSchema);
+        guessSchema.setPropertyProbabilityList(new ArrayList<>());
+        return guessSchema;
+    }
+
+    @Override
+    public String getId() {
+        return ID;
+    }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/iex/IexCloudAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/iex/IexCloudAdapter.java
new file mode 100644
index 0000000..6aa59fd
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/iex/IexCloudAdapter.java
@@ -0,0 +1,55 @@
+/*
+ * 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.connect.adapters.iex;
+
+import com.google.gson.Gson;
+import org.apache.http.client.fluent.Request;
+import org.apache.streampipes.connect.adapter.sdk.ParameterExtractor;
+import org.apache.streampipes.connect.adapters.PullAdapter;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+
+import java.io.IOException;
+
+public abstract class IexCloudAdapter extends PullAdapter {
+
+  protected static final String IexCloudBaseUrl = "https://cloud.iexapis.com/stable/stock/";
+  protected static final String Token = "?token=";
+
+  protected String apiToken;
+  protected String stockQuote;
+  private String iexCloudInstanceUrl;
+
+
+  public IexCloudAdapter(SpecificAdapterStreamDescription adapterDescription, String restPath) {
+    super(adapterDescription);
+    ParameterExtractor extractor = new ParameterExtractor(adapterDescription.getConfig());
+    this.apiToken = extractor.secretValue("token");
+    this.stockQuote = extractor.singleValue("stock");
+    this.iexCloudInstanceUrl = IexCloudBaseUrl + stockQuote + restPath + Token + apiToken;
+
+  }
+
+  public IexCloudAdapter() {
+    super();
+  }
+
+  protected <T> T fetchResult(Class<T> classToParse) throws IOException {
+    String response = Request.Get(iexCloudInstanceUrl).execute().returnContent().asString();
+    return new Gson().fromJson(response, classToParse);
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/iex/IexCloudNewsAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/iex/IexCloudNewsAdapter.java
new file mode 100644
index 0000000..a27ef21
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/iex/IexCloudNewsAdapter.java
@@ -0,0 +1,137 @@
+/*
+ * 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.connect.adapters.iex;
+
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.exception.ParseException;
+import org.apache.streampipes.connect.adapter.util.PollingSettings;
+import org.apache.streampipes.connect.adapters.iex.model.IexNewsData;
+import org.apache.streampipes.model.AdapterType;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.sdk.builder.adapter.GuessSchemaBuilder;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataStreamAdapterBuilder;
+import org.apache.streampipes.sdk.helpers.EpProperties;
+import org.apache.streampipes.sdk.helpers.Labels;
+import org.apache.streampipes.vocabulary.SO;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+public class IexCloudNewsAdapter extends IexCloudAdapter {
+
+  public static final String ID = "http://streampipes.org/adapter/specific/iexcloud/news";
+  private static final String News = "/news";
+
+  private static final String Timestamp = "timestamp";
+  private static final String Headline = "headline";
+  private static final String Source = "source";
+  private static final String Url = "url";
+  private static final String Summary = "summary";
+  private static final String Related = "related";
+  private static final String Image = "image";
+  private static final String Lang = "lang";
+  private static final String HasPaywall = "hasPaywall";
+
+  public IexCloudNewsAdapter(SpecificAdapterStreamDescription adapterStreamDescription) {
+    super(adapterStreamDescription, News);
+  }
+
+  public IexCloudNewsAdapter() {
+    super();
+  }
+
+  @Override
+  protected void pullData() {
+    try {
+      IexNewsData[] rawModel = fetchResult(IexNewsData[].class);
+
+      for (IexNewsData newsData : rawModel) {
+        Map<String, Object> outMap = new HashMap<>();
+        outMap.put(Timestamp, newsData.getDatetime());
+        outMap.put(Headline, newsData.getHeadline());
+        outMap.put(Source, newsData.getSource());
+        outMap.put(Url, newsData.getUrl());
+        outMap.put(Summary, newsData.getSummary());
+        outMap.put(Related, newsData.getRelated());
+        outMap.put(Image, newsData.getImage());
+        outMap.put(Lang, newsData.getLang());
+        outMap.put(HasPaywall, newsData.getHasPaywall());
+
+        adapterPipeline.process(outMap);
+      }
+    } catch (
+            IOException e) {
+      e.printStackTrace();
+    }
+  }
+
+  @Override
+  protected PollingSettings getPollingInterval() {
+    return PollingSettings.from(TimeUnit.SECONDS, 60);
+  }
+
+  @Override
+  public SpecificAdapterStreamDescription declareModel() {
+    return SpecificDataStreamAdapterBuilder.create(ID, "IEX Cloud News", "Fetches news for a " +
+            "given company (10 news / minutes maximum)")
+            .iconUrl("iexcloud.png")
+            .category(AdapterType.Finance, AdapterType.News)
+            .requiredSecret(Labels.from("token", "API Token", "The IEXCloud API token"))
+            .requiredTextParameter(Labels.from("stock", "Stock", "The stock symbol (e.g., AAPL)"))
+            .build();
+  }
+
+  @Override
+  public Adapter getInstance(SpecificAdapterStreamDescription adapterDescription) {
+    return new IexCloudNewsAdapter(adapterDescription);
+  }
+
+  @Override
+  public GuessSchema getSchema(SpecificAdapterStreamDescription adapterDescription) throws AdapterException, ParseException {
+    return GuessSchemaBuilder.create()
+            .property(EpProperties.timestampProperty(Timestamp))
+            .property(EpProperties.stringEp(Labels.from("headline", "Headline",
+                    "The headline of the article"), Headline, SO.Text))
+            .property(EpProperties.stringEp(Labels.from("source", "Source",
+                    "The source of the article"), Source, SO.Text))
+            .property(EpProperties.stringEp(Labels.from("url", "URL",
+                    "The URL of the article"), Url, SO.ContentUrl))
+            .property(EpProperties.stringEp(Labels.from("summary", "Summary",
+                    "A short summary of the article"), Summary, SO.Text))
+            .property(EpProperties.stringEp(Labels.from("related", "Related",
+                    "A comma-separated list of related stock symbols"), Related, SO.Text))
+            .property(EpProperties.stringEp(Labels.from("image", "Image",
+                    "Link to an image related to the news article"), Image, SO.Image))
+            .property(EpProperties.stringEp(Labels.from("lang", "Language",
+                    "The language the article is writte in"), Lang, SO.InLanguage))
+            .property(EpProperties.stringEp(Labels.from("paywall", "Has Paywall",
+                    "Indicates whether the article is behind a paywall"), HasPaywall,
+                    SO.Text))
+            .build();
+  }
+
+  @Override
+  public String getId() {
+    return ID;
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/iex/IexCloudStockAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/iex/IexCloudStockAdapter.java
new file mode 100644
index 0000000..c1dd929
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/iex/IexCloudStockAdapter.java
@@ -0,0 +1,111 @@
+/*
+ * 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.connect.adapters.iex;
+
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.exception.ParseException;
+import org.apache.streampipes.connect.adapter.util.PollingSettings;
+import org.apache.streampipes.connect.adapters.iex.model.IexStockData;
+import org.apache.streampipes.model.AdapterType;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.sdk.builder.adapter.GuessSchemaBuilder;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataStreamAdapterBuilder;
+import org.apache.streampipes.sdk.helpers.EpProperties;
+import org.apache.streampipes.sdk.helpers.Labels;
+import org.apache.streampipes.vocabulary.SO;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+public class IexCloudStockAdapter extends IexCloudAdapter {
+
+  public static final String ID = "http://streampipes.org/adapter/specific/iexcloud/stocks";
+
+  private static final String Quotes = "/quote";
+  private static final String LatestUpdate = "latestUpdate";
+  private static final String LatestPrice = "latestPrice";
+  private static final String Symbol = "symbol";
+
+  public IexCloudStockAdapter(SpecificAdapterStreamDescription adapterDescription) {
+    super(adapterDescription, Quotes);
+  }
+
+  public IexCloudStockAdapter() {
+    super();
+  }
+
+  @Override
+  public SpecificAdapterStreamDescription declareModel() {
+    return SpecificDataStreamAdapterBuilder.create(ID, "IEX Cloud Stock Quotes", "Live stock data" +
+            " provided by <a href='https://iexcloud.io'>IEX Cloud</a>")
+            .iconUrl("iexcloud.png")
+            .category(AdapterType.Finance)
+            .requiredSecret(Labels.from("token", "API Token", "The IEXCloud API token"))
+            .requiredTextParameter(Labels.from("stock", "Stock", "The stock symbol (e.g., AAPL)"))
+            .build();
+
+  }
+
+  @Override
+  protected void pullData() {
+    try {
+      IexStockData rawModel = fetchResult(IexStockData.class);
+
+      Map<String, Object> outMap = new HashMap<>();
+      outMap.put(LatestUpdate, rawModel.getLatestUpdate());
+      outMap.put(Symbol, rawModel.getSymbol());
+      outMap.put(LatestPrice, rawModel.getLatestPrice());
+
+      adapterPipeline.process(outMap);
+    } catch (
+            IOException e) {
+      e.printStackTrace();
+    }
+  }
+
+  @Override
+  protected PollingSettings getPollingInterval() {
+    return PollingSettings.from(TimeUnit.SECONDS, 5);
+  }
+
+  @Override
+  public Adapter getInstance(SpecificAdapterStreamDescription adapterDescription) {
+    return new IexCloudStockAdapter(adapterDescription);
+  }
+
+  @Override
+  public GuessSchema getSchema(SpecificAdapterStreamDescription adapterDescription) throws AdapterException, ParseException {
+    return GuessSchemaBuilder.create()
+            .property(EpProperties.timestampProperty(LatestUpdate))
+            .property(EpProperties.stringEp(Labels.from("symbol", "Symbol",
+                    "The stock symbol"), Symbol, SO.Text))
+            .property(EpProperties.doubleEp(Labels.from("latest-price", "Latest price",
+                    "The latest stock price"), LatestPrice, SO.Number))
+            .build();
+  }
+
+  @Override
+  public String getId() {
+    return ID;
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/iex/model/IexNewsData.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/iex/model/IexNewsData.java
new file mode 100644
index 0000000..85621e5
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/iex/model/IexNewsData.java
@@ -0,0 +1,120 @@
+/*
+ * 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.connect.adapters.iex.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class IexNewsData {
+
+    @SerializedName("datetime")
+    private Long mDatetime;
+    @SerializedName("hasPaywall")
+    private Boolean mHasPaywall;
+    @SerializedName("headline")
+    private String mHeadline;
+    @SerializedName("image")
+    private String mImage;
+    @SerializedName("lang")
+    private String mLang;
+    @SerializedName("related")
+    private String mRelated;
+    @SerializedName("source")
+    private String mSource;
+    @SerializedName("summary")
+    private String mSummary;
+    @SerializedName("url")
+    private String mUrl;
+
+    public Long getDatetime() {
+        return mDatetime;
+    }
+
+    public void setDatetime(Long datetime) {
+        mDatetime = datetime;
+    }
+
+    public Boolean getHasPaywall() {
+        return mHasPaywall;
+    }
+
+    public void setHasPaywall(Boolean hasPaywall) {
+        mHasPaywall = hasPaywall;
+    }
+
+    public String getHeadline() {
+        return mHeadline;
+    }
+
+    public void setHeadline(String headline) {
+        mHeadline = headline;
+    }
+
+    public String getImage() {
+        return mImage;
+    }
+
+    public void setImage(String image) {
+        mImage = image;
+    }
+
+    public String getLang() {
+        return mLang;
+    }
+
+    public void setLang(String lang) {
+        mLang = lang;
+    }
+
+    public String getRelated() {
+        return mRelated;
+    }
+
+    public void setRelated(String related) {
+        mRelated = related;
+    }
+
+    public String getSource() {
+        return mSource;
+    }
+
+    public void setSource(String source) {
+        mSource = source;
+    }
+
+    public String getSummary() {
+        return mSummary;
+    }
+
+    public void setSummary(String summary) {
+        mSummary = summary;
+    }
+
+    public String getUrl() {
+        return mUrl;
+    }
+
+    public void setUrl(String url) {
+        mUrl = url;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/iex/model/IexStockData.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/iex/model/IexStockData.java
new file mode 100644
index 0000000..b3d0f44
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/iex/model/IexStockData.java
@@ -0,0 +1,410 @@
+/*
+ * 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.connect.adapters.iex.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class IexStockData {
+
+    @SerializedName("avgTotalVolume")
+    private Long mAvgTotalVolume;
+    @SerializedName("calculationPrice")
+    private String mCalculationPrice;
+    @SerializedName("change")
+    private Double mChange;
+    @SerializedName("changePercent")
+    private Double mChangePercent;
+    @SerializedName("close")
+    private Double mClose;
+    @SerializedName("closeTime")
+    private Long mCloseTime;
+    @SerializedName("companyName")
+    private String mCompanyName;
+    @SerializedName("delayedPrice")
+    private Double mDelayedPrice;
+    @SerializedName("delayedPriceTime")
+    private Long mDelayedPriceTime;
+    @SerializedName("extendedChange")
+    private Double mExtendedChange;
+    @SerializedName("extendedChangePercent")
+    private Double mExtendedChangePercent;
+    @SerializedName("extendedPrice")
+    private Double mExtendedPrice;
+    @SerializedName("extendedPriceTime")
+    private Long mExtendedPriceTime;
+    @SerializedName("high")
+    private Double mHigh;
+    @SerializedName("iexAskPrice")
+    private Long mIexAskPrice;
+    @SerializedName("iexAskSize")
+    private Long mIexAskSize;
+    @SerializedName("iexBidPrice")
+    private Long mIexBidPrice;
+    @SerializedName("iexBidSize")
+    private Long mIexBidSize;
+    @SerializedName("iexLastUpdated")
+    private Long mIexLastUpdated;
+    @SerializedName("iexMarketPercent")
+    private Double mIexMarketPercent;
+    @SerializedName("iexRealtimePrice")
+    private Double mIexRealtimePrice;
+    @SerializedName("iexRealtimeSize")
+    private Long mIexRealtimeSize;
+    @SerializedName("iexVolume")
+    private Long mIexVolume;
+    @SerializedName("latestPrice")
+    private Double mLatestPrice;
+    @SerializedName("latestSource")
+    private String mLatestSource;
+    @SerializedName("latestTime")
+    private String mLatestTime;
+    @SerializedName("latestUpdate")
+    private Long mLatestUpdate;
+    @SerializedName("latestVolume")
+    private Long mLatestVolume;
+    @SerializedName("low")
+    private Double mLow;
+    @SerializedName("marketCap")
+    private Long mMarketCap;
+    @SerializedName("open")
+    private Double mOpen;
+    @SerializedName("openTime")
+    private Long mOpenTime;
+    @SerializedName("peRatio")
+    private Double mPeRatio;
+    @SerializedName("previousClose")
+    private Double mPreviousClose;
+    @SerializedName("symbol")
+    private String mSymbol;
+    @SerializedName("week52High")
+    private Double mWeek52High;
+    @SerializedName("week52Low")
+    private Long mWeek52Low;
+    @SerializedName("ytdChange")
+    private Double mYtdChange;
+
+    public Long getAvgTotalVolume() {
+        return mAvgTotalVolume;
+    }
+
+    public void setAvgTotalVolume(Long avgTotalVolume) {
+        mAvgTotalVolume = avgTotalVolume;
+    }
+
+    public String getCalculationPrice() {
+        return mCalculationPrice;
+    }
+
+    public void setCalculationPrice(String calculationPrice) {
+        mCalculationPrice = calculationPrice;
+    }
+
+    public Double getChange() {
+        return mChange;
+    }
+
+    public void setChange(Double change) {
+        mChange = change;
+    }
+
+    public Double getChangePercent() {
+        return mChangePercent;
+    }
+
+    public void setChangePercent(Double changePercent) {
+        mChangePercent = changePercent;
+    }
+
+    public Double getClose() {
+        return mClose;
+    }
+
+    public void setClose(Double close) {
+        mClose = close;
+    }
+
+    public Long getCloseTime() {
+        return mCloseTime;
+    }
+
+    public void setCloseTime(Long closeTime) {
+        mCloseTime = closeTime;
+    }
+
+    public String getCompanyName() {
+        return mCompanyName;
+    }
+
+    public void setCompanyName(String companyName) {
+        mCompanyName = companyName;
+    }
+
+    public Double getDelayedPrice() {
+        return mDelayedPrice;
+    }
+
+    public void setDelayedPrice(Double delayedPrice) {
+        mDelayedPrice = delayedPrice;
+    }
+
+    public Long getDelayedPriceTime() {
+        return mDelayedPriceTime;
+    }
+
+    public void setDelayedPriceTime(Long delayedPriceTime) {
+        mDelayedPriceTime = delayedPriceTime;
+    }
+
+    public Double getExtendedChange() {
+        return mExtendedChange;
+    }
+
+    public void setExtendedChange(Double extendedChange) {
+        mExtendedChange = extendedChange;
+    }
+
+    public Double getExtendedChangePercent() {
+        return mExtendedChangePercent;
+    }
+
+    public void setExtendedChangePercent(Double extendedChangePercent) {
+        mExtendedChangePercent = extendedChangePercent;
+    }
+
+    public Double getExtendedPrice() {
+        return mExtendedPrice;
+    }
+
+    public void setExtendedPrice(Double extendedPrice) {
+        mExtendedPrice = extendedPrice;
+    }
+
+    public Long getExtendedPriceTime() {
+        return mExtendedPriceTime;
+    }
+
+    public void setExtendedPriceTime(Long extendedPriceTime) {
+        mExtendedPriceTime = extendedPriceTime;
+    }
+
+    public Double getHigh() {
+        return mHigh;
+    }
+
+    public void setHigh(Double high) {
+        mHigh = high;
+    }
+
+    public Long getIexAskPrice() {
+        return mIexAskPrice;
+    }
+
+    public void setIexAskPrice(Long iexAskPrice) {
+        mIexAskPrice = iexAskPrice;
+    }
+
+    public Long getIexAskSize() {
+        return mIexAskSize;
+    }
+
+    public void setIexAskSize(Long iexAskSize) {
+        mIexAskSize = iexAskSize;
+    }
+
+    public Long getIexBidPrice() {
+        return mIexBidPrice;
+    }
+
+    public void setIexBidPrice(Long iexBidPrice) {
+        mIexBidPrice = iexBidPrice;
+    }
+
+    public Long getIexBidSize() {
+        return mIexBidSize;
+    }
+
+    public void setIexBidSize(Long iexBidSize) {
+        mIexBidSize = iexBidSize;
+    }
+
+    public Long getIexLastUpdated() {
+        return mIexLastUpdated;
+    }
+
+    public void setIexLastUpdated(Long iexLastUpdated) {
+        mIexLastUpdated = iexLastUpdated;
+    }
+
+    public Double getIexMarketPercent() {
+        return mIexMarketPercent;
+    }
+
+    public void setIexMarketPercent(Double iexMarketPercent) {
+        mIexMarketPercent = iexMarketPercent;
+    }
+
+    public Double getIexRealtimePrice() {
+        return mIexRealtimePrice;
+    }
+
+    public void setIexRealtimePrice(Double iexRealtimePrice) {
+        mIexRealtimePrice = iexRealtimePrice;
+    }
+
+    public Long getIexRealtimeSize() {
+        return mIexRealtimeSize;
+    }
+
+    public void setIexRealtimeSize(Long iexRealtimeSize) {
+        mIexRealtimeSize = iexRealtimeSize;
+    }
+
+    public Long getIexVolume() {
+        return mIexVolume;
+    }
+
+    public void setIexVolume(Long iexVolume) {
+        mIexVolume = iexVolume;
+    }
+
+    public Double getLatestPrice() {
+        return mLatestPrice;
+    }
+
+    public void setLatestPrice(Double latestPrice) {
+        mLatestPrice = latestPrice;
+    }
+
+    public String getLatestSource() {
+        return mLatestSource;
+    }
+
+    public void setLatestSource(String latestSource) {
+        mLatestSource = latestSource;
+    }
+
+    public String getLatestTime() {
+        return mLatestTime;
+    }
+
+    public void setLatestTime(String latestTime) {
+        mLatestTime = latestTime;
+    }
+
+    public Long getLatestUpdate() {
+        return mLatestUpdate;
+    }
+
+    public void setLatestUpdate(Long latestUpdate) {
+        mLatestUpdate = latestUpdate;
+    }
+
+    public Long getLatestVolume() {
+        return mLatestVolume;
+    }
+
+    public void setLatestVolume(Long latestVolume) {
+        mLatestVolume = latestVolume;
+    }
+
+    public Double getLow() {
+        return mLow;
+    }
+
+    public void setLow(Double low) {
+        mLow = low;
+    }
+
+    public Long getMarketCap() {
+        return mMarketCap;
+    }
+
+    public void setMarketCap(Long marketCap) {
+        mMarketCap = marketCap;
+    }
+
+    public Double getOpen() {
+        return mOpen;
+    }
+
+    public void setOpen(Double open) {
+        mOpen = open;
+    }
+
+    public Long getOpenTime() {
+        return mOpenTime;
+    }
+
+    public void setOpenTime(Long openTime) {
+        mOpenTime = openTime;
+    }
+
+    public Double getPeRatio() {
+        return mPeRatio;
+    }
+
+    public void setPeRatio(Double peRatio) {
+        mPeRatio = peRatio;
+    }
+
+    public Double getPreviousClose() {
+        return mPreviousClose;
+    }
+
+    public void setPreviousClose(Double previousClose) {
+        mPreviousClose = previousClose;
+    }
+
+    public String getSymbol() {
+        return mSymbol;
+    }
+
+    public void setSymbol(String symbol) {
+        mSymbol = symbol;
+    }
+
+    public Double getWeek52High() {
+        return mWeek52High;
+    }
+
+    public void setWeek52High(Double week52High) {
+        mWeek52High = week52High;
+    }
+
+    public Long getWeek52Low() {
+        return mWeek52Low;
+    }
+
+    public void setWeek52Low(Long week52Low) {
+        mWeek52Low = week52Low;
+    }
+
+    public Double getYtdChange() {
+        return mYtdChange;
+    }
+
+    public void setYtdChange(Double ytdChange) {
+        mYtdChange = ytdChange;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/influxdb/InfluxDbClient.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/influxdb/InfluxDbClient.java
new file mode 100644
index 0000000..723abc9
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/influxdb/InfluxDbClient.java
@@ -0,0 +1,321 @@
+/*
+ * 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.connect.adapters.influxdb;
+
+import org.influxdb.InfluxDB;
+import org.influxdb.InfluxDBFactory;
+import org.influxdb.InfluxDBIOException;
+import org.influxdb.dto.Pong;
+import org.influxdb.dto.Query;
+import org.influxdb.dto.QueryResult;
+import org.apache.streampipes.commons.exceptions.SpRuntimeException;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.model.schema.EventProperty;
+import org.apache.streampipes.model.schema.EventSchema;
+import org.apache.streampipes.sdk.builder.PrimitivePropertyBuilder;
+import org.apache.streampipes.sdk.utils.Datatypes;
+
+import java.time.Instant;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.TemporalAccessor;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.streampipes.vocabulary.SO.DateTime;
+
+public class InfluxDbClient {
+
+    private InfluxDB influxDb;
+
+    static final String HOST = "influxDbHost";
+    static final String PORT = "influxDbPort";
+    static final String DATABASE = "influxDbDatabase";
+    static final String MEASUREMENT = "influxDbMeasurement";
+    static final String USERNAME = "influxDbUsername";
+    static final String PASSWORD = "influxDbPassword";
+
+    static final String REPLACE_NULL_VALUES = "replaceNullValues";
+    static final String DO_REPLACE = "doReplace";
+    static final String DO_NOT_REPLACE = "doNotReplace";
+
+    private String host;
+    private int port;
+    private String database;
+    private String measurement;
+    private String username;
+    private String password;
+
+    private boolean replaceNullValues;
+
+    private List<Column> columns;
+    private String columnsString;
+
+    private boolean connected;
+
+    public static class Column {
+        private String name;
+        private Datatypes datatypes;
+
+        Column(String name, Datatypes datatypes) {
+            this.name = name;
+            this.datatypes = datatypes;
+        }
+
+        String getName() {
+            return name;
+        }
+
+        Datatypes getDatatypes() {
+            return datatypes;
+        }
+    }
+
+    InfluxDbClient(String host,
+                          int port,
+                          String database,
+                          String measurement,
+                          String username,
+                          String password,
+                          boolean replaceNullValues) {
+        this.host = host;
+        this.port = port;
+        this.database = database;
+        this.measurement = measurement;
+        this.username = username;
+        this.password = password;
+        this.replaceNullValues = replaceNullValues;
+
+        this.connected = false;
+    }
+
+    public void connect() throws AdapterException {
+        String urlAndPort = host + ":" + port;
+        try {
+            // Connect to the server and check if the server is available
+            influxDb = InfluxDBFactory.connect(urlAndPort, username, password);
+            Pong living = influxDb.ping();
+            if (living.getVersion().equalsIgnoreCase("unknown")) {
+                throw new AdapterException("Could not connect to InfluxDb Server: " + urlAndPort);
+            }
+
+            // Checking whether the database exists
+            if (!databaseExists(database)) {
+                throw new AdapterException("Database " + database + " could not be found.");
+            }
+
+            // Checking, whether the measurement exists
+            if (!measurementExists(measurement)) {
+                throw new AdapterException("Measurement " + measurement + " could not be found.");
+            }
+
+            connected = true;
+        } catch (InfluxDBIOException e) {
+            throw new AdapterException("Problem connecting with the server: " + e.getMessage());
+        }
+    }
+
+    public void disconnect() {
+        if (connected) {
+            influxDb.close();
+            connected = false;
+        }
+    }
+
+    private boolean databaseExists(String dbName) {
+        QueryResult queryResult = influxDb.query(new Query("SHOW DATABASES", ""));
+        for (List<Object> a : queryResult.getResults().get(0).getSeries().get(0).getValues()) {
+            if (a.get(0).equals(dbName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean measurementExists(String measurement) {
+        // Database must exist
+        QueryResult queryResult = influxDb.query(new Query("SHOW MEASUREMENTS", database));
+        for (List<Object> a : queryResult.getResults().get(0).getSeries().get(0).getValues()) {
+            if (a.get(0).equals(measurement)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public GuessSchema getSchema() throws AdapterException {
+        connect();
+        loadColumns();
+
+        EventSchema eventSchema = new EventSchema();
+        GuessSchema guessSchema = new GuessSchema();
+        List<EventProperty> allProperties = new ArrayList<>();
+
+        for (Column column : columns) {
+            PrimitivePropertyBuilder property = PrimitivePropertyBuilder
+                    .create(column.getDatatypes(), column.getName())
+                    .label(column.getName());
+            // Setting the timestamp field to the correct domainProperty
+            if (column.getName().equals("time")) {
+                property.domainProperty(DateTime);
+            }
+            allProperties.add(property.build());
+        }
+
+        eventSchema.setEventProperties(allProperties);
+        guessSchema.setEventSchema(eventSchema);
+
+        disconnect();
+        return guessSchema;
+    }
+
+    // Client must be connected before calling this method
+    void loadColumns() throws AdapterException {
+        if (!connected) {
+            throw new AdapterException("Client must be connected to the server in order to load the columns.");
+        }
+        List<List<Object>> fieldKeys = query("SHOW FIELD KEYS FROM " + measurement);
+        List<List<Object>> tagKeys = query("SHOW TAG KEYS FROM " + measurement);
+//        if (fieldKeys.size() == 0 || tagKeys.size() == 0) {
+        if (fieldKeys.size() == 0) {
+            throw new AdapterException("Error while checking the Schema (does the measurement exist?)");
+        }
+
+        columns = new ArrayList<>();
+        columns.add(new Column("time", Datatypes.Long));
+
+        for (List o : fieldKeys) {
+            // o.get(0): Name, o.get(1): Datatype
+            // Data types: https://docs.influxdata.com/influxdb/v1.7/write_protocols/line_protocol_reference/#data-types
+            String name = o.get(0).toString();
+            Datatypes datatype;
+            switch (o.get(1).toString()) {
+                case "float":
+                    datatype = Datatypes.Float;
+                    break;
+                case "boolean":
+                    datatype = Datatypes.Boolean;
+                    break;
+                case "integer":
+                    datatype = Datatypes.Integer;
+                    break;
+                default:
+                    datatype = Datatypes.String;
+                    break;
+            }
+            columns.add(new Column(name, datatype));
+        }
+        for (List o : tagKeys) {
+            // All tag keys are strings
+            String name = o.get(0).toString();
+            columns.add(new Column(name, Datatypes.String));
+        }
+
+        // Update the column String
+        // Do it only here, because it is needed every time for the query (performance)
+        StringBuilder sb = new StringBuilder();
+        for (Column column : columns) {
+            sb.append(column.getName()).append(", ");
+        }
+        sb.setLength(sb.length() - 2);
+        columnsString = sb.toString();
+    }
+
+    // Returns a list with the entries of the query. If there are no entries, it returns an empty list
+    List<List<Object>> query(String query) {
+        if (!connected) {
+            throw new RuntimeException("InfluxDbClient not connected");
+        }
+        QueryResult queryResult = influxDb.query(new Query(query, database));
+        if (queryResult.getResults().get(0).getSeries() != null) {
+            return queryResult.getResults().get(0).getSeries().get(0).getValues();
+        } else {
+            return new ArrayList<>();
+        }
+    }
+
+    // Returns null, if replaceNullValues == false and if in items is a null value
+    // Otherwise it returns a Map containing the runtimenames and the correctly parsed values
+    Map<String, Object> extractEvent(List<Object> items) throws SpRuntimeException {
+        if (items.size() != columns.size()) {
+            throw new SpRuntimeException("Converter: Item list length is not the same as column list length");
+        }
+        Map<String, Object> out = new HashMap<>();
+
+        // First element is the timestamp, which will be converted to milli seconds
+        TemporalAccessor temporalAccessor = DateTimeFormatter.ISO_INSTANT.parse((String)items.get(0));
+        Instant time = Instant.from(temporalAccessor);
+        out.put("time", time.toEpochMilli());
+
+        for (int i = 1; i < items.size(); i++) {
+            // The order of columns and items is the same, because the order in columnsString (which is used for the
+            // query) is based on the order of columns
+            if (items.get(i) != null) {
+                out.put(columns.get(i).getName(), items.get(i));
+            } else {
+                if (replaceNullValues) {
+                    // Replace null values with defaults
+                    switch (columns.get(i).getDatatypes()) {
+                        case String:
+                            out.put(columns.get(i).getName(), "");
+                            break;
+                        case Integer:
+                            out.put(columns.get(i).getName(), 0);
+                            break;
+                        case Float:
+                            out.put(columns.get(i).getName(), 0.0f);
+                            break;
+                        case Boolean:
+                            out.put(columns.get(i).getName(), false);
+                            break;
+                        default:
+                            throw new SpRuntimeException("Unexpected value: " + columns.get(i).getDatatypes());
+                    }
+                } else {
+                    // One field == null is enough to skip this event
+                    // Or maybe throw an exception instead?
+                    return null;
+                }
+            }
+        }
+        return out;
+    }
+
+    // Converts a string date from ISO_INSTANT format in a unix timestamp in nanoseconds
+    static String getTimestamp(String date) {
+        TemporalAccessor temporalAccessor = DateTimeFormatter.ISO_INSTANT.parse(date);
+
+        Instant time = Instant.from(temporalAccessor);
+        return time.getEpochSecond() + String.format("%09d", time.getNano());
+    }
+
+    String getColumnsString() {
+        return columnsString;
+    }
+
+    String getMeasurement() {
+        return measurement;
+    }
+
+    boolean isConnected() {
+        return connected;
+    }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/influxdb/InfluxDbSetAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/influxdb/InfluxDbSetAdapter.java
new file mode 100644
index 0000000..d92775c
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/influxdb/InfluxDbSetAdapter.java
@@ -0,0 +1,177 @@
+/*
+ * 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.connect.adapters.influxdb;
+
+import org.apache.streampipes.commons.exceptions.SpRuntimeException;
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.exception.ParseException;
+import org.apache.streampipes.connect.adapter.model.specific.SpecificDataSetAdapter;
+import org.apache.streampipes.connect.adapter.sdk.ParameterExtractor;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterSetDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataSetAdapterBuilder;
+import org.apache.streampipes.sdk.helpers.Labels;
+import org.apache.streampipes.sdk.helpers.Options;
+import org.apache.streampipes.sdk.helpers.Tuple2;
+
+import java.util.List;
+import java.util.Map;
+
+public class InfluxDbSetAdapter extends SpecificDataSetAdapter {
+
+    public static final String ID = "http://streampipes.org/adapter/specific/influxdbset";
+    public static final int BATCH_SIZE = 8192;
+
+    private InfluxDbClient influxDbClient;
+    private Thread fetchDataThread;
+
+    public static class FetchDataThread implements Runnable {
+
+        InfluxDbSetAdapter influxDbSetAdapter;
+        InfluxDbClient influxDbClient;
+
+        public FetchDataThread(InfluxDbSetAdapter influxDbSetAdapter) throws AdapterException {
+            this.influxDbSetAdapter = influxDbSetAdapter;
+            this.influxDbClient = influxDbSetAdapter.getInfluxDbClient();
+
+            influxDbClient.connect();
+            influxDbClient.loadColumns();
+        }
+
+        @Override
+        public void run() {
+            if (!influxDbClient.isConnected()) {
+                System.out.println("Cannot start PollingThread, when the client is not connected");
+                return;
+            }
+
+            String oldestTimestamp = "0";
+            while (!Thread.interrupted()) {
+                // Get the next n elements, where the time is > than the last timestamp and send them (if there are some)
+                List<List<Object>> queryResult = influxDbClient.
+                        query("SELECT " + influxDbClient.getColumnsString() + " FROM " + influxDbClient.getMeasurement()
+                                + " WHERE time > " + oldestTimestamp + " ORDER BY time ASC LIMIT " + BATCH_SIZE);
+
+                for (List<Object> event : queryResult) {
+                    try {
+                        influxDbSetAdapter.send(influxDbClient.extractEvent(event));
+                    } catch (SpRuntimeException e) {
+                        System.out.println(e.getMessage());
+                    }
+                }
+                if (queryResult.size() < BATCH_SIZE) {
+                    // The last events or no event at all => Stop
+                    break;
+                } else {
+                    // Get the new timestamp for the new round
+                    oldestTimestamp = InfluxDbClient.getTimestamp((String) queryResult.get(queryResult.size() - 1).get(0));
+                }
+            }
+            influxDbClient.disconnect();
+        }
+    }
+
+    public InfluxDbSetAdapter() {
+    }
+
+    public InfluxDbSetAdapter(SpecificAdapterSetDescription specificAdapterSetDescription) {
+        super(specificAdapterSetDescription);
+
+        getConfigurations(specificAdapterSetDescription);
+    }
+
+    @Override
+    public SpecificAdapterSetDescription declareModel() {
+        SpecificAdapterSetDescription description = SpecificDataSetAdapterBuilder.create(
+                ID,
+                "InfluxDB Set Adapter",
+                "Creates a data set for a InfluxDB measurement")
+                .requiredTextParameter(Labels.from(InfluxDbClient.HOST, "Hostname", "Hostname of the InfluxDB Server"))
+                .requiredIntegerParameter(Labels.from(InfluxDbClient.PORT, "Port", "Port of the InfluxDB Server"))
+                .requiredTextParameter(Labels.from(InfluxDbClient.DATABASE, "Database", "Name of the database"))
+                .requiredTextParameter(Labels.from(InfluxDbClient.MEASUREMENT, "Measurement", "Name of the measurement, which should be observed"))
+                .requiredTextParameter(Labels.from(InfluxDbClient.USERNAME, "Username", "The username to log into the InfluxDB"))
+                .requiredSecret(Labels.from(InfluxDbClient.PASSWORD, "Password", "The password to log into the InfluxDB"))
+                .requiredSingleValueSelection(Labels.from(InfluxDbClient.REPLACE_NULL_VALUES, "Replace Null Values", "Should null values in the incoming data be replace by defaults? If not, these events are skipped"),
+                        Options.from(
+                                new Tuple2<>("Yes", InfluxDbClient.DO_REPLACE),
+                                new Tuple2<>("No", InfluxDbClient.DO_NOT_REPLACE)))
+                .build();
+
+        description.setAppId(ID);
+        return description;
+    }
+
+    @Override
+    public void startAdapter() throws AdapterException {
+        fetchDataThread = new Thread(new FetchDataThread(this));
+        fetchDataThread.start();
+    }
+
+    @Override
+    public void stopAdapter() throws AdapterException {
+        fetchDataThread.interrupt();
+        try {
+            fetchDataThread.join();
+        } catch (InterruptedException e) {
+            throw new AdapterException("Unexpected Error while joining polling thread: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public Adapter getInstance(SpecificAdapterSetDescription adapterDescription) {
+        return new InfluxDbSetAdapter(adapterDescription);
+    }
+
+    @Override
+    public GuessSchema getSchema(SpecificAdapterSetDescription adapterDescription)
+            throws AdapterException, ParseException {
+        getConfigurations(adapterDescription);
+        return influxDbClient.getSchema();
+    }
+
+    @Override
+    public String getId() {
+        return ID;
+    }
+
+    private void send(Map<String, Object> map) {
+        adapterPipeline.process(map);
+    }
+
+    private void getConfigurations(SpecificAdapterSetDescription adapterDescription) {
+        ParameterExtractor extractor = new ParameterExtractor(adapterDescription.getConfig());
+
+        String replace = extractor.selectedSingleValueInternalName(InfluxDbClient.REPLACE_NULL_VALUES);
+
+        influxDbClient = new InfluxDbClient(
+                extractor.singleValue(InfluxDbClient.HOST, String.class),
+                extractor.singleValue(InfluxDbClient.PORT, Integer.class),
+                extractor.singleValue(InfluxDbClient.DATABASE, String.class),
+                extractor.singleValue(InfluxDbClient.MEASUREMENT, String.class),
+                extractor.singleValue(InfluxDbClient.USERNAME, String.class),
+                extractor.secretValue(InfluxDbClient.PASSWORD),
+                replace.equals(InfluxDbClient.DO_REPLACE));
+    }
+
+    public InfluxDbClient getInfluxDbClient() {
+        return influxDbClient;
+    }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/influxdb/InfluxDbStreamAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/influxdb/InfluxDbStreamAdapter.java
new file mode 100644
index 0000000..5a06a7e
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/influxdb/InfluxDbStreamAdapter.java
@@ -0,0 +1,211 @@
+/*
+ * 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.connect.adapters.influxdb;
+
+import org.apache.streampipes.commons.exceptions.SpRuntimeException;
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.exception.ParseException;
+import org.apache.streampipes.connect.adapter.model.specific.SpecificDataStreamAdapter;
+import org.apache.streampipes.connect.adapter.sdk.ParameterExtractor;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataStreamAdapterBuilder;
+import org.apache.streampipes.sdk.helpers.Labels;
+import org.apache.streampipes.sdk.helpers.Options;
+import org.apache.streampipes.sdk.helpers.Tuple2;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.streampipes.connect.adapters.influxdb.InfluxDbClient.getTimestamp;
+
+public class InfluxDbStreamAdapter extends SpecificDataStreamAdapter {
+
+    public static final String ID = "http://streampipes.org/adapter/specific/influxdbstream";
+
+    private static final String POLLING_INTERVAL = "pollingInterval";
+
+    private InfluxDbClient influxDbClient;
+
+    private Thread pollingThread;
+    private int pollingInterval;
+
+    public static class PollingThread implements Runnable {
+        private int pollingInterval;
+
+        private InfluxDbClient influxDbClient;
+        private InfluxDbStreamAdapter influxDbStreamAdapter;
+
+        PollingThread(InfluxDbStreamAdapter influxDbStreamAdapter, int pollingInterval) throws AdapterException {
+            this.pollingInterval = pollingInterval;
+            this.influxDbStreamAdapter = influxDbStreamAdapter;
+            this.influxDbClient = influxDbStreamAdapter.getInfluxDbClient();
+
+            influxDbClient.connect();
+            influxDbClient.loadColumns();
+        }
+
+        @Override
+        public void run() {
+            if (!influxDbClient.isConnected()) {
+                System.out.println("Cannot start PollingThread, when the client is not connected");
+                return;
+            }
+            // Checking the most recent timestamp
+            // Timestamp is a string, because a long might not be big enough (it includes nano seconds)
+            String lastTimestamp;
+            try {
+                lastTimestamp = getNewestTimestamp();
+            } catch (SpRuntimeException e) {
+                System.out.println(e.getMessage());
+                return;
+            }
+
+            while (!Thread.interrupted()) {
+                try {
+                    Thread.sleep(pollingInterval);
+                } catch (InterruptedException e) {
+                    break;
+                }
+                List<List<Object>> queryResult = influxDbClient.query("SELECT " + influxDbClient.getColumnsString()
+                        + " FROM " + influxDbClient.getMeasurement() + " WHERE time > " + lastTimestamp + " ORDER BY time ASC ");
+                if (queryResult.size() > 0) {
+                    // The last element has the highest timestamp (ordered asc) -> Set the new latest timestamp
+                    lastTimestamp = getTimestamp((String)queryResult.get(queryResult.size() - 1).get(0));
+
+                    for (List<Object> value : queryResult) {
+                        try {
+                            Map<String, Object> out = influxDbClient.extractEvent(value);
+                            if (out != null) {
+                                influxDbStreamAdapter.send(out);
+                            }
+                        } catch (SpRuntimeException e) {
+                            System.out.println("Error: " + e.getMessage());
+                        }
+                    }
+                }
+            }
+            influxDbClient.disconnect();
+        }
+
+        // Returns the newest timestamp in the measurement as unix timestamp in Nanoseconds.
+        // If no entry is found, a SpRuntimeException is thrown
+        String getNewestTimestamp() throws SpRuntimeException {
+            List<List<Object>> queryResult = influxDbClient.query("SELECT * FROM " + influxDbClient.getMeasurement()
+                    + " ORDER BY time DESC LIMIT 1");
+            if (queryResult.size() > 0) {
+                return getTimestamp((String)queryResult.get(0).get(0));
+            } else {
+                throw new SpRuntimeException("No entry found in query");
+            }
+        }
+    }
+
+    private InfluxDbClient getInfluxDbClient() {
+        return influxDbClient;
+    }
+
+    public InfluxDbStreamAdapter() {
+    }
+
+    public InfluxDbStreamAdapter(SpecificAdapterStreamDescription specificAdapterStreamDescription) {
+        super(specificAdapterStreamDescription);
+
+        getConfigurations(specificAdapterStreamDescription);
+    }
+
+    @Override
+    public SpecificAdapterStreamDescription declareModel() {
+        SpecificAdapterStreamDescription description = SpecificDataStreamAdapterBuilder.create(
+                ID,
+                "InfluxDB Stream Adapter",
+                "Creates a data stream for a InfluxDB measurement")
+                .requiredTextParameter(Labels.from(InfluxDbClient.HOST, "Hostname", "Hostname of the InfluxDB Server (needs an \"http://\" in front)"))
+                .requiredIntegerParameter(Labels.from(InfluxDbClient.PORT, "Port", "Port of the InfluxDB Server (e.g. 8086"), 8086)
+                .requiredTextParameter(Labels.from(InfluxDbClient.DATABASE, "Database", "Name of the database"))
+                .requiredTextParameter(Labels.from(InfluxDbClient.MEASUREMENT, "Measurement", "Name of the measurement, which should be observed"))
+                .requiredTextParameter(Labels.from(InfluxDbClient.USERNAME, "Username", "The username to log into the InfluxDB"))
+                .requiredSecret(Labels.from(InfluxDbClient.PASSWORD, "Password", "The password to log into the InfluxDB"))
+                .requiredIntegerParameter(Labels.from(POLLING_INTERVAL, "Polling interval (MS)", "How often the database should be checked for new entries (in MS)"))
+                .requiredSingleValueSelection(Labels.from(InfluxDbClient.REPLACE_NULL_VALUES, "Replace Null Values", "Should null values in the incoming data be replace by defaults? If not, these events are skipped"),
+                        Options.from(
+                                new Tuple2<>("Yes", InfluxDbClient.DO_REPLACE),
+                                new Tuple2<>("No", InfluxDbClient.DO_NOT_REPLACE)))
+                .build();
+
+        description.setAppId(ID);
+        return description;
+    }
+
+    @Override
+    public void startAdapter() throws AdapterException {
+        pollingThread = new Thread(new PollingThread(this, pollingInterval));
+        pollingThread.start();
+    }
+
+    @Override
+    public void stopAdapter() throws AdapterException {
+        // Signaling the thread to stop and then disconnect from the server
+        pollingThread.interrupt();
+        try {
+            pollingThread.join();
+        } catch (InterruptedException e) {
+            throw new AdapterException("Unexpected Error while joining polling thread: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public Adapter getInstance(SpecificAdapterStreamDescription adapterDescription) {
+        return new InfluxDbStreamAdapter(adapterDescription);
+    }
+
+    @Override
+    public GuessSchema getSchema(SpecificAdapterStreamDescription adapterDescription)
+            throws AdapterException, ParseException {
+        getConfigurations(adapterDescription);
+        return influxDbClient.getSchema();
+    }
+
+    @Override
+    public String getId() {
+        return ID;
+    }
+
+    private void send(Map<String, Object> map) {
+        adapterPipeline.process(map);
+    }
+
+    private void getConfigurations(SpecificAdapterStreamDescription adapterDescription) {
+        ParameterExtractor extractor = new ParameterExtractor(adapterDescription.getConfig());
+
+        pollingInterval = extractor.singleValue(POLLING_INTERVAL, Integer.class);
+        String replace = extractor.selectedSingleValueInternalName(InfluxDbClient.REPLACE_NULL_VALUES);
+
+        influxDbClient = new InfluxDbClient(
+                extractor.singleValue(InfluxDbClient.HOST, String.class),
+                extractor.singleValue(InfluxDbClient.PORT, Integer.class),
+                extractor.singleValue(InfluxDbClient.DATABASE, String.class),
+                extractor.singleValue(InfluxDbClient.MEASUREMENT, String.class),
+                extractor.singleValue(InfluxDbClient.USERNAME, String.class),
+                extractor.secretValue(InfluxDbClient.PASSWORD),
+                replace.equals(InfluxDbClient.DO_REPLACE));
+
+    }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/mysql/Column.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/mysql/Column.java
new file mode 100644
index 0000000..58c63e2
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/mysql/Column.java
@@ -0,0 +1,76 @@
+/*
+ * 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.connect.adapters.mysql;
+
+import org.apache.streampipes.sdk.utils.Datatypes;
+
+class Column {
+  private String name;
+  private Datatypes type;
+  private Object def;
+
+  Column(String name, String dataType, String columnType) {
+    this.name = name;
+    switch (dataType) {
+      case "tinyint":
+      case "smallint":
+      case "mediumint":
+      case "int":
+      case "bit":
+        this.type = Datatypes.Integer;
+        def = 0;
+        break;
+      case "bigint":
+        this.type = Datatypes.Long;
+        def = 0L;
+        break;
+      case "float":
+      case "decimal":   // Watch out for loss of precision
+      case "double":
+        this.type = Datatypes.Float;
+        def = 0.0f;
+        break;
+      case "text":
+      case "varchar":
+      case "char":
+        this.type = Datatypes.String;
+        def = "";
+        break;
+      default:
+        // date, datetime, time, timestamp, year
+        throw new IllegalArgumentException("Type " + type + " not supported.");
+    }
+    if (columnType.equals("tinyint(1)") || columnType.equals("bit(1)")) {
+      this.type = Datatypes.Boolean;
+      def = Boolean.FALSE;
+    }
+    System.out.println("Found column: " + name + ", type: " + this.type + " (sql-type: "
+        + dataType + ", column-tpye: " + columnType + ")");
+  }
+
+  public String getName() {
+    return name;
+  }
+  public Datatypes getType() {
+    return type;
+  }
+  public Object getDefault() {
+    return def;
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/mysql/MySqlAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/mysql/MySqlAdapter.java
new file mode 100644
index 0000000..61028c0
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/mysql/MySqlAdapter.java
@@ -0,0 +1,259 @@
+/*
+ * 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.connect.adapters.mysql;
+
+import com.github.shyiko.mysql.binlog.BinaryLogClient;
+import com.github.shyiko.mysql.binlog.event.*;
+import com.github.shyiko.mysql.binlog.event.deserialization.EventDeserializer;
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.exception.ParseException;
+import org.apache.streampipes.connect.adapter.model.specific.SpecificDataStreamAdapter;
+import org.apache.streampipes.connect.adapter.sdk.ParameterExtractor;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.model.schema.EventProperty;
+import org.apache.streampipes.model.schema.EventSchema;
+import org.apache.streampipes.sdk.builder.PrimitivePropertyBuilder;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataStreamAdapterBuilder;
+import org.apache.streampipes.sdk.helpers.Labels;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+public class MySqlAdapter extends SpecificDataStreamAdapter {
+
+  public static final String ID = "http://streampipes.org/adapter/specific/mysql";
+
+  private static String MYSQL_HOST = "MYSQL_HOST";
+  private static String MYSQL_USER = "MYSQL_USER";
+  private static String MYSQL_PASS = "MYSQL_PASS";
+  private static String MYSQL_DB = "MYSQL_DB";
+  private static String MYSQL_TABLE = "MYSQL_TABLE";
+  private static String MYSQL_PORT = "MYSQL_PORT";
+
+  private String host;
+  private String user;
+  private String pass;
+  private String database;
+  private String table;
+  private String port;
+
+  private boolean dataComing = false;
+  private List<Column> tableSchema;
+  private BinaryLogClient client;
+
+  public MySqlAdapter() {
+  }
+
+  public MySqlAdapter(SpecificAdapterStreamDescription adapterDescription) {
+    super(adapterDescription);
+
+    getConfigurations(adapterDescription);
+  }
+
+  @Override
+  public SpecificAdapterStreamDescription declareModel() {
+    //TODO: Add Icon
+    SpecificAdapterStreamDescription description = SpecificDataStreamAdapterBuilder.create(ID,
+            "MySql Adapter",
+            "Creates a data stream for a SQL table")
+            .iconUrl("sql.png")
+            .requiredTextParameter(Labels.from(MYSQL_HOST, "Hostname", "Hostname of the MySql Server"))
+            .requiredTextParameter(Labels.from(MYSQL_USER, "Username", "Username of the user"))
+            .requiredTextParameter(Labels.from(MYSQL_PASS, "Password", "Password of the user"))
+            .requiredTextParameter(Labels.from(MYSQL_DB, "Database", "Database in which the table is located"))
+            .requiredTextParameter(Labels.from(MYSQL_TABLE, "Table", "Table which should be watched"))
+            .requiredIntegerParameter(Labels.from(MYSQL_PORT, "Port", "Port of the MySql Server. Default: 3306"), 3306)
+            .build();
+
+    description.setAppId(ID);
+    return  description;
+  }
+
+  @Override
+  public void startAdapter() throws AdapterException {
+    checkJdbcDriver();
+    extractTableInformation();
+
+    // Connect BinaryLogClient
+    client = new BinaryLogClient(host, Integer.parseInt(port), user, pass);
+    EventDeserializer eventDeserializer = new EventDeserializer();
+    eventDeserializer.setCompatibilityMode(
+            EventDeserializer.CompatibilityMode.DATE_AND_TIME_AS_LONG,
+            EventDeserializer.CompatibilityMode.CHAR_AND_BINARY_AS_BYTE_ARRAY
+    );
+    client.setEventDeserializer(eventDeserializer);
+    client.registerEventListener(event -> sendEvent(event));
+    try {
+      client.connect();
+    } catch (IOException e) {
+      throw new AdapterException(e.getMessage());
+    }
+  }
+
+  private void sendEvent(Event event) {
+    // An event can contain multiple insertions/updates
+    if (event.getHeader().getEventType() == EventType.TABLE_MAP) {
+      // Check table and database, if the next event should be streamed
+      if (((TableMapEventData) event.getData()).getDatabase().equals(database)
+              && ((TableMapEventData) event.getData()).getTable().equals((table))) {
+        dataComing = true;
+      }
+    }
+    if (dataComing) {
+      if (EventType.isUpdate(event.getHeader().getEventType())) {
+        for (Entry<Serializable[], Serializable[]> en : ((UpdateRowsEventData) event.getData()).getRows()) {
+          sendChange(en.getValue());
+        }
+        dataComing = false;
+      } else if (EventType.isWrite(event.getHeader().getEventType())) {
+        for (Serializable[] s : ((WriteRowsEventData) event.getData()).getRows()) {
+          sendChange(s);
+        }
+        dataComing = false;
+      }
+    }
+  }
+
+  private void sendChange(Serializable[] rows) {
+    Map<String, Object> out = new HashMap<>();
+    for (int i = 0; i < rows.length; i++) {
+      if (rows[i] != null) {
+        if (rows[i] instanceof byte[]) {
+          // Strings are sent in byte arrays and have to be converted. TODO: Check that encoding is correct
+          out.put(tableSchema.get(i).getName(), new String((byte[])rows[i]));
+        } else {
+          out.put(tableSchema.get(i).getName(), rows[i]);
+        }
+      } else {
+        out.put(tableSchema.get(i).getName(), tableSchema.get(i).getDefault());
+      }
+    }
+    adapterPipeline.process(out);
+  }
+
+  @Override
+  public void stopAdapter() throws AdapterException {
+    try {
+      client.disconnect();
+    } catch (IOException e) {
+      throw new AdapterException("Thrown exception: " + e.getMessage());
+    }
+  }
+
+  @Override
+  public Adapter getInstance(SpecificAdapterStreamDescription adapterDescription) {
+    return new MySqlAdapter(adapterDescription);
+  }
+
+  @Override
+  public GuessSchema getSchema(SpecificAdapterStreamDescription adapterDescription)
+          throws AdapterException, ParseException {
+    // Load JDBC Driver, connect JDBC Driver, Extract information, disconnect JDBC Driver
+    EventSchema eventSchema = new EventSchema();
+    GuessSchema guessSchema = new GuessSchema();
+    List<EventProperty> allProperties = new ArrayList<>();
+
+    getConfigurations(adapterDescription);
+
+    checkJdbcDriver();
+    extractTableInformation();
+
+    for (Column column : tableSchema) {
+      allProperties.add(PrimitivePropertyBuilder
+              .create(column.getType(), database + "." + table + "." + column.getName())
+              .label(column.getName())
+              .build());
+    }
+
+    eventSchema.setEventProperties(allProperties);
+    guessSchema.setEventSchema(eventSchema);
+
+    return guessSchema;
+  }
+
+  @Override
+  public String getId() {
+    return ID;
+  }
+
+  private void getConfigurations(SpecificAdapterStreamDescription adapterDescription) {
+    ParameterExtractor extractor = new ParameterExtractor(adapterDescription.getConfig());
+
+    this.host = extractor.singleValue(MYSQL_HOST, String.class);
+    this.user = extractor.singleValue(MYSQL_USER, String.class);
+    this.pass = extractor.singleValue(MYSQL_PASS, String.class);
+    this.database = extractor.singleValue(MYSQL_DB, String.class);
+    this.table = extractor.singleValue(MYSQL_TABLE, String.class);
+    this.port = extractor.singleValue(MYSQL_PORT, String.class);
+  }
+
+  private void checkJdbcDriver() throws AdapterException {
+    try {
+      Class.forName("com.mysql.cj.jdbc.Driver");
+    } catch (ClassNotFoundException e) {
+      throw new AdapterException("MySql Driver not found.");
+    }
+  }
+
+  private void extractTableInformation() throws AdapterException {
+    String server = "jdbc:mysql://" + host + ":" + port + "/" + "?sslMode=DISABLED&allowPublicKeyRetrieval=true";
+    ResultSet resultSet = null;
+    tableSchema = new ArrayList<>();
+
+    String query = "SELECT COLUMN_NAME, DATA_TYPE, COLUMN_TYPE FROM "
+            + "INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ? AND TABLE_SCHEMA = ? ORDER BY "
+            + "ORDINAL_POSITION ASC;";
+
+    try (Connection con = DriverManager.getConnection(server, user, pass);
+         PreparedStatement statement = con.prepareStatement(query)) {
+
+      statement.setString(1, table);
+      statement.setString(2, database);
+      resultSet = statement.executeQuery();
+
+      if (resultSet.next()) {
+        do {
+          String name = resultSet.getString("COLUMN_NAME");
+          String dataType = resultSet.getString("DATA_TYPE");
+          String columnType = resultSet.getString("COLUMN_TYPE");
+          tableSchema.add(new Column(name, dataType, columnType));
+        } while(resultSet.next());
+      } else {
+        // No columns found -> Table/Database does not exist
+        throw new IllegalArgumentException("Database/table not found");
+      }
+    } catch (SQLException e) {
+      throw new AdapterException("SqlException: " + e.getMessage()
+              + ", Error code: " + e.getErrorCode()
+              + ", SqlState: " + e.getSQLState());
+    } finally {
+      try {
+        resultSet.close();
+      } catch (Exception e) {}
+    }
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/mysql/MySqlClient.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/mysql/MySqlClient.java
new file mode 100644
index 0000000..ae9d66e
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/mysql/MySqlClient.java
@@ -0,0 +1,206 @@
+/*
+ * 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.connect.adapters.mysql;
+
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.model.schema.EventProperty;
+import org.apache.streampipes.model.schema.EventSchema;
+import org.apache.streampipes.sdk.builder.PrimitivePropertyBuilder;
+
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.List;
+
+public class MySqlClient {
+
+  public static final String ID = "http://streampipes.org/adapter/specific/mysql";
+
+  static final String HOST = "mysqlHost";
+  static final String PORT = "mysqlPort";
+  static final String DATABASE = "mysqlDatabase";
+  static final String TABLE = "mysqlTable";
+  static final String USER = "mysqlUser";
+  static final String PASSWORD = "mysqlPassword";
+
+  static final String REPLACE_NULL_VALUES = "replaceNullValues";
+  static final String DO_REPLACE_NULL_VALUES = "doReplaceNullValues";
+  static final String DO_NOT_REPLACE_NULL_VALUES = "doNotReplaceNullValues";
+
+  private String host;
+  private Integer port;
+  private String database;
+  private String table;
+
+  private String username;
+  private String password;
+
+
+  private List<Column> columns;
+
+  Connection connection;
+
+  MySqlClient(String host,
+              int port,
+              String database,
+              String table,
+              String username,
+              String password) {
+    this.host = host;
+    this.port = port;
+    this.database = database;
+    this.table = table;
+    this.username = username;
+    this.password = password;
+
+    connection = null;
+  }
+
+  public void connect() throws AdapterException {
+    checkJdbcDriver();
+    String server = "jdbc:mysql://" + host + ":" + port + "/" + "?sslMode=DISABLED&allowPublicKeyRetrieval=true";
+    try {
+      connection = DriverManager.getConnection(server, username, password);
+    } catch (SQLException e) {
+      throw new AdapterException("Could not connect to server: " + e.getMessage());
+    }
+  }
+
+  public void disconnect() throws AdapterException {
+    if (connection != null) {
+      try {
+        connection.close();
+      } catch (SQLException e) {
+        throw new AdapterException("Error while disconnecting: " + e.getMessage());
+      }
+      connection = null;
+    }
+  }
+
+  public GuessSchema getSchema() throws AdapterException {
+    connect();
+    loadColumns();
+
+    EventSchema eventSchema = new EventSchema();
+    GuessSchema guessSchema = new GuessSchema();
+    List<EventProperty> allProperties = new ArrayList<>();
+
+    for (Column column : columns) {
+      allProperties.add(PrimitivePropertyBuilder
+              .create(column.getType(), column.getName())
+              .label(column.getName())
+              .build());
+    }
+
+    eventSchema.setEventProperties(allProperties);
+    guessSchema.setEventSchema(eventSchema);
+
+    disconnect();
+    return guessSchema;
+  }
+
+  /**
+   * Checks that the MySql-JDBC-Driver is "installed". Throws an AdapterException otherwise
+   */
+  private void checkJdbcDriver() throws AdapterException {
+    try {
+      Class.forName("com.mysql.cj.jdbc.Driver");
+    } catch (ClassNotFoundException e) {
+      throw new AdapterException("MySql Driver not found.");
+    }
+  }
+
+  /**
+   * Fills the columns with the columns from the SQL Table
+   */
+  public void loadColumns() throws AdapterException {
+    if (connection == null) {
+      throw new AdapterException("Client must be connected in order to load the columns");
+    }
+    ResultSet resultSet = null;
+    columns = new ArrayList<>();
+
+    String query = "SELECT COLUMN_NAME, DATA_TYPE, COLUMN_TYPE FROM "
+            + "INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ? AND TABLE_SCHEMA = ? ORDER BY "
+            + "ORDINAL_POSITION ASC;";
+
+    try (PreparedStatement statement = connection.prepareStatement(query)) {
+
+      statement.setString(1, table);
+      statement.setString(2, database);
+      resultSet = statement.executeQuery();
+
+      if (resultSet.next()) {
+        do {
+          String name = resultSet.getString("COLUMN_NAME");
+          String dataType = resultSet.getString("DATA_TYPE");
+          String columnType = resultSet.getString("COLUMN_TYPE");
+          columns.add(new Column(name, dataType, columnType));
+        } while(resultSet.next());
+      } else {
+        // No columns found -> Table/Database does not exist
+        throw new IllegalArgumentException("Database/table not found");
+      }
+    } catch (SQLException e) {
+      throw new AdapterException("SqlException while loading columns: " + e.getMessage()
+              + ", Error code: " + e.getErrorCode()
+              + ", SqlState: " + e.getSQLState());
+    } finally {
+      try {
+        resultSet.close();
+      } catch (Exception e) {}
+    }
+  }
+
+  public String getHost() {
+    return host;
+  }
+
+  public Integer getPort() {
+    return port;
+  }
+
+  public String getDatabase() {
+    return database;
+  }
+
+  public String getTable() {
+    return table;
+  }
+
+  public String getUsername() {
+    return username;
+  }
+
+  public String getPassword() {
+    return password;
+  }
+
+  public List<Column> getColumns() {
+    return columns;
+  }
+
+  public boolean isConnected() {
+    return connection != null;
+  }
+
+  Connection getConnection() {
+    return connection;
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/mysql/MySqlSetAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/mysql/MySqlSetAdapter.java
new file mode 100644
index 0000000..3ee2beb
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/mysql/MySqlSetAdapter.java
@@ -0,0 +1,200 @@
+/*
+ * 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.connect.adapters.mysql;
+
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.exception.ParseException;
+import org.apache.streampipes.connect.adapter.model.specific.SpecificDataSetAdapter;
+import org.apache.streampipes.connect.adapter.sdk.ParameterExtractor;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterSetDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataSetAdapterBuilder;
+import org.apache.streampipes.sdk.helpers.Labels;
+import org.apache.streampipes.sdk.helpers.Options;
+import org.apache.streampipes.sdk.helpers.Tuple2;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.Map;
+
+public class MySqlSetAdapter extends SpecificDataSetAdapter {
+
+    public static final String ID = "http://streampipes.org/adapter/specific/mysqlset";
+
+    private MySqlClient mySqlClient;
+    private Thread fetchDataThread;
+
+    private boolean replaceNullValues;
+
+    public static class FetchDataThread implements Runnable {
+
+        MySqlSetAdapter mySqlSetAdapter;
+        MySqlClient mySqlClient;
+
+        public FetchDataThread(MySqlSetAdapter mySqlSetAdapter) throws AdapterException {
+            this.mySqlSetAdapter = mySqlSetAdapter;
+            this.mySqlClient = mySqlSetAdapter.getMySqlClient();
+
+            mySqlClient.connect();
+            mySqlClient.loadColumns();
+        }
+
+        @Override
+        public void run() {
+            if (!mySqlClient.isConnected()) {
+                System.out.println("Cannot start PollingThread, when the client is not connected");
+                return;
+            }
+            // No batch approach like in the influx adapter due to the lack of a unique key in the table
+            // Create the columnString:
+            StringBuilder sb = new StringBuilder();
+            for (Column column : mySqlClient.getColumns()) {
+                sb.append(column.getName()).append(", ");
+            }
+            sb.setLength(Math.max(0, sb.length() - 2));
+
+            String query = "SELECT " + sb.toString() + " FROM " + mySqlClient.getDatabase() + "." + mySqlClient.getTable();
+
+            try (Statement statement = mySqlClient.getConnection().createStatement()) {
+                boolean executed = statement.execute(query);
+                if (executed) {
+                    ResultSet resultSet = statement.getResultSet();
+                    while (resultSet.next()) {
+                        // Retrieve by column name
+                        Map<String, Object> event = new HashMap<>();
+                        for (Column column : mySqlClient.getColumns()) {
+                            Object in = resultSet.getObject(column.getName());
+                            if (in == null) {
+                                if (mySqlSetAdapter.replaceNullValues) {
+                                    in = column.getDefault();
+                                } else {
+                                    // We do not want to send this event (replaceNullValues == false)
+                                    event = null;
+                                    break;
+                                }
+                            }
+                            event.put(column.getName(), in);
+                        }
+                        if (event != null) {
+                            mySqlSetAdapter.send(event);
+                        }
+                    }
+                    resultSet.close();
+                }
+            } catch (SQLException e) {
+                System.out.println(e.getMessage());
+            }
+
+            try {
+                mySqlClient.disconnect();
+            } catch (AdapterException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public MySqlSetAdapter() {
+    }
+
+    public MySqlSetAdapter(SpecificAdapterSetDescription adapterDescription) {
+        super(adapterDescription);
+
+        getConfigurations(adapterDescription);
+    }
+
+
+    @Override
+    public SpecificAdapterSetDescription declareModel() {
+        SpecificAdapterSetDescription description = SpecificDataSetAdapterBuilder.create(ID,
+                "MySql Set Adapter",
+                "Creates a data set of a SQL table")
+                .requiredTextParameter(Labels.from(MySqlClient.HOST, "Hostname", "Hostname of the MySql Server"))
+                .requiredIntegerParameter(Labels.from(MySqlClient.PORT, "Port", "Port of the MySql Server. Default: 3306"), 3306)
+                .requiredTextParameter(Labels.from(MySqlClient.DATABASE, "Database", "Database in which the table is located"))
+                .requiredTextParameter(Labels.from(MySqlClient.TABLE, "Table", "Table which should be watched"))
+                .requiredTextParameter(Labels.from(MySqlClient.USER, "Username", "Username of the user"))
+                .requiredSecret(Labels.from(MySqlClient.PASSWORD, "Password", "Password of the user"))
+                .requiredSingleValueSelection(Labels.from(MySqlClient.REPLACE_NULL_VALUES, "Replace Null Values", "Should null values in the incoming data be replace by defaults? If not, these events are skipped"),
+                        Options.from(
+                                new Tuple2<>("Yes", MySqlClient.DO_REPLACE_NULL_VALUES),
+                                new Tuple2<>("No", MySqlClient.DO_NOT_REPLACE_NULL_VALUES)))
+                .build();
+
+        description.setAppId(ID);
+        return description;
+    }
+
+    @Override
+    public void startAdapter() throws AdapterException {
+        fetchDataThread = new Thread(new FetchDataThread(this));
+        fetchDataThread.start();
+    }
+
+    @Override
+    public void stopAdapter() throws AdapterException {
+        fetchDataThread.interrupt();
+        try {
+            fetchDataThread.join();
+        } catch (InterruptedException e) {
+            throw new AdapterException("Unexpected Error while joining polling thread: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public Adapter getInstance(SpecificAdapterSetDescription adapterDescription) {
+        return new MySqlSetAdapter(adapterDescription);
+    }
+
+    @Override
+    public GuessSchema getSchema(SpecificAdapterSetDescription adapterDescription) throws AdapterException, ParseException {
+        getConfigurations(adapterDescription);
+        return mySqlClient.getSchema();
+    }
+
+    @Override
+    public String getId() {
+        return ID;
+    }
+
+    private void send(Map<String, Object> map) {
+        adapterPipeline.process(map);
+    }
+
+    private void getConfigurations(SpecificAdapterSetDescription adapterDescription) {
+        ParameterExtractor extractor = new ParameterExtractor(adapterDescription.getConfig());
+
+        String replace = extractor.selectedSingleValueInternalName(MySqlClient.REPLACE_NULL_VALUES);
+        replaceNullValues = replace.equals(MySqlClient.DO_REPLACE_NULL_VALUES);
+
+        mySqlClient = new MySqlClient(
+                extractor.singleValue(MySqlClient.HOST, String.class),
+                extractor.singleValue(MySqlClient.PORT, Integer.class),
+                extractor.singleValue(MySqlClient.DATABASE, String.class),
+                extractor.singleValue(MySqlClient.TABLE, String.class),
+                extractor.singleValue(MySqlClient.USER, String.class),
+                extractor.secretValue(MySqlClient.PASSWORD));
+    }
+
+    public MySqlClient getMySqlClient() {
+        return mySqlClient;
+    }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/mysql/MySqlStreamAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/mysql/MySqlStreamAdapter.java
new file mode 100644
index 0000000..fb69a4e
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/mysql/MySqlStreamAdapter.java
@@ -0,0 +1,199 @@
+/*
+ * 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.connect.adapters.mysql;
+
+import com.github.shyiko.mysql.binlog.BinaryLogClient;
+import com.github.shyiko.mysql.binlog.event.*;
+import com.github.shyiko.mysql.binlog.event.deserialization.EventDeserializer;
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.exception.ParseException;
+import org.apache.streampipes.connect.adapter.model.specific.SpecificDataStreamAdapter;
+import org.apache.streampipes.connect.adapter.sdk.ParameterExtractor;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataStreamAdapterBuilder;
+import org.apache.streampipes.sdk.helpers.Labels;
+import org.apache.streampipes.sdk.helpers.Options;
+import org.apache.streampipes.sdk.helpers.Tuple2;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+public class MySqlStreamAdapter extends SpecificDataStreamAdapter {
+
+    public static final String ID = "http://streampipes.org/adapter/specific/mysqlstream";
+
+    private MySqlClient mySqlClient;
+    private BinaryLogClient binaryLogClient;
+
+    private Thread subscriptionThread  = new Thread(()-> {
+        try {
+            binaryLogClient.connect();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    });
+
+    private boolean replaceNullValues;
+    private boolean dataComing = false;
+
+    public MySqlStreamAdapter() {
+    }
+
+    public MySqlStreamAdapter(SpecificAdapterStreamDescription adapterDescription) {
+        super(adapterDescription);
+
+        getConfigurations(adapterDescription);
+    }
+
+    @Override
+    public SpecificAdapterStreamDescription declareModel() {
+        SpecificAdapterStreamDescription description = SpecificDataStreamAdapterBuilder.create(ID,
+                "MySql Stream Adapter",
+                "Creates a data stream for a SQL table")
+                .requiredTextParameter(Labels.from(MySqlClient.HOST, "Hostname", "Hostname of the MySql Server"))
+                .requiredIntegerParameter(Labels.from(MySqlClient.PORT, "Port", "Port of the MySql Server. Default: 3306"), 3306)
+                .requiredTextParameter(Labels.from(MySqlClient.DATABASE, "Database", "Database in which the table is located"))
+                .requiredTextParameter(Labels.from(MySqlClient.TABLE, "Table", "Table which should be watched"))
+                .requiredTextParameter(Labels.from(MySqlClient.USER, "Username", "Username of the user"))
+                .requiredSecret(Labels.from(MySqlClient.PASSWORD, "Password", "Password of the user"))
+                .requiredSingleValueSelection(Labels.from(MySqlClient.REPLACE_NULL_VALUES, "Replace Null Values", "Should null values in the incoming data be replace by defaults? If not, these events are skipped"),
+                        Options.from(
+                                new Tuple2<>("Yes", MySqlClient.DO_REPLACE_NULL_VALUES),
+                                new Tuple2<>("No", MySqlClient.DO_NOT_REPLACE_NULL_VALUES)))
+                .build();
+
+        description.setAppId(ID);
+        return description;
+    }
+
+    @Override
+    public void startAdapter() throws AdapterException {
+        // Making sure, that the columns are all loaded
+        mySqlClient.connect();
+        mySqlClient.loadColumns();
+        mySqlClient.disconnect();
+
+        // Connect BinaryLogClient
+        binaryLogClient = new BinaryLogClient(
+                mySqlClient.getHost(),
+                mySqlClient.getPort(),
+                mySqlClient.getUsername(),
+                mySqlClient.getPassword());
+
+        EventDeserializer eventDeserializer = new EventDeserializer();
+        eventDeserializer.setCompatibilityMode(
+                EventDeserializer.CompatibilityMode.DATE_AND_TIME_AS_LONG,
+                EventDeserializer.CompatibilityMode.CHAR_AND_BINARY_AS_BYTE_ARRAY
+        );
+        binaryLogClient.setEventDeserializer(eventDeserializer);
+        binaryLogClient.registerEventListener(event -> sendEvent(event));
+        subscriptionThread.start();
+    }
+
+
+    private void sendEvent(Event event) {
+        // An event can contain multiple insertions/updates
+        if (event.getHeader().getEventType() == EventType.TABLE_MAP) {
+            // Check table and database, if the next event should be streamed
+            if (((TableMapEventData) event.getData()).getDatabase().equals(mySqlClient.getDatabase())
+                    && ((TableMapEventData) event.getData()).getTable().equals((mySqlClient.getTable()))) {
+                dataComing = true;
+            }
+        }
+        if (dataComing) {
+            if (EventType.isUpdate(event.getHeader().getEventType())) {
+                for (Map.Entry<Serializable[], Serializable[]> en : ((UpdateRowsEventData) event.getData()).getRows()) {
+                    sendChange(en.getValue());
+                }
+                dataComing = false;
+            } else if (EventType.isWrite(event.getHeader().getEventType())) {
+                for (Serializable[] s : ((WriteRowsEventData) event.getData()).getRows()) {
+                    sendChange(s);
+                }
+                dataComing = false;
+            }
+        }
+    }
+
+    private void sendChange(Serializable[] rows) {
+        Map<String, Object> out = new HashMap<>();
+        for (int i = 0; i < rows.length; i++) {
+            if (rows[i] != null) {
+                if (rows[i] instanceof byte[]) {
+                    // Strings are sent in byte arrays and have to be converted.
+                    //TODO: Check that encoding is correct
+                    out.put(mySqlClient.getColumns().get(i).getName(), new String((byte[])rows[i]));
+                } else {
+                    out.put(mySqlClient.getColumns().get(i).getName(), rows[i]);
+                }
+            } else if (replaceNullValues) {
+                out.put(mySqlClient.getColumns().get(i).getName(), mySqlClient.getColumns().get(i).getDefault());
+            } else {
+                // We should skip events with null values
+                return;
+            }
+        }
+        adapterPipeline.process(out);
+    }
+
+    @Override
+    public void stopAdapter() throws AdapterException {
+        try {
+            binaryLogClient.disconnect();
+            subscriptionThread.join();
+        } catch (IOException | InterruptedException e) {
+            throw new AdapterException("Thrown exception: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public Adapter getInstance(SpecificAdapterStreamDescription adapterDescription) {
+        return new MySqlStreamAdapter(adapterDescription);
+    }
+
+    @Override
+    public GuessSchema getSchema(SpecificAdapterStreamDescription adapterDescription) throws AdapterException, ParseException {
+        getConfigurations(adapterDescription);
+        return mySqlClient.getSchema();
+    }
+
+    @Override
+    public String getId() {
+        return ID;
+    }
+
+    private void getConfigurations(SpecificAdapterStreamDescription adapterDescription) {
+        ParameterExtractor extractor = new ParameterExtractor(adapterDescription.getConfig());
+
+        String replace = extractor.selectedSingleValueInternalName(MySqlClient.REPLACE_NULL_VALUES);
+        replaceNullValues = replace.equals(MySqlClient.DO_REPLACE_NULL_VALUES);
+
+        mySqlClient = new MySqlClient(
+                extractor.singleValue(MySqlClient.HOST, String.class),
+                extractor.singleValue(MySqlClient.PORT, Integer.class),
+                extractor.singleValue(MySqlClient.DATABASE, String.class),
+                extractor.singleValue(MySqlClient.TABLE, String.class),
+                extractor.singleValue(MySqlClient.USER, String.class),
+                extractor.secretValue(MySqlClient.PASSWORD));
+    }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/CameraDataHttpExecutor.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/CameraDataHttpExecutor.java
new file mode 100644
index 0000000..f1d941d
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/CameraDataHttpExecutor.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.connect.adapters.nswaustralia.trafficcamera;
+
+import org.apache.http.client.fluent.Request;
+
+import java.io.IOException;
+
+public class CameraDataHttpExecutor {
+
+  private String imageUrl;
+
+  public CameraDataHttpExecutor(String imageUrl) {
+    this.imageUrl = imageUrl;
+  }
+
+  public byte[] getImageData() throws IOException {
+    return Request
+            .Get(imageUrl)
+            .execute()
+            .returnContent()
+            .asBytes();
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/CameraFeatureTransformer.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/CameraFeatureTransformer.java
new file mode 100644
index 0000000..ec50e7e
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/CameraFeatureTransformer.java
@@ -0,0 +1,66 @@
+/*
+ * 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.connect.adapters.nswaustralia.trafficcamera;
+
+import org.apache.streampipes.connect.adapters.nswaustralia.trafficcamera.model.Feature;
+import org.apache.streampipes.connect.adapters.sensemap.SensorNames;
+
+import java.io.IOException;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+
+public class CameraFeatureTransformer {
+
+  private Feature cameraInfo;
+
+  public CameraFeatureTransformer(Feature cameraInfo) {
+    this.cameraInfo = cameraInfo;
+  }
+
+  public Map<String, Object> toMap() {
+    Map<String, Object> map = new HashMap<>();
+
+    map.put(SensorNames.KEY_TIMESTAMP, System.currentTimeMillis());
+    map.put(TrafficCameraSensorNames.KEY_REGION, cameraInfo.getProperties().getRegion());
+    map.put(TrafficCameraSensorNames.KEY_DIRECTION, cameraInfo.getProperties().getDirection());
+    map.put(TrafficCameraSensorNames.KEY_VIEW, cameraInfo.getProperties().getView());
+    map.put(TrafficCameraSensorNames.KEY_TITLE, cameraInfo.getProperties().getTitle());
+    map.put(TrafficCameraSensorNames.KEY_LATITUDE, cameraInfo.getGeometry().getCoordinates().get
+            (0));
+    map.put(TrafficCameraSensorNames.KEY_LONGITUDE, cameraInfo.getGeometry().getCoordinates().get
+            (1));
+    map.put(TrafficCameraSensorNames.KEY_IMAGE, getImage(cameraInfo.getProperties().getHref()));
+
+    return map;
+  }
+
+  private String getImage(String href) {
+    try {
+      byte[] imageBytes = new CameraDataHttpExecutor(href).getImageData();
+      return toBase64(imageBytes);
+    } catch (IOException e) {
+      e.printStackTrace();
+      return "No image available";
+    }
+  }
+
+  private String toBase64(byte[] imageData) {
+    return Base64.getEncoder().encodeToString(imageData);
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/CameraInfoHttpExecutor.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/CameraInfoHttpExecutor.java
new file mode 100644
index 0000000..3667eda
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/CameraInfoHttpExecutor.java
@@ -0,0 +1,47 @@
+/*
+ * 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.connect.adapters.nswaustralia.trafficcamera;
+
+import com.google.gson.Gson;
+import org.apache.http.client.fluent.Request;
+import org.apache.streampipes.connect.adapters.nswaustralia.trafficcamera.model.FeatureCollection;
+
+import java.io.IOException;
+
+public class CameraInfoHttpExecutor {
+
+  private static final String Url = "https://api.transport.nsw.gov.au/v1/live/cameras";
+
+  private String apiKey;
+
+  public CameraInfoHttpExecutor(String apiKey) {
+    this.apiKey = apiKey;
+  }
+
+  public FeatureCollection getCameraData() throws IOException {
+
+    String response = Request
+            .Get(Url)
+            .addHeader("Authorization", "apiKey " +this.apiKey)
+            .execute()
+            .returnContent()
+            .asString();
+
+    return new Gson().fromJson(response, FeatureCollection.class);
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/NswTrafficCameraAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/NswTrafficCameraAdapter.java
new file mode 100644
index 0000000..4c52757
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/NswTrafficCameraAdapter.java
@@ -0,0 +1,152 @@
+/*
+ * 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.connect.adapters.nswaustralia.trafficcamera;
+
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.util.PollingSettings;
+import org.apache.streampipes.connect.adapters.PullAdapter;
+import org.apache.streampipes.connect.adapters.nswaustralia.trafficcamera.model.Feature;
+import org.apache.streampipes.connect.adapters.nswaustralia.trafficcamera.model.FeatureCollection;
+import org.apache.streampipes.connect.adapters.sensemap.SensorNames;
+import org.apache.streampipes.model.AdapterType;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.model.schema.EventProperty;
+import org.apache.streampipes.model.schema.EventSchema;
+import org.apache.streampipes.sdk.builder.PrimitivePropertyBuilder;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataStreamAdapterBuilder;
+import org.apache.streampipes.sdk.helpers.EpProperties;
+import org.apache.streampipes.sdk.helpers.Labels;
+import org.apache.streampipes.sdk.utils.Datatypes;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+public class NswTrafficCameraAdapter extends PullAdapter {
+
+  public static final String ID = "http://streampipes.org/adapter/specific/nswtrafficcamera";
+  private static final String API_KEY = "";
+
+  public NswTrafficCameraAdapter() {
+    super();
+  }
+
+  public NswTrafficCameraAdapter(SpecificAdapterStreamDescription adapterDescription) {
+    super(adapterDescription);
+  }
+
+  @Override
+  protected void pullData() {
+    List<Map<String, Object>> events = getEvents();
+
+    for (Map<String, Object> event : events) {
+      adapterPipeline.process(event);
+    }
+  }
+
+  @Override
+  protected PollingSettings getPollingInterval() {
+    return PollingSettings.from(TimeUnit.MINUTES, 5);
+  }
+
+  private List<Map<String, Object>> getEvents() {
+    List<Map<String, Object>> events = new ArrayList<>();
+
+    try {
+      FeatureCollection cameras = new CameraInfoHttpExecutor(API_KEY).getCameraData();
+
+      for (Feature cameraInfo : cameras.getFeatures()) {
+        events.add(new CameraFeatureTransformer(cameraInfo).toMap());
+      }
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+
+    return events;
+  }
+
+  @Override
+  public SpecificAdapterStreamDescription declareModel() {
+    SpecificAdapterStreamDescription description = SpecificDataStreamAdapterBuilder.create(ID, "NSW Traffic Cameras", "Traffic camera " +
+            "images produced by NSW Australia")
+            .category(AdapterType.OpenData)
+            .requiredTextParameter(Labels.from("api-key", "API Key", "The TfNSW " +
+                    "API key"))
+            .iconUrl("nsw.png")
+            .build();
+
+    description.setAppId(ID);
+    return description;
+  }
+
+  @Override
+  public Adapter getInstance(SpecificAdapterStreamDescription adapterDescription) {
+    return new NswTrafficCameraAdapter(adapterDescription);
+  }
+
+  @Override
+  public GuessSchema getSchema(SpecificAdapterStreamDescription adapterDescription) {
+
+    EventSchema schema = new EventSchema();
+
+    List<EventProperty> allProperties = new ArrayList<>();
+
+    allProperties.add(EpProperties.timestampProperty(SensorNames.KEY_TIMESTAMP));
+
+    allProperties.add(PrimitivePropertyBuilder
+            .create(Datatypes.String, TrafficCameraSensorNames.KEY_REGION)
+            .label(TrafficCameraSensorNames.LABEL_REGION)
+            .description("The region")
+            .build());
+
+    allProperties.add(PrimitivePropertyBuilder
+            .create(Datatypes.String, TrafficCameraSensorNames.KEY_VIEW)
+            .label(TrafficCameraSensorNames.LABEL_VIEW)
+            .description("The view")
+            .build());
+
+    allProperties.add(PrimitivePropertyBuilder
+            .create(Datatypes.String, TrafficCameraSensorNames.KEY_DIRECTION)
+            .label(TrafficCameraSensorNames.LABEL_DIRECTION)
+            .description("The region")
+            .build());
+
+    allProperties.add(PrimitivePropertyBuilder
+            .create(Datatypes.String, TrafficCameraSensorNames.KEY_IMAGE)
+            .label(TrafficCameraSensorNames.LABEL_IMAGE)
+            .description("The image")
+            .build());
+
+    schema.setEventProperties(allProperties);
+
+    GuessSchema guessSchema = new GuessSchema();
+    guessSchema.setEventSchema(schema);
+    guessSchema.setPropertyProbabilityList(Collections.emptyList());
+
+    return guessSchema;
+  }
+
+  @Override
+  public String getId() {
+    return ID;
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/TrafficCameraSensorNames.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/TrafficCameraSensorNames.java
new file mode 100644
index 0000000..b38e95a
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/TrafficCameraSensorNames.java
@@ -0,0 +1,42 @@
+/*
+ * 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.connect.adapters.nswaustralia.trafficcamera;
+
+public class TrafficCameraSensorNames {
+
+  public static final String KEY_REGION = "region";
+  public static final String LABEL_REGION = "Region";
+
+  public static final String KEY_VIEW = "view";
+  public static final String LABEL_VIEW = "View";
+
+  public static final String KEY_DIRECTION = "direction";
+  public static final String LABEL_DIRECTION = "Direction";
+
+  public static final String KEY_IMAGE = "image";
+  public static final String LABEL_IMAGE = "Image";
+
+  public static final String KEY_TITLE = "title";
+  public static final String LABEL_TITLE = "Title";
+
+  public static final String KEY_LATITUDE = "latitude";
+  public static final String LABEL_LATITUDE = "Latitude";
+
+  public static final String KEY_LONGITUDE = "longitude";
+  public static final String LABEL_LONGITUDE = "Longitude";
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/model/Feature.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/model/Feature.java
new file mode 100644
index 0000000..1277145
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/model/Feature.java
@@ -0,0 +1,69 @@
+/*
+ * 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.connect.adapters.nswaustralia.trafficcamera.model;
+import com.google.gson.annotations.Expose;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class Feature {
+
+    @Expose
+    private Geometry geometry;
+    @Expose
+    private String id;
+    @Expose
+    private Properties properties;
+    @Expose
+    private String type;
+
+    public Geometry getGeometry() {
+        return geometry;
+    }
+
+    public void setGeometry(Geometry geometry) {
+        this.geometry = geometry;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public Properties getProperties() {
+        return properties;
+    }
+
+    public void setProperties(Properties properties) {
+        this.properties = properties;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/model/FeatureCollection.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/model/FeatureCollection.java
new file mode 100644
index 0000000..2286cc5
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/model/FeatureCollection.java
@@ -0,0 +1,62 @@
+/*
+ * 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.connect.adapters.nswaustralia.trafficcamera.model;
+
+import com.google.gson.annotations.Expose;
+
+import java.util.List;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class FeatureCollection {
+
+    @Expose
+    private List<Feature> features;
+    @Expose
+    private Rights rights;
+    @Expose
+    private String type;
+
+    public List<Feature> getFeatures() {
+        return features;
+    }
+
+    public void setFeatures(List<Feature> features) {
+        this.features = features;
+    }
+
+    public Rights getRights() {
+        return rights;
+    }
+
+    public void setRights(Rights rights) {
+        this.rights = rights;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/model/Geometry.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/model/Geometry.java
new file mode 100644
index 0000000..8f61019
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/model/Geometry.java
@@ -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.
+ *
+ */
+
+package org.apache.streampipes.connect.adapters.nswaustralia.trafficcamera.model;
+
+import com.google.gson.annotations.Expose;
+
+import java.util.List;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class Geometry {
+
+    @Expose
+    private List<Double> coordinates;
+    @Expose
+    private String type;
+
+    public List<Double> getCoordinates() {
+        return coordinates;
+    }
+
+    public void setCoordinates(List<Double> coordinates) {
+        this.coordinates = coordinates;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/model/Properties.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/model/Properties.java
new file mode 100644
index 0000000..f8f674f
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/model/Properties.java
@@ -0,0 +1,80 @@
+/*
+ * 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.connect.adapters.nswaustralia.trafficcamera.model;
+
+import com.google.gson.annotations.Expose;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class Properties {
+
+    @Expose
+    private String direction;
+    @Expose
+    private String href;
+    @Expose
+    private String region;
+    @Expose
+    private String title;
+    @Expose
+    private String view;
+
+    public String getDirection() {
+        return direction;
+    }
+
+    public void setDirection(String direction) {
+        this.direction = direction;
+    }
+
+    public String getHref() {
+        return href;
+    }
+
+    public void setHref(String href) {
+        this.href = href;
+    }
+
+    public String getRegion() {
+        return region;
+    }
+
+    public void setRegion(String region) {
+        this.region = region;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getView() {
+        return view;
+    }
+
+    public void setView(String view) {
+        this.view = view;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/model/Rights.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/model/Rights.java
new file mode 100644
index 0000000..a64ecc4
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/nswaustralia/trafficcamera/model/Rights.java
@@ -0,0 +1,50 @@
+/*
+ * 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.connect.adapters.nswaustralia.trafficcamera.model;
+
+import com.google.gson.annotations.Expose;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class Rights {
+
+    @Expose
+    private String copyright;
+    @Expose
+    private String licence;
+
+    public String getCopyright() {
+        return copyright;
+    }
+
+    public void setCopyright(String copyright) {
+        this.copyright = copyright;
+    }
+
+    public String getLicence() {
+        return licence;
+    }
+
+    public void setLicence(String licence) {
+        this.licence = licence;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/opcua/OpcNode.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/opcua/OpcNode.java
new file mode 100644
index 0000000..a9a4040
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/opcua/OpcNode.java
@@ -0,0 +1,59 @@
+/*
+ * 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.connect.adapters.opcua;
+
+import org.eclipse.milo.opcua.stack.core.types.builtin.ExpandedNodeId;
+import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
+import org.apache.streampipes.sdk.utils.Datatypes;
+
+public class OpcNode {
+    String label;
+    Datatypes type;
+    NodeId nodeId;
+
+    public OpcNode(String label, Datatypes type, NodeId nodeId) {
+        this.label = label;
+        this.type = type;
+        this.nodeId = nodeId;
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public void setLabel(String label) {
+        this.label = label;
+    }
+
+    public Datatypes getType() {
+        return type;
+    }
+
+    public void setType(Datatypes type) {
+        this.type = type;
+    }
+
+    public NodeId getNodeId() {
+        return nodeId;
+    }
+
+    public void setNodeId(NodeId nodeId) {
+        this.nodeId = nodeId;
+    }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/opcua/OpcUa.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/opcua/OpcUa.java
new file mode 100644
index 0000000..9185530
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/opcua/OpcUa.java
@@ -0,0 +1,311 @@
+/*
+ * 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.connect.adapters.opcua;
+
+
+import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
+import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig;
+import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaMonitoredItem;
+import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscription;
+import org.eclipse.milo.opcua.stack.client.UaTcpStackClient;
+import org.eclipse.milo.opcua.stack.core.AttributeId;
+import org.eclipse.milo.opcua.stack.core.Identifiers;
+import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
+import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
+import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
+import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
+import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName;
+import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
+import org.eclipse.milo.opcua.stack.core.types.enumerated.*;
+import org.eclipse.milo.opcua.stack.core.types.structured.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.sdk.utils.Datatypes;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.BiConsumer;
+
+import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint;
+import static org.eclipse.milo.opcua.stack.core.util.ConversionUtil.toList;
+
+public class OpcUa {
+
+    static Logger LOG = LoggerFactory.getLogger(OpcUa.class);
+
+    private NodeId node;
+    private String opcServerURL;
+    private OpcUaClient client;
+
+    private static final AtomicLong clientHandles = new AtomicLong(1L);
+
+
+    public OpcUa(String opcServerURL, int namespaceIndex, String nodeId) {
+
+        this.opcServerURL = opcServerURL;
+
+        if (isInteger(nodeId)) {
+            int integerNodeId = Integer.parseInt(nodeId);
+            this.node  = new NodeId(namespaceIndex, integerNodeId);
+        } else {
+            this.node  = new NodeId(namespaceIndex, nodeId);
+        }
+    }
+
+    public OpcUa(String opcServer, int opcServerPort, int namespaceIndex, String nodeId) {
+
+
+        this.opcServerURL = "opc.tcp://" + opcServer + ":" + opcServerPort;
+
+        if (isInteger(nodeId)) {
+            int integerNodeId = Integer.parseInt(nodeId);
+            this.node  = new NodeId(namespaceIndex, integerNodeId);
+        } else {
+            this.node  = new NodeId(namespaceIndex, nodeId);
+        }
+    }
+
+    public OpcUa(int namespaceIndex, String nodeId) {
+        if (isInteger(nodeId)) {
+            int integerNodeId = Integer.parseInt(nodeId);
+            this.node  = new NodeId(namespaceIndex, integerNodeId);
+        } else {
+            this.node  = new NodeId(namespaceIndex, nodeId);
+        }
+
+    }
+
+    public void connect() throws Exception {
+
+        EndpointDescription[] endpoints = UaTcpStackClient.getEndpoints(this.opcServerURL).get();
+        String host = this.opcServerURL.split("://")[1].split(":")[0];
+
+        EndpointDescription tmpEndpoint = Arrays.stream(endpoints).filter(e ->
+            e.getSecurityPolicyUri().equals(SecurityPolicy.None.getSecurityPolicyUri())
+        ).findFirst().orElseThrow(() -> new Exception("No endpoint with security policy none"));
+
+//        EndpointDescription tmpEndpoint = endpoints[0];
+        tmpEndpoint = updateEndpointUrl(tmpEndpoint, host);
+        endpoints = new EndpointDescription[]{tmpEndpoint};
+
+        EndpointDescription endpoint = Arrays.stream(endpoints)
+                .filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getSecurityPolicyUri()))
+                .findFirst().orElseThrow(() -> new Exception("no desired endpoints returned"));
+
+        OpcUaClientConfig config = OpcUaClientConfig.builder()
+                .setApplicationName(LocalizedText.english("eclipse milo opc-ua client"))
+                .setApplicationUri("urn:eclipse:milo:examples:client")
+                .setEndpoint(endpoint)
+                .build();
+
+        this.client = new OpcUaClient(config);
+        client.connect().get();
+    }
+
+    public void disconnect() {
+        client.disconnect();
+    }
+
+    private EndpointDescription updateEndpointUrl(
+            EndpointDescription original, String hostname) throws URISyntaxException {
+
+        URI uri = new URI(original.getEndpointUrl()).parseServerAuthority();
+
+        String endpointUrl = String.format(
+                "%s://%s:%s%s",
+                uri.getScheme(),
+                hostname,
+                uri.getPort(),
+                uri.getPath()
+        );
+
+        return new EndpointDescription(
+                endpointUrl,
+                original.getServer(),
+                original.getServerCertificate(),
+                original.getSecurityMode(),
+                original.getSecurityPolicyUri(),
+                original.getUserIdentityTokens(),
+                original.getTransportProfileUri(),
+                original.getSecurityLevel()
+        );
+    }
+
+    public List<OpcNode> browseNode() throws AdapterException {
+        List<OpcNode> referenceDescriptions = browseNode(node);
+
+        if (referenceDescriptions.size() == 0) {
+            referenceDescriptions = getRootNote(node);
+        }
+
+        return referenceDescriptions;
+    }
+
+    private List<OpcNode> getRootNote(NodeId browseRoot) {
+        List<OpcNode> result = new ArrayList<>();
+
+        try {
+//            VariableNode resultNode = client.getAddressSpace().getVariableNode(browseRoot).get();
+            String label = client.getAddressSpace().getVariableNode(browseRoot).get().getDisplayName().get().getText();
+            Datatypes type = OpcUaTypes.getType((UInteger)client.getAddressSpace().getVariableNode(browseRoot).get().getDataType().get().getIdentifier());
+            NodeId nodeId = client.getAddressSpace().getVariableNode(browseRoot).get().getNodeId().get();
+            result.add(new OpcNode(label, type, nodeId));
+
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            e.printStackTrace();
+        }
+
+        return result;
+    }
+
+    private List<OpcNode> browseNode(NodeId browseRoot) throws AdapterException {
+        List<OpcNode> result = new ArrayList<>();
+
+
+        BrowseDescription browse = new BrowseDescription(
+                browseRoot,
+                BrowseDirection.Forward,
+                Identifiers.References,
+                true,
+                uint(NodeClass.Object.getValue() | NodeClass.Variable.getValue()),
+                uint(BrowseResultMask.All.getValue())
+        );
+
+        try {
+            BrowseResult browseResult = client.browse(browse).get();
+
+            if (browseResult.getStatusCode().isBad()) {
+                throw new AdapterException(browseResult.getStatusCode().toString());
+            }
+
+            List<ReferenceDescription> references = toList(browseResult.getReferences());
+
+            for (ReferenceDescription rd : references) {
+                if (rd.getNodeClass() == NodeClass.Variable) {
+
+                    OpcNode opcNode = new OpcNode( rd.getBrowseName().getName(), OpcUaTypes.getType((UInteger) rd.getTypeDefinition().getIdentifier()), rd.getNodeId().local().get());
+                    rd.getNodeId();
+
+                    result.add(opcNode);
+                    rd.getNodeId().local().ifPresent(nodeId -> {
+                        try {
+                            browseNode(nodeId);
+                        } catch (AdapterException e) {
+                            e.printStackTrace();
+                        }
+                    });
+                }
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            throw new AdapterException("Browsing nodeId=" + browse + " failed: " + e.getMessage());
+        }
+
+        return result;
+
+    }
+
+
+    public void createListSubscription(List<NodeId> nodes, OpcUaAdapter opcUaAdapter) throws Exception {
+        /*
+         * create a subscription @ 1000ms
+         */
+        UaSubscription subscription = this.client.getSubscriptionManager().createSubscription(1000.0).get();
+
+
+        List<CompletableFuture<DataValue>> values = new ArrayList<>();
+
+        for (NodeId node : nodes) {
+            values.add(this.client.readValue(0, TimestampsToReturn.Both, node));
+        }
+
+        for (CompletableFuture<DataValue> value : values) {
+            if (value.get().getValue().toString().contains("null")) {
+                System.out.println("Node has no value");
+            }
+        }
+
+
+        List<ReadValueId> readValues = new ArrayList<>();
+        // Read a specific value attribute
+        for (NodeId node : nodes) {
+            readValues.add(new ReadValueId(node, AttributeId.Value.uid(), null, QualifiedName.NULL_VALUE));
+        }
+
+        List<MonitoredItemCreateRequest> requests = new ArrayList<>();
+
+        for (ReadValueId readValue : readValues) {
+            // important: client handle must be unique per item
+            UInteger clientHandle = uint(clientHandles.getAndIncrement());
+
+            MonitoringParameters parameters = new MonitoringParameters(
+                    clientHandle,
+                    1000.0,     // sampling interval
+                    null,      // filter, null means use default
+                    uint(10),   // queue size
+                    true         // discard oldest
+            );
+
+            requests.add(new MonitoredItemCreateRequest(readValue, MonitoringMode.Reporting, parameters));
+        }
+
+        BiConsumer<UaMonitoredItem, Integer> onItemCreated =
+                (item, id) -> {
+                    item.setValueConsumer(opcUaAdapter::onSubscriptionValue);
+                };
+
+        List<UaMonitoredItem> items = subscription.createMonitoredItems(
+                TimestampsToReturn.Both,
+                requests,
+                onItemCreated
+        ).get();
+
+        for (UaMonitoredItem item : items) {
+            NodeId tagId = item.getReadValueId().getNodeId();
+            if (item.getStatusCode().isGood()) {
+                System.out.println("item created for nodeId="+ tagId);
+            } else {
+                System.out.println("failed to create item for " + item.getReadValueId().getNodeId() + item.getStatusCode());
+            }
+        }
+
+    }
+
+    public static boolean isInteger(String s) {
+        try {
+            Integer.parseInt(s);
+        } catch(NumberFormatException e) {
+            return false;
+        } catch(NullPointerException e) {
+            return false;
+        }
+        // only got here if we didn't return false
+        return true;
+    }
+
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/opcua/OpcUaAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/opcua/OpcUaAdapter.java
new file mode 100644
index 0000000..952274e
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/opcua/OpcUaAdapter.java
@@ -0,0 +1,258 @@
+/*
+ * 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.connect.adapters.opcua;
+
+import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaMonitoredItem;
+import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
+import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.exception.ParseException;
+import org.apache.streampipes.connect.adapter.model.specific.SpecificDataStreamAdapter;
+import org.apache.streampipes.connect.adapter.sdk.ParameterExtractor;
+import org.apache.streampipes.container.api.ResolvesContainerProvidedOptions;
+import org.apache.streampipes.model.AdapterType;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.model.schema.EventProperty;
+import org.apache.streampipes.model.schema.EventSchema;
+import org.apache.streampipes.sdk.StaticProperties;
+import org.apache.streampipes.sdk.builder.PrimitivePropertyBuilder;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataStreamAdapterBuilder;
+import org.apache.streampipes.sdk.extractor.StaticPropertyExtractor;
+import org.apache.streampipes.sdk.helpers.Alternatives;
+import org.apache.streampipes.sdk.helpers.Labels;
+
+import java.util.*;
+
+public class OpcUaAdapter extends SpecificDataStreamAdapter {
+
+    public static final String ID = "http://streampipes.org/adapter/specific/opcua";
+
+    private static final String OPC_HOST_OR_URL = "OPC_HOST_OR_URL";
+    private static final String OPC_URL = "OPC_URL";
+    private static final String OPC_HOST = "OPC_HOST";
+    private static final String OPC_SERVER_URL = "OPC_SERVER_URL";
+    private static final String OPC_SERVER_HOST = "OPC_SERVER_HOST";
+    private static final String OPC_SERVER_PORT = "OPC_SERVER_PORT";
+    private static final String NAMESPACE_INDEX = "NAMESPACE_INDEX";
+    private static final String NODE_ID = "NODE_ID";
+
+    private String opcUaServer;
+    private String namespaceIndex;
+    private String nodeId;
+    private String port;
+    private boolean selectedURL;
+
+    private Map<String, Object> event;
+
+    private OpcUa opcUa;
+
+    private int numberProperties;
+
+
+    public OpcUaAdapter() {
+        this.event = new HashMap<>();
+        this.numberProperties = 0;
+    }
+
+    public OpcUaAdapter(SpecificAdapterStreamDescription adapterDescription) {
+        super(adapterDescription);
+
+        getConfigurations(adapterDescription);
+
+        this.event = new HashMap<>();
+        this.numberProperties = 0;
+    }
+
+    @Override
+    public SpecificAdapterStreamDescription declareModel() {
+
+        SpecificAdapterStreamDescription description = SpecificDataStreamAdapterBuilder.create(ID, "OPC UA", "Reads values from an OPC-UA server")
+                .iconUrl("opc.png")
+                .category(AdapterType.Generic, AdapterType.Manufacturing)
+                .requiredAlternatives(Labels.from(OPC_HOST_OR_URL, "OPC Server", ""),
+                        Alternatives.from(Labels.from(OPC_URL, "URL", ""),
+                                StaticProperties.stringFreeTextProperty(Labels.from(OPC_SERVER_URL, "URL", "Example: opc.tcp://test-server.com:4840"))
+                        ),
+                        Alternatives.from(Labels.from(OPC_HOST, "Host/Port", ""),
+                                StaticProperties.group(Labels.withId("host-port"),
+                                        StaticProperties.stringFreeTextProperty(Labels.from(OPC_SERVER_HOST, "Host", "Example: test-server.com (No leading opc.tcp://) ")),
+                                        StaticProperties.stringFreeTextProperty(Labels.from(OPC_SERVER_PORT, "Port", "Example: 4840")))))
+                .requiredTextParameter(Labels.from(NAMESPACE_INDEX, "Namespace Index", "Example: 2"))
+                .requiredTextParameter(Labels.from(NODE_ID, "Node Id", "Id of the Node to read the values from"))
+                .build();
+        description.setAppId(ID);
+
+
+        return  description;
+    }
+
+    public void onSubscriptionValue(UaMonitoredItem item, DataValue value) {
+
+        String key = getRuntimeNameOfNode(item.getReadValueId().getNodeId());
+
+        event.put(key, value.getValue().getValue());
+
+        // ensure that event is complete and all opc ua subscriptions transmitted at least one value
+        if (event.keySet().size() >= this.numberProperties) {
+            adapterPipeline.process(event);
+        }
+    }
+
+
+    @Override
+    public void startAdapter() throws AdapterException {
+        if (this.selectedURL) {
+            this.opcUa = new OpcUa(opcUaServer, Integer.parseInt(namespaceIndex), nodeId);
+        } else {
+            this.opcUa = new OpcUa(opcUaServer, Integer.parseInt(port), Integer.parseInt(namespaceIndex), nodeId);
+        }
+
+        try {
+            this.opcUa.connect();
+
+            List<OpcNode> allNodes = this.opcUa.browseNode();
+            List<NodeId> nodeIds = new ArrayList<>();
+
+            for (OpcNode rd : allNodes) {
+                nodeIds.add(rd.nodeId);
+            }
+
+            this.numberProperties = nodeIds.size();
+            this.opcUa.createListSubscription(nodeIds, this);
+        } catch (Exception e) {
+            throw new AdapterException("Could not connect to OPC-UA server! Server: " + opcUaServer + " Port: " + port +
+                    " NamespaceIndex: " + namespaceIndex + " NodeId: " + nodeId);
+        }
+    }
+
+    @Override
+    public void stopAdapter() throws AdapterException {
+        // close connection
+        this.opcUa.disconnect();
+    }
+
+    @Override
+    public Adapter getInstance(SpecificAdapterStreamDescription adapterDescription) {
+        return new OpcUaAdapter(adapterDescription);
+    }
+
+    @Override
+    public GuessSchema getSchema(SpecificAdapterStreamDescription adapterDescription) throws AdapterException, ParseException {
+
+        GuessSchema guessSchema = new GuessSchema();
+        EventSchema eventSchema = new EventSchema();
+        List<EventProperty> allProperties = new ArrayList<>();
+
+
+        getConfigurations(adapterDescription);
+        OpcUa opc;
+        if (this.selectedURL) {
+            opc = new OpcUa(opcUaServer, Integer.parseInt(namespaceIndex), nodeId);
+        } else {
+            opc = new OpcUa(opcUaServer, Integer.parseInt(port), Integer.parseInt(namespaceIndex), nodeId);
+        }
+
+        try {
+            opc.connect();
+            List<OpcNode> res =  opc.browseNode();
+
+
+            if (res.size() > 0) {
+                for (OpcNode opcNode : res) {
+
+                    String runtimeName = getRuntimeNameOfNode(opcNode.getNodeId());
+                    allProperties.add(PrimitivePropertyBuilder
+                            .create(opcNode.getType(), runtimeName)
+                            .label(opcNode.getLabel())
+                            .build());
+                }
+            }
+
+            opc.disconnect();
+        } catch (Exception e) {
+
+            throw new AdapterException("Could not guess schema for opc node! " + e.getMessage());
+
+        }
+
+        eventSchema.setEventProperties(allProperties);
+        guessSchema.setEventSchema(eventSchema);
+
+        return guessSchema;
+    }
+
+    @Override
+    public String getId() {
+        return ID;
+    }
+
+    private void getConfigurations(SpecificAdapterStreamDescription adapterDescription) {
+        StaticPropertyExtractor extractor =
+                StaticPropertyExtractor.from(adapterDescription.getConfig(), new ArrayList<>());
+
+        String selectedAlternative = extractor.selectedAlternativeInternalId(OPC_HOST_OR_URL);
+
+        if (selectedAlternative.equals(OPC_URL)) {
+            this.opcUaServer = extractor.singleValueParameter(OPC_SERVER_URL, String.class);
+            this.selectedURL = true;
+        } else {
+            this.opcUaServer = extractor.singleValueParameter(OPC_SERVER_HOST, String.class);
+            this.port = extractor.singleValueParameter(OPC_SERVER_PORT, String.class);
+            this.selectedURL = false;
+        }
+
+        this.namespaceIndex = extractor.singleValueParameter(NAMESPACE_INDEX, String.class);
+        this.nodeId = extractor.singleValueParameter(NODE_ID, String.class);
+    }
+
+//    @Override
+//    public List<Option> resolveOptions(String requestId, StaticPropertyExtractor parameterExtractor) {
+//        String opcUaServer = parameterExtractor.singleValueParameter(OPC_SERVER_HOST, String.class);
+//        int port = parameterExtractor.singleValueParameter(OPC_SERVER_PORT, Integer.class);
+//        int namespaceIndex = parameterExtractor.singleValueParameter(NAMESPACE_INDEX, Integer.class);
+//
+//        OpcUa opc = new OpcUa(opcUaServer, port, namespaceIndex, Identifiers.RootFolder);
+//
+//        try {
+//            opc.connect();
+//            List<OpcNode> res =  opc.browseNode();
+//            System.out.println(res);
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+//
+//        return new ArrayList<>();
+//    }
+
+
+    private String getRuntimeNameOfNode(NodeId nodeId) {
+        String[] keys = nodeId.getIdentifier().toString().split("\\.");
+        String key;
+
+        if (keys.length > 0) {
+            key = keys[keys.length - 1];
+        } else {
+            key = nodeId.getIdentifier().toString();
+        }
+
+        return key;
+    }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/opcua/OpcUaTest.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/opcua/OpcUaTest.java
new file mode 100644
index 0000000..184a933
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/opcua/OpcUaTest.java
@@ -0,0 +1,341 @@
+/*
+ * 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.connect.adapters.opcua;
+
+
+import com.github.jsonldjava.shaded.com.google.common.collect.Lists;
+import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
+import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig;
+import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaMonitoredItem;
+import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscription;
+import org.eclipse.milo.opcua.stack.client.UaTcpStackClient;
+import org.eclipse.milo.opcua.stack.core.AttributeId;
+import org.eclipse.milo.opcua.stack.core.Identifiers;
+import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
+import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
+import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
+import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
+import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName;
+import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
+import org.eclipse.milo.opcua.stack.core.types.enumerated.*;
+import org.eclipse.milo.opcua.stack.core.types.structured.*;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.BiConsumer;
+
+import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint;
+import static org.eclipse.milo.opcua.stack.core.util.ConversionUtil.toList;
+
+public class OpcUaTest {
+
+    //    private OpcUaClient myClient;
+    private static String opcServerURL = "opc.tcp://141.21.12.160:4840";
+    //    private static String opcServerURL = "opc.tcp://192.168.0.144:4840";
+    private static final AtomicLong clientHandles = new AtomicLong(1L);
+
+
+    public static void main(String... args) throws Exception {
+
+        OpcUaClient client = init();
+//        client.connect().get();
+        client.connect().get();
+
+        NodeId node1 = new NodeId(1, "Sensor");
+//        NodeId node2 = new NodeId(4, "|var|CODESYS Control for Raspberry Pi SL.Application.PLC_PRG.auto_rot");
+//        NodeId node3 = new NodeId(4, "|var|CODESYS Control for Raspberry Pi SL.Application.PLC_PRG.fuss_rot");
+//        NodeId node4 = new NodeId(4, "|var|CODESYS Control for Raspberry Pi SL.Application.PLC_PRG");
+
+        browseNodeTest("", client, Identifiers.RootFolder);
+
+//        CompletableFuture<DataValue> va1 = client.readValue(0, TimestampsToReturn.Both, node1);
+//        CompletableFuture<DataValue> va2 = client.readValue(0, TimestampsToReturn.Both, node2);
+//        CompletableFuture<DataValue> va3 = client.readValue(0, TimestampsToReturn.Both, node3);
+//
+//
+//        System.out.println("Auto grün: " + va1.get().getValue());
+//        System.out.println("Auto rot: " + va2.get().getValue());
+//        System.out.println("Fußgänger rot: " + va3.get().getValue());
+
+	 /*   JSONParser parser = new JSONParser();
+	    JSONObject json = (JSONObject) parser.parse(exchange.getIn().getBody().toString());*/
+
+//	 createListSubscription(client, Arrays.asList(node1, node2));
+//        createSubscription(client, node1);
+//        createSubscription(client, node2);
+
+        // let the example run for 10 seconds then terminate
+        Thread.sleep(100000000);
+
+//	 client.disconnect();
+
+    }
+
+
+
+    private static OpcUaClient init() throws Exception{
+        EndpointDescription[] endpoints = UaTcpStackClient.getEndpoints(opcServerURL).get();
+
+        EndpointDescription tmpEndpoint = endpoints[0];
+        tmpEndpoint = updateEndpointUrl(tmpEndpoint, "141.21.12.160");
+        endpoints = new EndpointDescription[]{tmpEndpoint};
+
+        EndpointDescription endpoint = Arrays.stream(endpoints)
+                .filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getSecurityPolicyUri()))
+                .findFirst().orElseThrow(() -> new Exception("no desired endpoints returned"));
+
+        OpcUaClientConfig config = OpcUaClientConfig.builder()
+                .setApplicationName(LocalizedText.english("eclipse milo opc-ua client"))
+                .setApplicationUri("urn:eclipse:milo:examples:client")
+                .setEndpoint(endpoint)
+                .build();
+
+        return new OpcUaClient(config);
+    }
+
+    private static EndpointDescription updateEndpointUrl(
+            EndpointDescription original, String hostname) throws URISyntaxException {
+
+        URI uri = new URI(original.getEndpointUrl()).parseServerAuthority();
+
+        String endpointUrl = String.format(
+                "%s://%s:%s%s",
+                uri.getScheme(),
+                hostname,
+                uri.getPort(),
+                uri.getPath()
+        );
+
+        return new EndpointDescription(
+                endpointUrl,
+                original.getServer(),
+                original.getServerCertificate(),
+                original.getSecurityMode(),
+                original.getSecurityPolicyUri(),
+                original.getUserIdentityTokens(),
+                original.getTransportProfileUri(),
+                original.getSecurityLevel()
+        );
+    }
+
+
+    private static void onSubscriptionValue(UaMonitoredItem item, DataValue value) {
+        System.out.println(
+                "subscription value received: " + item.getReadValueId().toString() + " " + value.getValue().toString());
+
+    }
+
+    private static void createListSubscription(OpcUaClient client, List<NodeId> nodes) throws Exception {
+        /*
+         * create a subscription @ 1000ms
+         */
+        UaSubscription subscription = client.getSubscriptionManager().createSubscription(1000.0).get();
+
+
+        List<CompletableFuture<DataValue>> values = new ArrayList<>();
+
+        for (NodeId node : nodes) {
+            values.add(client.readValue(0, TimestampsToReturn.Both, node));
+        }
+
+        for (CompletableFuture<DataValue> value : values) {
+            if (value.get().getValue().toString().contains("null")) {
+                System.out.println("Node has no value");
+            }
+        }
+
+
+        List<ReadValueId> readValues = new ArrayList<>();
+            // Read a specific value attribute
+        for (NodeId node : nodes) {
+            readValues.add(new ReadValueId(node, AttributeId.Value.uid(), null, QualifiedName.NULL_VALUE));
+        }
+
+            List<MonitoredItemCreateRequest> requests = new ArrayList<>();
+
+            for (ReadValueId readValue : readValues) {
+                // important: client handle must be unique per item
+                UInteger clientHandle = uint(clientHandles.getAndIncrement());
+
+                MonitoringParameters parameters = new MonitoringParameters(
+                        clientHandle,
+                        1000.0,     // sampling interval
+                        null,      // filter, null means use default
+                        uint(10),   // queue size
+                        true         // discard oldest
+                );
+
+                requests.add(new MonitoredItemCreateRequest(readValue, MonitoringMode.Reporting, parameters));
+            }
+
+            BiConsumer<UaMonitoredItem, Integer> onItemCreated =
+                    (item, id) -> {
+                        item.setValueConsumer(OpcUaTest::onSubscriptionValue);
+                    };
+
+            List<UaMonitoredItem> items = subscription.createMonitoredItems(
+                    TimestampsToReturn.Both,
+                    requests,
+                    onItemCreated
+            ).get();
+
+            for (UaMonitoredItem item : items) {
+                NodeId tagId = item.getReadValueId().getNodeId();
+                if (item.getStatusCode().isGood()) {
+                    System.out.println("item created for nodeId="+ tagId);
+                } else {
+                    System.out.println("failed to create item for " + item.getReadValueId().getNodeId() + item.getStatusCode());
+                }
+            }
+
+    }
+
+
+    /**
+     * creates a subcription for the given node
+     *
+     * @param client
+     * @param node
+     * @throws Exception
+     */
+    private static void createSubscription(OpcUaClient client, NodeId node) throws Exception {
+        /*
+         * create a subscription @ 1000ms
+         */
+        UaSubscription subscription = client.getSubscriptionManager().createSubscription(1000.0).get();
+
+        CompletableFuture<DataValue> value = client.readValue(0, TimestampsToReturn.Both, node);
+
+        if (value.get().getValue().toString().contains("null")) {
+            System.out.println("Node has no value");
+        } else {
+            // Read a specific value attribute
+            ReadValueId readValue = new ReadValueId(node, AttributeId.Value.uid(), null, QualifiedName.NULL_VALUE);
+
+            // important: client handle must be unique per item
+            UInteger clientHandle = uint(clientHandles.getAndIncrement());
+
+            MonitoringParameters parameters = new MonitoringParameters(
+                    clientHandle,
+                    1000.0,     // sampling interval
+                    null,      // filter, null means use default
+                    uint(10),   // queue size
+                    true         // discard oldest
+            );
+
+            MonitoredItemCreateRequest request = new MonitoredItemCreateRequest(readValue, MonitoringMode.Reporting, parameters);
+
+
+            BiConsumer<UaMonitoredItem, Integer> onItemCreated =
+                    (item, id) -> {
+                        System.out.println(id);
+                        item.setValueConsumer(OpcUaTest::onSubscriptionValue);
+                    };
+
+
+            List<UaMonitoredItem> items = subscription.createMonitoredItems(
+                    TimestampsToReturn.Both,
+                    Lists.newArrayList(request),
+                    onItemCreated
+            ).get();
+
+            for (UaMonitoredItem item : items) {
+                NodeId tagId = item.getReadValueId().getNodeId();
+                if (item.getStatusCode().isGood()) {
+                    System.out.println("item created for nodeId="+ tagId);
+                } else {
+                    System.out.println("failed to create item for " + item.getReadValueId().getNodeId() + item.getStatusCode());
+                }
+            }
+
+        }
+    }
+
+    private static void browseNodeTest(String indent, OpcUaClient client, NodeId browseRoot) {
+        BrowseDescription browse = new BrowseDescription(
+                browseRoot,
+                BrowseDirection.Forward,
+                Identifiers.References,
+                true,
+                uint(NodeClass.Object.getValue() | NodeClass.Variable.getValue()),
+                uint(BrowseResultMask.All.getValue())
+        );
+
+        try {
+            BrowseResult browseResult = client.browse(browse).get();
+
+            List<ReferenceDescription> references = toList(browseResult.getReferences());
+
+            for (ReferenceDescription rd : references) {
+                System.out.println("=====================================================================");
+                System.out.println(rd.toString());
+                System.out.println(rd.getNodeClass());
+                System.out.println("Node={} " + indent + " " + rd.getBrowseName().getName());
+                System.out.println("=====================================================================");
+                // recursively browse to children
+                rd.getNodeId().local().ifPresent(nodeId -> {
+                    System.out.println("NodeId: " + nodeId.getNamespaceIndex());
+                    System.out.println("NodeId: " + nodeId.getIdentifier());
+                    System.out.println("NodeId: " + nodeId.getType());
+                    browseNodeTest(indent + "  ", client, nodeId);
+
+                });
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            System.out.println("Browsing nodeId=" + browseRoot + " failed: " + e.getMessage());
+        }
+    }
+
+
+    private List<ReferenceDescription> browseNode(String indent, OpcUaClient client, NodeId browseRoot) {
+        List<ReferenceDescription> result = new ArrayList<>();
+
+        BrowseDescription browse = new BrowseDescription(
+                browseRoot,
+                BrowseDirection.Forward,
+                Identifiers.References,
+                true,
+                uint(NodeClass.Object.getValue() | NodeClass.Variable.getValue()),
+                uint(BrowseResultMask.All.getValue())
+        );
+
+        try {
+            BrowseResult browseResult = client.browse(browse).get();
+
+            List<ReferenceDescription> references = toList(browseResult.getReferences());
+
+            for (ReferenceDescription rd : references) {
+                result.add(rd);
+                rd.getNodeId().local().ifPresent(nodeId -> browseNode(indent + "  ", client, nodeId));
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            System.out.println("Browsing nodeId=" + browseRoot + " failed: " + e.getMessage());
+        }
+
+        return result;
+
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/opcua/OpcUaTypes.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/opcua/OpcUaTypes.java
new file mode 100644
index 0000000..50774fd
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/opcua/OpcUaTypes.java
@@ -0,0 +1,44 @@
+/*
+ * 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.connect.adapters.opcua;
+
+
+import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
+import org.apache.streampipes.sdk.utils.Datatypes;
+
+public class OpcUaTypes {
+
+    public static Datatypes getType(UInteger o) {
+        if (UInteger.valueOf(4).equals(o) | UInteger.valueOf(6).equals(o) | UInteger.valueOf(8).equals(o) | UInteger.valueOf(27).equals(o)) {
+            return Datatypes.Integer;
+        } else if (UInteger.valueOf(11).equals(o)) {
+            return Datatypes.Double;
+        } else if (UInteger.valueOf(10).equals(o) | UInteger.valueOf(26).equals(o)) {
+            return Datatypes.Float;
+        } else if (UInteger.valueOf(1).equals(o)) {
+            return Datatypes.Boolean;
+        } else if (UInteger.valueOf(12).equals(o)) {
+            return Datatypes.String;
+        }
+
+        return Datatypes.String;
+    }
+
+}
+
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/plc4x/passive/Plc4xPassiveAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/plc4x/passive/Plc4xPassiveAdapter.java
new file mode 100644
index 0000000..de04f15
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/plc4x/passive/Plc4xPassiveAdapter.java
@@ -0,0 +1,117 @@
+/*
+ * 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.connect.adapters.plc4x.passive;
+
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.exception.ParseException;
+import org.apache.streampipes.connect.adapter.model.specific.SpecificDataStreamAdapter;
+import org.apache.streampipes.model.AdapterType;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.model.schema.EventProperty;
+import org.apache.streampipes.model.schema.EventSchema;
+import org.apache.streampipes.sdk.builder.PrimitivePropertyBuilder;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataStreamAdapterBuilder;
+import org.apache.streampipes.sdk.utils.Datatypes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Plc4xPassiveAdapter extends SpecificDataStreamAdapter {
+
+    /**
+     * A unique id to identify the adapter
+     */
+    public static final String ID = "http://streampipes.org/adapter/specific/plc4xpassive";
+
+    public Plc4xPassiveAdapter() {
+    }
+
+    public Plc4xPassiveAdapter(SpecificAdapterStreamDescription adapterDescription) {
+        super(adapterDescription);
+    }
+
+    @Override
+    public SpecificAdapterStreamDescription declareModel() {
+        SpecificAdapterStreamDescription description = SpecificDataStreamAdapterBuilder.create(ID, "PLC4X Passive", "")
+                .iconUrl("plc4x.png")
+                .category(AdapterType.Manufacturing)
+                .build();
+        description.setAppId(ID);
+
+        return description;
+    }
+
+    @Override
+    public GuessSchema getSchema(SpecificAdapterStreamDescription adapterDescription) throws AdapterException, ParseException {
+        GuessSchema guessSchema = new GuessSchema();
+
+        EventSchema eventSchema = new EventSchema();
+        List<EventProperty> allProperties = new ArrayList<>();
+
+        allProperties.add(
+                PrimitivePropertyBuilder
+                        .create(Datatypes.String, "sourceId")
+                        .label("Source Id")
+                        .description("")
+                        .build());
+
+        allProperties.add(
+                PrimitivePropertyBuilder
+                        .create(Datatypes.String, "propertyId")
+                        .label("Property Id")
+                        .description("")
+                        .build());
+
+        // We need to define the type of the value, I choose a numerical value
+        allProperties.add(
+                PrimitivePropertyBuilder
+                        .create(Datatypes.Float, "value")
+                        .label("Value")
+                        .description("")
+                        .build());
+
+
+        eventSchema.setEventProperties(allProperties);
+        guessSchema.setEventSchema(eventSchema);
+        guessSchema.setPropertyProbabilityList(new ArrayList<>());
+        return guessSchema;
+    }
+
+    @Override
+    public void startAdapter() throws AdapterException {
+        // TODO
+    }
+
+    @Override
+    public void stopAdapter() throws AdapterException {
+        // TODO
+    }
+
+    @Override
+    public Adapter getInstance(SpecificAdapterStreamDescription adapterDescription) {
+        return new Plc4xPassiveAdapter(adapterDescription);
+    }
+
+    @Override
+    public String getId() {
+        return ID;
+    }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/plc4x/s7/Plc4xS7Adapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/plc4x/s7/Plc4xS7Adapter.java
new file mode 100644
index 0000000..a2a3aae
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/plc4x/s7/Plc4xS7Adapter.java
@@ -0,0 +1,265 @@
+/*
+ * 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.connect.adapters.plc4x.s7;
+
+import org.apache.plc4x.java.PlcDriverManager;
+import org.apache.plc4x.java.api.PlcConnection;
+import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+import org.apache.plc4x.java.api.messages.PlcReadRequest;
+import org.apache.plc4x.java.api.messages.PlcReadResponse;
+import org.apache.plc4x.java.api.types.PlcResponseCode;
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.sdk.ParameterExtractor;
+import org.apache.streampipes.connect.adapter.util.PollingSettings;
+import org.apache.streampipes.connect.adapters.PullAdapter;
+import org.apache.streampipes.model.AdapterType;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.model.schema.EventProperty;
+import org.apache.streampipes.model.schema.EventSchema;
+import org.apache.streampipes.sdk.builder.PrimitivePropertyBuilder;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataStreamAdapterBuilder;
+import org.apache.streampipes.sdk.helpers.Labels;
+import org.apache.streampipes.sdk.utils.Datatypes;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+
+public class Plc4xS7Adapter extends PullAdapter {
+
+    /**
+     * A unique id to identify the Plc4xS7Adapter
+      */
+    public static final String ID = "http://streampipes.org/adapter/specific/plc4xs7";
+
+    /**
+     * Keys of user configuration parameters
+     */
+    private static final String PLC_IP = "PLC_IP";
+    private static final String PLC_NODE_NAME = "PLC_NODE_NAME";
+    private static final String PLC_NODE_TYPE = "PLC_NODE_TYPE";
+
+    /**
+     * Values of user configuration parameters
+     */
+    private String ip;
+    private String nodeName;
+    private String nodeType;
+
+    /**
+     * Connection to the PLC
+     */
+    private PlcConnection plcConnection;
+
+    /**
+     * Empty constructor and a constructor with SpecificAdapterStreamDescription are mandatory
+     */
+    public Plc4xS7Adapter() {
+    }
+
+    public Plc4xS7Adapter(SpecificAdapterStreamDescription adapterDescription) {
+        super(adapterDescription);
+    }
+
+
+    /**
+     * Describe the adapter adapter and define what user inputs are required. Currently users can just select one node, this will be extended in the future
+     * @return
+     */
+    @Override
+    public SpecificAdapterStreamDescription declareModel() {
+
+        SpecificAdapterStreamDescription description = SpecificDataStreamAdapterBuilder.create(ID, "PLC4X S7", "Connect directly to your PLC")
+                .iconUrl("plc4x.png")
+                .category(AdapterType.Manufacturing)
+                .requiredTextParameter(Labels.from(PLC_IP, "PLC Address", "Example: 192.168.34.56"))
+                .requiredTextParameter(Labels.from(PLC_NODE_NAME, "Node Name", "temperature"))
+                .requiredTextParameter(Labels.from(PLC_NODE_TYPE, "Node Type", "%Q0.4:BOOL"))
+                .build();
+        description.setAppId(ID);
+
+
+        return description;
+    }
+
+    /**
+     * Takes the user input and creates the event schema. The event schema describes the properties of the event stream.
+     * @param adapterDescription
+     * @return
+     * @throws AdapterException
+     */
+    @Override
+    public GuessSchema getSchema(SpecificAdapterStreamDescription adapterDescription) throws AdapterException {
+        // TODO add a validation to check if the user input is available in the PLC
+
+        // Extract user input
+        getConfigurations(adapterDescription);
+
+        GuessSchema guessSchema = new GuessSchema();
+
+        EventSchema eventSchema = new EventSchema();
+        List<EventProperty> allProperties = new ArrayList<>();
+
+        Datatypes datatype = getStreamPipesDataType(this.nodeType);
+
+        allProperties.add(
+                PrimitivePropertyBuilder
+                        .create(datatype, this.nodeName)
+                        .label(this.nodeName)
+                        .description("")
+                        .build());
+
+        eventSchema.setEventProperties(allProperties);
+        guessSchema.setEventSchema(eventSchema);
+        guessSchema.setPropertyProbabilityList(new ArrayList<>());
+        return guessSchema;
+    }
+
+    /**
+     * This method is executed when the adapter is started. A connection to the PLC is initialized
+     * @throws AdapterException
+     */
+    @Override
+    protected void before() throws AdapterException {
+        // Extract user input
+        getConfigurations(adapterDescription);
+
+        try {
+            this.plcConnection= new PlcDriverManager().getConnection("s7://" + this.ip + "/1/1");
+
+            if (!this.plcConnection.getMetadata().canRead()) {
+                throw new AdapterException("The S7 on IP: " + this.ip + " does not support reading data");
+            }
+
+        } catch (PlcConnectionException e) {
+            throw new AdapterException("Could not establish connection to S7 with ip " + this.ip);
+        }
+    }
+
+
+    /**
+     * pullData is called iteratively according to the polling interval defined in getPollInterval.
+     */
+    @Override
+    protected void pullData() {
+
+        // Create PLC read request
+        PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
+        builder.addItem(this.nodeName, this.nodeType);
+        PlcReadRequest readRequest = builder.build();
+
+        // Execute the request
+        PlcReadResponse response = null;
+        try {
+            response = readRequest.execute().get();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            e.printStackTrace();
+        }
+
+        // Create an event containing the value of the PLC
+        Map<String, Object> event = new HashMap<>();
+        for (String fieldName : response.getFieldNames()) {
+            if(response.getResponseCode(fieldName) == PlcResponseCode.OK) {
+                event.put(fieldName, response.getObject(fieldName));
+            }
+
+            else {
+                logger.error("Error[" + fieldName + "]: " + response.getResponseCode(fieldName).name());
+            }
+        }
+
+        // publish the final event
+        adapterPipeline.process(event);
+    }
+
+
+    /**
+     * Define the polling interval of this adapter. Default is to poll every second
+     * @return
+     */
+    @Override
+    protected PollingSettings getPollingInterval() {
+        return PollingSettings.from(TimeUnit.SECONDS, 1);
+    }
+
+    /**
+     * Required by StreamPipes return a new adapter instance by calling the constructor with SpecificAdapterStreamDescription
+     * @param adapterDescription
+     * @return
+     */
+    @Override
+    public Adapter getInstance(SpecificAdapterStreamDescription adapterDescription) {
+        return new Plc4xS7Adapter(adapterDescription);
+    }
+
+
+    /**
+     * Required by StreamPipes. Return the id of the adapter
+     * @return
+     */
+    @Override
+    public String getId() {
+        return ID;
+    }
+
+    /**
+     * Extracts the user configuration from the SpecificAdapterStreamDescription and sets the local variales
+     * @param adapterDescription
+     */
+    private void getConfigurations(SpecificAdapterStreamDescription adapterDescription) {
+        ParameterExtractor extractor = new ParameterExtractor(adapterDescription.getConfig());
+        this.ip = extractor.singleValue(PLC_IP, String.class);
+        this.nodeName = extractor.singleValue(PLC_NODE_NAME, String.class);
+        this.nodeType = extractor.singleValue(PLC_NODE_TYPE, String.class);
+    }
+
+    /**
+     * Transforms PLC4X data types to datatypes supported in StreamPipes
+     * @param plcType
+     * @return
+     * @throws AdapterException
+     */
+    private Datatypes getStreamPipesDataType(String plcType) throws AdapterException {
+
+        String type = plcType.substring(plcType.lastIndexOf(":")+1);
+
+        switch (type) {
+            case "BOOL":
+                return Datatypes.Boolean;
+            case "BYTE":
+                return Datatypes.Float;
+            case "INT":
+                return Datatypes.Integer;
+            case "WORD":
+                return Datatypes.String;
+            case "REAL":
+                return Datatypes.Float;
+            default:
+                throw new AdapterException("Datatype " + plcType + " is not supported");
+        }
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/ros/RosBridgeAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/ros/RosBridgeAdapter.java
new file mode 100644
index 0000000..a6500d8
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/ros/RosBridgeAdapter.java
@@ -0,0 +1,274 @@
+/*
+ * 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.connect.adapters.ros;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import edu.wpi.rail.jrosbridge.Ros;
+import edu.wpi.rail.jrosbridge.Service;
+import edu.wpi.rail.jrosbridge.Topic;
+import edu.wpi.rail.jrosbridge.callback.TopicCallback;
+import edu.wpi.rail.jrosbridge.messages.Message;
+import edu.wpi.rail.jrosbridge.services.ServiceRequest;
+import edu.wpi.rail.jrosbridge.services.ServiceResponse;
+import org.apache.streampipes.connect.EmitBinaryEvent;
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.format.json.object.JsonObjectFormat;
+import org.apache.streampipes.connect.adapter.format.json.object.JsonObjectParser;
+import org.apache.streampipes.connect.adapter.model.specific.SpecificDataStreamAdapter;
+import org.apache.streampipes.connect.adapter.sdk.ParameterExtractor;
+import org.apache.streampipes.container.api.ResolvesContainerProvidedOptions;
+import org.apache.streampipes.model.AdapterType;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.model.schema.EventSchema;
+import org.apache.streampipes.model.staticproperty.Option;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataStreamAdapterBuilder;
+import org.apache.streampipes.sdk.extractor.StaticPropertyExtractor;
+import org.apache.streampipes.sdk.helpers.Labels;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class RosBridgeAdapter extends SpecificDataStreamAdapter  implements ResolvesContainerProvidedOptions {
+
+    public static final String ID = "http://streampipes.org/adapter/specific/ros";
+
+    private static final String ROS_HOST_KEY = "ROS_HOST_KEY";
+    private static final String ROS_PORT_KEY = "ROS_PORT_KEY";
+    private static final String TOPIC_KEY = "TOPIC_KEY";
+
+    private String topic;
+    private String host;
+    private int port;
+
+    private Ros ros;
+
+    private JsonObjectParser jsonObjectParser;
+
+    public RosBridgeAdapter() {
+    }
+
+    public RosBridgeAdapter(SpecificAdapterStreamDescription adapterDescription) {
+        super(adapterDescription);
+
+        getConfigurations(adapterDescription);
+
+        this.jsonObjectParser = new JsonObjectParser();
+    }
+
+    @Override
+    public SpecificAdapterStreamDescription declareModel() {
+        SpecificAdapterStreamDescription description = SpecificDataStreamAdapterBuilder.create(ID, "ROS Bridge", "Connect Robots running on ROS")
+                .iconUrl("ros.png")
+                .category(AdapterType.Manufacturing)
+                .requiredTextParameter(Labels.from(ROS_HOST_KEY, "Ros Bridge", "Example: test-server.com (No protocol) "))
+                .requiredTextParameter(Labels.from(ROS_PORT_KEY, "Port", "Example: 9090"))
+                .requiredSingleValueSelectionFromContainer(Labels.from(TOPIC_KEY, "Topic",
+                        "Example: /battery (Starts with /) "), Arrays.asList(ROS_HOST_KEY,
+                        ROS_PORT_KEY))
+//                .requiredTextParameter(Labels.from(TOPIC_KEY, "Topic", "Example: /battery " +
+//                        "(Starts with /) "))
+                .build();
+        description.setAppId(ID);
+
+
+        return  description;
+    }
+
+    @Override
+    public void startAdapter() throws AdapterException {
+        this.ros = new Ros(this.host, this.port);
+        this.ros.connect();
+
+        String topicType = getMethodType(this.ros, this.topic);
+
+        Topic echoBack = new Topic(ros, this.topic, topicType);
+        echoBack.subscribe(new TopicCallback() {
+            @Override
+            public void handleMessage(Message message) {
+
+                InputStream stream = new ByteArrayInputStream(message.toString().getBytes(StandardCharsets.UTF_8));
+
+                jsonObjectParser.parse(stream, new ParseData());
+            }
+        });
+
+
+    }
+
+    @Override
+    public List<Option> resolveOptions(String requestId, StaticPropertyExtractor extractor) {
+        String rosBridgeHost = extractor.singleValueParameter(ROS_HOST_KEY, String.class);
+        Integer rosBridgePort = extractor.singleValueParameter(ROS_PORT_KEY, Integer.class);
+
+        Ros ros = new Ros(rosBridgeHost, rosBridgePort);
+
+        ros.connect();
+        List<String> topics = getListOfAllTopics(ros);
+        ros.disconnect();
+        return topics.stream().map(Option::new).collect(Collectors.toList());
+    }
+
+    private class GetNEvents implements Runnable {
+
+        private String topic;
+        private String topicType;
+        private Ros ros;
+
+        private List<byte[]> events;
+
+        public GetNEvents(String topic, String topicType, Ros ros) {
+            this.topic = topic;
+            this.topicType = topicType;
+            this.ros = ros;
+            this.events = new ArrayList<>();
+        }
+
+        @Override
+        public void run() {
+            Topic echoBack = new Topic(ros, this.topic, topicType);
+            echoBack.subscribe(new TopicCallback() {
+                @Override
+                public void handleMessage(Message message) {
+                    events.add(message.toString().getBytes());
+                }
+            });
+        }
+
+        public List<byte[]> getEvents() {
+            return this.events;
+        }
+    }
+
+    @Override
+    public void stopAdapter() throws AdapterException {
+        this.ros.disconnect();
+    }
+
+    @Override
+    public GuessSchema getSchema(SpecificAdapterStreamDescription adapterDescription) throws AdapterException {
+        getConfigurations(adapterDescription);
+
+
+        Ros ros = new Ros(host, port);
+
+        boolean connect = ros.connect();
+
+        if (!connect) {
+            throw new AdapterException("Could not connect to ROS bridge Endpoint: " + host + " with port: " + port);
+        }
+
+        String topicType = getMethodType(ros, topic);
+
+        GetNEvents getNEvents = new GetNEvents(topic, topicType, ros);
+        Thread t = new Thread(getNEvents);
+        t.start();
+
+        while (getNEvents.getEvents().size() < 1) {
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+
+        t.interrupt();
+
+        ros.disconnect();
+
+        EventSchema eventSchema = this.jsonObjectParser.getEventSchema(getNEvents.getEvents());
+
+        GuessSchema guessSchema = new GuessSchema();
+
+        guessSchema.setEventSchema(eventSchema);
+        guessSchema.setPropertyProbabilityList(new ArrayList<>());
+        return guessSchema;
+    }
+
+    @Override
+    public Adapter getInstance(SpecificAdapterStreamDescription adapterDescription) {
+        return new RosBridgeAdapter(adapterDescription);
+    }
+
+    @Override
+    public String getId() {
+        return ID;
+    }
+
+    private String getMethodType(Ros ros, String topic) {
+        Service addTwoInts = new Service(ros, "/rosapi/topic_type", "rosapi/TopicType");
+        ServiceRequest request = new ServiceRequest("{\"topic\": \""+ topic +"\"}");
+        ServiceResponse response = addTwoInts.callServiceAndWait(request);
+
+        JsonObject ob = new JsonParser().parse(response.toString()).getAsJsonObject();
+        return ob.get("type").getAsString();
+    }
+
+    private class ParseData implements EmitBinaryEvent {
+
+        private JsonObjectFormat jsonObjectFormat;
+
+        public ParseData() {
+            this.jsonObjectFormat = new JsonObjectFormat();
+        }
+
+        @Override
+        public Boolean emit(byte[] event) {
+            Map<String, Object> result = this.jsonObjectFormat.parse(event);
+            adapterPipeline.process(result);
+            return true;
+        }
+    }
+
+    private void getConfigurations(SpecificAdapterStreamDescription adapterDescription) {
+        ParameterExtractor extractor = new ParameterExtractor(adapterDescription.getConfig());
+        this.host = extractor.singleValue(ROS_HOST_KEY, String.class);
+        this.topic = extractor.selectedSingleValueOption(TOPIC_KEY);
+        this.port = extractor.singleValue(ROS_PORT_KEY, Integer.class);
+    }
+
+    // Ignore for now, but is interesting for future implementations
+    private List<String> getListOfAllTopics(Ros ros) {
+        List<String> result = new ArrayList<>();
+        Service service = new Service(ros, "/rosapi/topics", "rosapi/Topics");
+        ServiceRequest request = new ServiceRequest();
+        ServiceResponse response = service.callServiceAndWait(request);
+        JsonObject ob = new JsonParser().parse(response.toString()).getAsJsonObject();
+
+        if (ob.has("topics")) {
+            JsonArray topics = ob.get("topics").getAsJsonArray();
+            for (int i = 0; i < topics.size(); i++) {
+                result.add(topics.get(i).getAsString());
+            }
+
+        }
+
+        return result;
+
+    }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/OpenSenseMapAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/OpenSenseMapAdapter.java
new file mode 100644
index 0000000..a9556ff
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/OpenSenseMapAdapter.java
@@ -0,0 +1,403 @@
+/*
+ * 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.connect.adapters.sensemap;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.util.PollingSettings;
+import org.apache.streampipes.connect.adapters.PullRestAdapter;
+import org.apache.streampipes.connect.adapters.sensemap.model.CurrentLocation;
+import org.apache.streampipes.connect.adapters.sensemap.model.SenseBox;
+import org.apache.streampipes.connect.adapters.sensemap.model.Sensor;
+import org.apache.streampipes.model.AdapterType;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.model.schema.EventProperty;
+import org.apache.streampipes.model.schema.EventPropertyPrimitive;
+import org.apache.streampipes.model.schema.EventSchema;
+import org.apache.streampipes.model.staticproperty.AnyStaticProperty;
+import org.apache.streampipes.model.staticproperty.Option;
+import org.apache.streampipes.sdk.builder.PrimitivePropertyBuilder;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataStreamAdapterBuilder;
+import org.apache.streampipes.sdk.helpers.EpProperties;
+import org.apache.streampipes.sdk.helpers.Labels;
+import org.apache.streampipes.sdk.utils.Datatypes;
+import org.apache.streampipes.vocabulary.XSD;
+
+import java.time.Instant;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class OpenSenseMapAdapter extends PullRestAdapter {
+
+    private Logger logger = LoggerFactory.getLogger(OpenSenseMapAdapter.class);
+
+    public static final String ID = "http://streampipes.org/adapter/specific/opensensemap";
+    public static final int POLLING_INTERVALL = 5;
+
+    private List<String> selectedSensors;
+
+    private String standartKeys[] = {"id", "timestamp", "model", "latitude", "longitude"};
+
+//    private String url = "https://api.opensensemap.org/boxes";
+    private String url = "http://localhost:3001/opensensemap";
+//    private String url = "http://test-connect-datasources-rest:3001/opensensemap";
+
+
+    public OpenSenseMapAdapter() {
+        super();
+    }
+
+    public OpenSenseMapAdapter(SpecificAdapterStreamDescription adapterDescription) {
+        super(adapterDescription);
+
+
+    }
+
+    @Override
+    public SpecificAdapterStreamDescription declareModel() {
+
+        SpecificAdapterStreamDescription description = SpecificDataStreamAdapterBuilder.create(ID, "OpenSenseMap", "Environment Sensors")
+                .iconUrl("openSenseMap.png")
+                .category(AdapterType.Environment, AdapterType.OpenData)
+                .requiredMultiValueSelection(Labels.from("sensors", "Sensors", "Select the " +
+                        "sensors that are included in the data stream"), Stream
+                        .of(SensorNames.ALL_SENSOR_LABELS)
+                        .map(s -> new Option(s, SensorNames.getKeyFromLabel(s)))
+                        .collect(Collectors.toList()))
+                .build();
+
+        description.setAppId(ID);
+        return description;
+    }
+
+    @Override
+    public Adapter getInstance(SpecificAdapterStreamDescription adapterDescription) {
+        return new OpenSenseMapAdapter(adapterDescription);
+    }
+
+    @Override
+    public GuessSchema getSchema(SpecificAdapterStreamDescription adapterDescription) {
+        GuessSchema guessSchema = new GuessSchema();
+
+        EventSchema eventSchema = new EventSchema();
+        EventPropertyPrimitive eventPropertyPrimitive = new EventPropertyPrimitive();
+        eventPropertyPrimitive.setRuntimeType(XSD._double.toString());
+
+        List<EventProperty> allProperties = new ArrayList<>();
+
+        List<Option> allOptions = ((AnyStaticProperty) (adapterDescription.getConfig().get(0))).getOptions();
+        activateSensors(allOptions);
+
+        // Set basic properties
+        allProperties.add(EpProperties.timestampProperty(SensorNames.KEY_TIMESTAMP));
+        allProperties.add(
+                PrimitivePropertyBuilder
+                        .create(Datatypes.Integer, SensorNames.KEY_ID)
+                        .label(SensorNames.LABEL_ID)
+                        .description("The unique identifier of a SenseBox")
+                        .build());
+        allProperties.add(
+                PrimitivePropertyBuilder
+                        .create(Datatypes.String, SensorNames.KEY_NAME)
+                        .label(SensorNames.LABEL_NAME)
+                        .description("The name of the SenseBox")
+                        .build());
+        allProperties.add(
+                PrimitivePropertyBuilder
+                        .create(Datatypes.String, SensorNames.KEY_MODEL)
+                        .label(SensorNames.LABEL_MODEL)
+                        .description("Model of the SenseBox")
+                        .build());
+
+        allProperties.add(
+                PrimitivePropertyBuilder
+                        .create(Datatypes.String, SensorNames.KEY_LATITUDE)
+                        .label(SensorNames.LABEL_LATITUDE)
+                        .description("Latitude value of box location")
+                        .build());
+        allProperties.add(
+                PrimitivePropertyBuilder
+                        .create(Datatypes.String, SensorNames.KEY_LONGITUDE)
+                        .label(SensorNames.LABEL_LONGITUDE)
+                        .description("Longitude value of box location")
+                        .build());
+
+
+        if (selected(SensorNames.KEY_TEMPERATURE)) {
+            allProperties.add(PrimitivePropertyBuilder
+                    .create(Datatypes.Double, SensorNames.KEY_TEMPERATURE)
+                    .label(SensorNames.LABEL_TEMPERATURE)
+                    .description("Measurement for the temperature")
+//                    .measurementUnit(TemperatureUnit.CELSIUS.getResource())
+                    .build());
+        }
+        if (selected(SensorNames.KEY_HUMIDITY)) {
+            allProperties.add(PrimitivePropertyBuilder
+                    .create(Datatypes.Double, SensorNames.KEY_HUMIDITY)
+                    .label(SensorNames.LABEL_HUMIDITY)
+                    .description("Measures the humidity in the air")
+//                    .measurementUnit(CountingUnit.PERCENT.getResource())
+                    .build());
+        }
+        if (selected(SensorNames.KEY_PRESSURE)) {
+            allProperties.add(PrimitivePropertyBuilder
+                    .create(Datatypes.Double, SensorNames.KEY_PRESSURE)
+                    .label(SensorNames.LABEL_PRESSURE)
+                    .description("Air pressure")
+//                    .measurementUnit(PressureOrStressUnit.PASCAL.getResource())
+                    .build());
+        }
+        if (selected(SensorNames.KEY_ILLUMINANCE)) {
+            allProperties.add(PrimitivePropertyBuilder
+                    .create(Datatypes.Double, SensorNames.KEY_ILLUMINANCE)
+                    .label(SensorNames.LABEL_ILLUMINANCE)
+                    .description("Total luminous flux incident on a surface per unit area")
+                    // TODO
+//                    .measurementUnit(.getResource())
+                    .build());
+        }
+        if (selected(SensorNames.KEY_UV_INTENSITY)) {
+            allProperties.add(PrimitivePropertyBuilder
+                    .create(Datatypes.Double, SensorNames.KEY_UV_INTENSITY)
+                    .label(SensorNames.LABEL_UV_INTENSITY)
+                    .description("")
+                    // TODO
+//                    .measurementUnit(.getResource())
+                    .build());
+        }
+        if (selected(SensorNames.KEY_PM10)) {
+            allProperties.add(PrimitivePropertyBuilder
+                    .create(Datatypes.Double, SensorNames.KEY_PM10)
+                    .label(SensorNames.LABEL_PM10)
+                    .description("Particulate Matter in the air with a diameter of 10 micrometer")
+                    // TODO
+//                    .measurementUnit(.getResource())
+                    .build());
+        }
+        if (selected(SensorNames.KEY_PM2_5)) {
+            allProperties.add(PrimitivePropertyBuilder
+                    .create(Datatypes.Double, SensorNames.KEY_PM2_5)
+                    .label(SensorNames.LABEL_PM2_5)
+                    .description("Particulate Matter in the air with a diameter of 10 micrometer")
+                    // TODO
+//                    .measurementUnit(.getResource())
+                    .build());
+        }
+
+        eventSchema.setEventProperties(allProperties);
+        guessSchema.setEventSchema(eventSchema);
+        guessSchema.setPropertyProbabilityList(new ArrayList<>());
+        return guessSchema;
+    }
+
+    @Override
+    public String getId() {
+        return ID;
+    }
+
+    public List<Map<String, Object>> getEvents() {
+
+        List<Map<String, Object>> eventResults = new ArrayList<>();
+
+        SenseBox[] senseBoxResult = {};
+        try {
+            senseBoxResult = getDataFromEndpoint(url, SenseBox[].class);
+        } catch (AdapterException e) {
+            e.printStackTrace();
+        }
+
+        logger.info("Number of all detected SenseBoxes: " + senseBoxResult.length);
+
+        for (SenseBox senseBox : senseBoxResult) {
+            Map<String, Object> event = new HashMap<>();
+
+            if (senseBox.getCreatedAt() != null) {
+
+                event.put(SensorNames.KEY_ID, senseBox.get_id());
+                // TODO change timestamp
+                Long timestamp = getDateMillis(senseBox.getUpdatedAt());
+                event.put(SensorNames.KEY_TIMESTAMP, timestamp);
+                event.put(SensorNames.KEY_NAME, senseBox.getName());
+                event.put(SensorNames.KEY_MODEL, senseBox.getModel());
+
+                double latitude = getLatitude(senseBox);
+                double longitude = getLongitude(senseBox);
+                if (latitude != Double.MIN_VALUE && longitude != Double.MIN_VALUE) {
+                    event.put(SensorNames.KEY_LATITUDE, getLatitude(senseBox));
+                    event.put(SensorNames.KEY_LONGITUDE, getLongitude(senseBox));
+                } else {
+                    logger.info("Sense box id: " + senseBox.get_id() + " does not contain correct latitude or longitude values");
+                }
+
+//                Add Sensor values
+                for (Sensor s : senseBox.getSensors()) {
+                    if (s.getLastMeasurement() != null) {
+                        String key = SensorNames.getKey(s.getTitle());
+                        if (key != SensorNames.KEY_NOT_FOUND) {
+                            double value = getDoubleSensorValue(s.getLastMeasurement().getValue());
+                            if (value != Double.MIN_VALUE) {
+                                event.put(key, value);
+                            } else {
+                                logger.info("Sensor value " + s.getLastMeasurement().getValue() + " of sensor id: " +
+                                        s.get_id() + " in sense box id: " + senseBox.get_id() +
+                                        " is not correctly formatted");
+                            }
+                        }
+                    }
+                }
+
+                if (checkEvent(event)) {
+                    eventResults.add(filterSensors(event));
+                }
+            }
+        }
+
+        logger.info("All data sucessfully processed and " + eventResults.size() + " events will be send to Kafka");
+
+        return eventResults;
+    }
+
+    @Override
+    protected void pullData() {
+        List<Option> allOptions = ((AnyStaticProperty) (adapterDescription.getConfig().get(0))).getOptions();
+        activateSensors(allOptions);
+
+        List<Map<String, Object>> events = getEvents();
+
+        for (Map<String, Object> event : events) {
+            adapterPipeline.process(event);
+        }
+
+    }
+
+    @Override
+    protected PollingSettings getPollingInterval() {
+        return PollingSettings.from(TimeUnit.MINUTES, POLLING_INTERVALL);
+    }
+
+    private void activateSensors(List<Option> config) {
+//        this.selectedSensors = Arrays.asList(SensorNames.ALL_SENSOR_KEYS);
+        this.selectedSensors = new ArrayList<>();
+
+        for (Option option : config) {
+
+            if (option.isSelected()) {
+                this.selectedSensors.add(option.getInternalName());
+            }
+        }
+    }
+
+    private Map<String, Object> filterSensors(Map<String, Object> event) {
+        Map<String, Object> result = new HashMap<>();
+
+        for (String key : selectedSensors) {
+            result.put(key, event.get(key));
+        }
+
+        for (String key : SensorNames.ALL_META_KEYS) {
+            result.put(key, event.get(key));
+        }
+
+        return result;
+    }
+
+    private boolean checkEvent(Map<String, Object> event) {
+        for (String key : selectedSensors) {
+            if (!event.keySet().contains(key)) {
+                return false;
+            }
+        }
+
+        for (String key : SensorNames.ALL_META_KEYS) {
+            if (!event.keySet().contains(key)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private boolean selected(String value) {
+        return this.selectedSensors.contains(value);
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public void setSelectedSensors(List<String> selectedSensors) {
+        this.selectedSensors = selectedSensors;
+    }
+
+    private Long getDateMillis(String date) {
+
+        if (date != null) {
+            Date result = Date.from(Instant.parse(date));
+            return result.getTime();
+        }
+        return Long.MIN_VALUE;
+    }
+
+    private double getDoubleSensorValue(String sensorValue) {
+        try {
+            return Double.parseDouble(sensorValue);
+        } catch (NumberFormatException e) {
+            return Double.MIN_VALUE;
+        }
+    }
+
+    private double getLatitude(SenseBox box) {
+        List<Double> latlong = getLatLong(box);
+
+        if (latlong != null) {
+            return latlong.get(1);
+        } else {
+            return Double.MIN_VALUE;
+        }
+
+    }
+
+    private double getLongitude(SenseBox box) {
+        List<Double> latlong = getLatLong(box);
+
+        if (latlong != null) {
+            return latlong.get(0);
+        } else {
+            return Double.MIN_VALUE;
+        }
+    }
+
+    private List<Double> getLatLong(SenseBox box) {
+        CurrentLocation currentLocation = box.getCurrentLocation();
+
+        if (currentLocation == null) {
+            return null;
+        }
+
+        List<Double> latlong = currentLocation.getCoordinates();
+
+        return latlong;
+
+    }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/SensorNames.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/SensorNames.java
new file mode 100644
index 0000000..231bf12
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/SensorNames.java
@@ -0,0 +1,137 @@
+/*
+ * 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.connect.adapters.sensemap;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class SensorNames {
+    public final static String KEY_NOT_FOUND = "KEY_NOT_FOUND";
+
+    public final static String KEY_ID = "id";
+    public final static String KEY_TIMESTAMP = "timestamp";
+    public final static String KEY_NAME = "name";
+    public final static String KEY_MODEL = "model";
+    public final static String KEY_LATITUDE = "latitude";
+    public final static String KEY_LONGITUDE = "longitude";
+
+
+    public final static String KEY_TEMPERATURE = "temperature";
+    public final static String KEY_HUMIDITY = "humidity";
+    public final static String KEY_PRESSURE = "pressure";
+    public final static String KEY_ILLUMINANCE = "illuminance";
+    public final static String KEY_UV_INTENSITY = "uv_intensity";
+    public final static String KEY_PM10 = "pm10";
+    public final static String KEY_PM2_5 = "pm2_5";
+
+
+    public final static String LABEL_ID = "Id";
+    public final static String LABEL_NAME = "Name";
+    public final static String LABEL_MODEL = "Model";
+    public final static String LABEL_LATITUDE = "latitude";
+    public final static String LABEL_LONGITUDE = "longitude";
+
+
+
+    public final static String LABEL_TEMPERATURE = "Temperature";
+    public final static String LABEL_HUMIDITY = "Humidity";
+    public final static String LABEL_PRESSURE = "Pressure";
+    public final static String LABEL_ILLUMINANCE = "Illuminance";
+    public final static String LABEL_UV_INTENSITY = "UV Intensity";
+    public final static String LABEL_PM10 = "Particulate Matter 10";
+    public final static String LABEL_PM2_5 = "Particulate Matter 2.5";
+
+
+    public final static String GERMAN_TEMPERATURE = "Temperatur";
+    public final static String GERMAN_HUMIDITY = "rel. Luftfeuchte";
+    public final static String GERMAN_PRESSURE = "Luftdruck";
+    public final static String GERMAN_ILLUMINANCE = "Beleuchtungsstärke";
+    public final static String GERMAN_UV_INTENSITY = "UV-Intensität";
+    public final static String GERMAN_PM10 = "PM10";
+    public final static String GERMAN_PM2_5 = "PM2.5";
+
+    public final static String[] ALL_SENSOR_KEYS = {
+            KEY_TEMPERATURE,
+            KEY_HUMIDITY,
+            KEY_PRESSURE,
+            KEY_ILLUMINANCE,
+            KEY_UV_INTENSITY,
+            KEY_PM10,
+            KEY_PM2_5
+    };
+
+    public final static String[] ALL_SENSOR_LABELS = {
+            LABEL_TEMPERATURE,
+            LABEL_HUMIDITY,
+            LABEL_PRESSURE,
+            LABEL_ILLUMINANCE,
+            LABEL_UV_INTENSITY,
+            LABEL_PM10,
+            LABEL_PM2_5
+    };
+    public final static List<String> ALL_META_KEYS = Arrays.asList(
+            KEY_ID, KEY_NAME, KEY_TIMESTAMP, KEY_MODEL, KEY_LONGITUDE, KEY_LATITUDE
+    );
+
+    public static String getKey(String germanKeyValue) {
+        if (check(germanKeyValue, GERMAN_TEMPERATURE)) {
+            return KEY_TEMPERATURE;
+        } else if (check(germanKeyValue, GERMAN_HUMIDITY)) {
+            return KEY_HUMIDITY;
+        } else if (check(germanKeyValue, GERMAN_PRESSURE)) {
+            return KEY_PRESSURE;
+        } else if (check(germanKeyValue, GERMAN_ILLUMINANCE)) {
+            return KEY_ILLUMINANCE;
+        } else if (check(germanKeyValue, GERMAN_UV_INTENSITY)) {
+            return KEY_UV_INTENSITY;
+        } else if (check(germanKeyValue, GERMAN_PM10)) {
+            return KEY_PM10;
+        } else if (check(germanKeyValue, GERMAN_PM2_5)) {
+            return KEY_PM2_5;
+        } else {
+            return KEY_NOT_FOUND;
+        }
+    }
+
+    public static String getKeyFromLabel(String labelString) {
+        if (LABEL_TEMPERATURE.equals(labelString)) {
+            return KEY_TEMPERATURE;
+        } else if (LABEL_HUMIDITY.equals(labelString)) {
+            return KEY_HUMIDITY;
+        } else if (LABEL_PRESSURE.equals(labelString)) {
+            return KEY_PRESSURE;
+        } else if (LABEL_ILLUMINANCE.equals(labelString)) {
+            return KEY_ILLUMINANCE;
+        } else if (LABEL_UV_INTENSITY.equals(labelString)) {
+            return KEY_UV_INTENSITY;
+        } else if (LABEL_PM10.equals(labelString)) {
+            return KEY_PM10;
+        } else if (LABEL_PM2_5.equals(labelString)) {
+            return KEY_PM2_5;
+        } else {
+            return KEY_NOT_FOUND;
+        }
+    }
+
+    private static boolean check(String value, String contains) {
+        return value.contains(contains);
+    }
+
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/model/CurrentLocation.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/model/CurrentLocation.java
new file mode 100644
index 0000000..ebece9d
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/model/CurrentLocation.java
@@ -0,0 +1,62 @@
+/*
+ * 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.connect.adapters.sensemap.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.List;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class CurrentLocation {
+
+    @SerializedName("coordinates")
+    private List<Double> mCoordinates;
+    @SerializedName("timestamp")
+    private String mTimestamp;
+    @SerializedName("type")
+    private String mType;
+
+    public List<Double> getCoordinates() {
+        return mCoordinates;
+    }
+
+    public void setCoordinates(List<Double> coordinates) {
+        mCoordinates = coordinates;
+    }
+
+    public String getTimestamp() {
+        return mTimestamp;
+    }
+
+    public void setTimestamp(String timestamp) {
+        mTimestamp = timestamp;
+    }
+
+    public String getType() {
+        return mType;
+    }
+
+    public void setType(String type) {
+        mType = type;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/model/Geometry.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/model/Geometry.java
new file mode 100644
index 0000000..84e2cd5
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/model/Geometry.java
@@ -0,0 +1,62 @@
+/*
+ * 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.connect.adapters.sensemap.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.List;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class Geometry {
+
+    @SerializedName("coordinates")
+    private List<Double> mCoordinates;
+    @SerializedName("timestamp")
+    private String mTimestamp;
+    @SerializedName("type")
+    private String mType;
+
+    public List<Double> getCoordinates() {
+        return mCoordinates;
+    }
+
+    public void setCoordinates(List<Double> coordinates) {
+        mCoordinates = coordinates;
+    }
+
+    public String getTimestamp() {
+        return mTimestamp;
+    }
+
+    public void setTimestamp(String timestamp) {
+        mTimestamp = timestamp;
+    }
+
+    public String getType() {
+        return mType;
+    }
+
+    public void setType(String type) {
+        mType = type;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/model/LastMeasurement.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/model/LastMeasurement.java
new file mode 100644
index 0000000..a5839a6
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/model/LastMeasurement.java
@@ -0,0 +1,50 @@
+/*
+ * 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.connect.adapters.sensemap.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class LastMeasurement {
+
+    @SerializedName("createdAt")
+    private String mCreatedAt;
+    @SerializedName("value")
+    private String mValue;
+
+    public String getCreatedAt() {
+        return mCreatedAt;
+    }
+
+    public void setCreatedAt(String createdAt) {
+        mCreatedAt = createdAt;
+    }
+
+    public String getValue() {
+        return mValue;
+    }
+
+    public void setValue(String value) {
+        mValue = value;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/model/Loc.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/model/Loc.java
new file mode 100644
index 0000000..0219db9
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/model/Loc.java
@@ -0,0 +1,50 @@
+/*
+ * 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.connect.adapters.sensemap.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class Loc {
+
+    @SerializedName("geometry")
+    private Geometry mGeometry;
+    @SerializedName("type")
+    private String mType;
+
+    public Geometry getGeometry() {
+        return mGeometry;
+    }
+
+    public void setGeometry(Geometry geometry) {
+        mGeometry = geometry;
+    }
+
+    public String getType() {
+        return mType;
+    }
+
+    public void setType(String type) {
+        mType = type;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/model/SenseBox.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/model/SenseBox.java
new file mode 100644
index 0000000..b4f841b
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/model/SenseBox.java
@@ -0,0 +1,122 @@
+/*
+ * 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.connect.adapters.sensemap.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.List;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class SenseBox {
+
+    @SerializedName("createdAt")
+    private String mCreatedAt;
+    @SerializedName("currentLocation")
+    private CurrentLocation mCurrentLocation;
+    @SerializedName("exposure")
+    private String mExposure;
+    @SerializedName("loc")
+    private List<Loc> mLoc;
+    @SerializedName("model")
+    private String mModel;
+    @SerializedName("name")
+    private String mName;
+    @SerializedName("sensors")
+    private List<Sensor> mSensors;
+    @SerializedName("updatedAt")
+    private String mUpdatedAt;
+    @SerializedName("_id")
+    private String m_id;
+
+    public String getCreatedAt() {
+        return mCreatedAt;
+    }
+
+    public void setCreatedAt(String createdAt) {
+        mCreatedAt = createdAt;
+    }
+
+    public CurrentLocation getCurrentLocation() {
+        return mCurrentLocation;
+    }
+
+    public void setCurrentLocation(CurrentLocation currentLocation) {
+        mCurrentLocation = currentLocation;
+    }
+
+    public String getExposure() {
+        return mExposure;
+    }
+
+    public void setExposure(String exposure) {
+        mExposure = exposure;
+    }
+
+    public List<Loc> getLoc() {
+        return mLoc;
+    }
+
+    public void setLoc(List<Loc> loc) {
+        mLoc = loc;
+    }
+
+    public String getModel() {
+        return mModel;
+    }
+
+    public void setModel(String model) {
+        mModel = model;
+    }
+
+    public String getName() {
+        return mName;
+    }
+
+    public void setName(String name) {
+        mName = name;
+    }
+
+    public List<Sensor> getSensors() {
+        return mSensors;
+    }
+
+    public void setSensors(List<Sensor> sensors) {
+        mSensors = sensors;
+    }
+
+    public String getUpdatedAt() {
+        return mUpdatedAt;
+    }
+
+    public void setUpdatedAt(String updatedAt) {
+        mUpdatedAt = updatedAt;
+    }
+
+    public String get_id() {
+        return m_id;
+    }
+
+    public void set_id(String _id) {
+        m_id = _id;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/model/Sensor.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/model/Sensor.java
new file mode 100644
index 0000000..0472fea
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/sensemap/model/Sensor.java
@@ -0,0 +1,90 @@
+/*
+ * 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.connect.adapters.sensemap.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class Sensor {
+
+    @SerializedName("icon")
+    private String mIcon;
+    @SerializedName("lastMeasurement")
+    private LastMeasurement mLastMeasurement;
+    @SerializedName("sensorType")
+    private String mSensorType;
+    @SerializedName("title")
+    private String mTitle;
+    @SerializedName("unit")
+    private String mUnit;
+    @SerializedName("_id")
+    private String m_id;
+
+    public String getIcon() {
+        return mIcon;
+    }
+
+    public void setIcon(String icon) {
+        mIcon = icon;
+    }
+
+    public LastMeasurement getLastMeasurement() {
+        return mLastMeasurement;
+    }
+
+    public void setLastMeasurement(LastMeasurement lastMeasurement) {
+        mLastMeasurement = lastMeasurement;
+    }
+
+    public String getSensorType() {
+        return mSensorType;
+    }
+
+    public void setSensorType(String sensorType) {
+        mSensorType = sensorType;
+    }
+
+    public String getTitle() {
+        return mTitle;
+    }
+
+    public void setTitle(String title) {
+        mTitle = title;
+    }
+
+    public String getUnit() {
+        return mUnit;
+    }
+
+    public void setUnit(String unit) {
+        mUnit = unit;
+    }
+
+    public String get_id() {
+        return m_id;
+    }
+
+    public void set_id(String _id) {
+        m_id = _id;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/simulator/RandomDataSetAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/simulator/RandomDataSetAdapter.java
new file mode 100644
index 0000000..677ebbd
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/simulator/RandomDataSetAdapter.java
@@ -0,0 +1,90 @@
+/*
+ * 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.connect.adapters.simulator;
+
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.exception.ParseException;
+import org.apache.streampipes.connect.adapter.model.specific.SpecificDataSetAdapter;
+import org.apache.streampipes.connect.adapter.sdk.ParameterExtractor;
+import org.apache.streampipes.model.AdapterType;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterSetDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataSetAdapterBuilder;
+import org.apache.streampipes.sdk.helpers.Labels;
+
+public class RandomDataSetAdapter extends SpecificDataSetAdapter {
+
+  public static final String ID = "http://streampipes.org/adapter/specific/randomdataset";
+
+  private static final String WaitTimeMs = "wait-time-ms";
+  private static final String NumberOfEvents = "number-of-events";
+
+  private RandomDataSimulator randomDataSimulator;
+
+  public RandomDataSetAdapter() {
+    super();
+  }
+
+  public RandomDataSetAdapter(SpecificAdapterSetDescription adapterSetDescription) {
+    super(adapterSetDescription);
+    ParameterExtractor extractor = new ParameterExtractor(adapterSetDescription.getConfig());
+    Integer waitTimeMs = extractor.singleValue(WaitTimeMs, Integer.class);
+    Integer numberOfEvents = extractor.singleValue(NumberOfEvents, Integer.class);
+    this.randomDataSimulator = new RandomDataSimulator(adapterPipeline, waitTimeMs, numberOfEvents);
+  }
+
+  @Override
+  public SpecificAdapterSetDescription declareModel() {
+    return SpecificDataSetAdapterBuilder.create(ID, "Random Data Simulator (Set)",
+            "Publishes a bounded stream of random events")
+            .iconUrl("dice.png")
+            .category(AdapterType.Debugging)
+            .requiredIntegerParameter(Labels.from(WaitTimeMs, "Wait Time (MS)", "The time to " +
+                    "wait between two events in milliseconds"))
+            .requiredIntegerParameter(Labels.from(NumberOfEvents, "Number of Events", "The number" +
+                    " of events to send."))
+            .build();
+  }
+
+  @Override
+  public void startAdapter() throws AdapterException {
+    Thread thread = new Thread(this.randomDataSimulator);
+    thread.start();
+  }
+
+  @Override
+  public void stopAdapter() throws AdapterException {
+    this.randomDataSimulator.setRunning(false);
+  }
+
+  @Override
+  public Adapter getInstance(SpecificAdapterSetDescription adapterDescription) {
+    return new RandomDataSetAdapter(adapterDescription);
+  }
+
+  @Override
+  public GuessSchema getSchema(SpecificAdapterSetDescription adapterDescription) throws AdapterException, ParseException {
+    return RandomDataSimulatorUtils.randomSchema();
+  }
+
+  @Override
+  public String getId() {
+    return ID;
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/simulator/RandomDataSimulator.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/simulator/RandomDataSimulator.java
new file mode 100644
index 0000000..bce4c60
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/simulator/RandomDataSimulator.java
@@ -0,0 +1,87 @@
+/*
+ * 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.connect.adapters.simulator;
+
+import org.apache.streampipes.connect.adapter.model.pipeline.AdapterPipeline;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+public class RandomDataSimulator implements Runnable {
+
+  private AdapterPipeline adapterPipeline;
+
+  private Random random;
+  private Boolean running;
+  private Boolean infinite;
+  private Integer maxEvents;
+  private Integer waitTimeMs;
+
+  public RandomDataSimulator(AdapterPipeline adapterPipeline, Integer waitTimeMs,
+                             Integer maxEvents) {
+    this(adapterPipeline, waitTimeMs);
+    this.infinite = false;
+    this.maxEvents = maxEvents;
+
+  }
+
+  public RandomDataSimulator(AdapterPipeline adapterPipeline, Integer waitTimeMs) {
+    this.running = true;
+    this.waitTimeMs = waitTimeMs;
+    this.adapterPipeline = adapterPipeline;
+    this.random = new Random();
+    this.infinite = true;
+  }
+
+  @Override
+  public void run() {
+    int counter = 0;
+    this.running = true;
+    while ((running && infinite) || (running && counter <= maxEvents)) {
+      Map<String, Object> event = buildEvent(System.currentTimeMillis(), counter);
+      adapterPipeline.process(event);
+      counter++;
+      try {
+        Thread.sleep(waitTimeMs);
+      } catch (InterruptedException e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  private Map<String, Object> buildEvent(long timestamp, int counter) {
+    Map<String, Object> event = new HashMap<>();
+
+    event.put("timestamp", timestamp);
+    event.put("randomNumber", random.nextInt(100));
+    event.put("randomText", randomString());
+    event.put("count", counter);
+    return event;
+  }
+
+  private String randomString() {
+    String[] randomStrings = new String[]{"a", "b", "c", "d"};
+    Random random = new Random();
+    return randomStrings[random.nextInt(3)];
+  }
+
+  public void setRunning(Boolean running) {
+    this.running = running;
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/simulator/RandomDataSimulatorUtils.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/simulator/RandomDataSimulatorUtils.java
new file mode 100644
index 0000000..98bce40
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/simulator/RandomDataSimulatorUtils.java
@@ -0,0 +1,46 @@
+/*
+ * 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.connect.adapters.simulator;
+
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.sdk.builder.adapter.GuessSchemaBuilder;
+import org.apache.streampipes.sdk.helpers.Labels;
+import org.apache.streampipes.vocabulary.SO;
+
+import static org.apache.streampipes.sdk.helpers.EpProperties.*;
+
+public class RandomDataSimulatorUtils {
+
+  private static final String TIMESTAMP = "timestamp";
+  private static final String RANDOM_NUMBER = "randomNumber";
+  private static final String RANDOM_TEXT = "randomText";
+  private static final String COUNT = "count";
+
+  public static GuessSchema randomSchema() {
+    return GuessSchemaBuilder.create()
+            .property(timestampProperty(TIMESTAMP))
+            .property(integerEp(Labels.from(RANDOM_NUMBER, "Random Number", "A random number"),
+                    RANDOM_NUMBER, SO.Number))
+            .property(stringEp(Labels.from(RANDOM_TEXT, "Random Text", "A random text value"),
+                    RANDOM_TEXT,
+                    SO.Text))
+            .property(integerEp(Labels.from(COUNT, "count", "Count value"),
+                    COUNT, SO.Number))
+            .build();
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/simulator/RandomDataStreamAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/simulator/RandomDataStreamAdapter.java
new file mode 100644
index 0000000..c2cc21f
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/simulator/RandomDataStreamAdapter.java
@@ -0,0 +1,86 @@
+/*
+ * 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.connect.adapters.simulator;
+
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.exception.ParseException;
+import org.apache.streampipes.connect.adapter.model.specific.SpecificDataStreamAdapter;
+import org.apache.streampipes.connect.adapter.sdk.ParameterExtractor;
+import org.apache.streampipes.model.AdapterType;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataStreamAdapterBuilder;
+import org.apache.streampipes.sdk.helpers.Labels;
+
+public class RandomDataStreamAdapter extends SpecificDataStreamAdapter {
+
+  public static final String ID = "http://streampipes.org/adapter/specific/randomdatastream";
+
+  private final static String WaitTimeMs = "wait-time-ms";
+
+  private RandomDataSimulator randomDataSimulator;
+
+  public RandomDataStreamAdapter() {
+    super();
+  }
+
+  public RandomDataStreamAdapter(SpecificAdapterStreamDescription adapterStreamDescription) {
+    super(adapterStreamDescription);
+    ParameterExtractor extractor = new ParameterExtractor(adapterStreamDescription.getConfig());
+    Integer waitTimeMs = extractor.singleValue(WaitTimeMs, Integer.class);
+    this.randomDataSimulator = new RandomDataSimulator(adapterPipeline, waitTimeMs);
+  }
+
+  @Override
+  public SpecificAdapterStreamDescription declareModel() {
+    return SpecificDataStreamAdapterBuilder.create(ID, "Random Data Simulator (Stream)",
+            "Publishes an endless stream of random events")
+            .iconUrl("dice.png")
+            .category(AdapterType.Debugging)
+            .requiredIntegerParameter(Labels.from(WaitTimeMs, "Wait Time (MS)", "The time to " +
+                    "wait between two events in milliseconds"))
+            .build();
+  }
+
+  @Override
+  public void startAdapter() throws AdapterException {
+    Thread thread = new Thread(this.randomDataSimulator);
+    thread.start();
+  }
+
+  @Override
+  public void stopAdapter() throws AdapterException {
+    this.randomDataSimulator.setRunning(false);
+  }
+
+  @Override
+  public Adapter getInstance(SpecificAdapterStreamDescription adapterDescription) {
+    return new RandomDataStreamAdapter(adapterDescription);
+  }
+
+  @Override
+  public GuessSchema getSchema(SpecificAdapterStreamDescription adapterDescription) throws AdapterException, ParseException {
+    return RandomDataSimulatorUtils.randomSchema();
+  }
+
+  @Override
+  public String getId() {
+    return ID;
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/slack/SlackAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/slack/SlackAdapter.java
new file mode 100644
index 0000000..ecf8451
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/slack/SlackAdapter.java
@@ -0,0 +1,106 @@
+/*
+ * 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.connect.adapters.slack;
+
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.exception.ParseException;
+import org.apache.streampipes.connect.adapter.model.specific.SpecificDataStreamAdapter;
+import org.apache.streampipes.connect.adapter.sdk.ParameterExtractor;
+import org.apache.streampipes.model.AdapterType;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.sdk.builder.adapter.GuessSchemaBuilder;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataStreamAdapterBuilder;
+import org.apache.streampipes.sdk.helpers.Labels;
+import org.apache.streampipes.vocabulary.SO;
+
+import static org.apache.streampipes.sdk.helpers.EpProperties.stringEp;
+import static org.apache.streampipes.sdk.helpers.EpProperties.timestampProperty;
+
+public class SlackAdapter extends SpecificDataStreamAdapter {
+
+  public static final String ID = "http://streampipes.org/adapter/specific/slack";
+
+  private static final String SlackToken = "slack-token";
+  private static final String Timestamp = "timestamp";
+  private static final String Message = "message";
+  private static final String Author = "author";
+  private static final String Channel = "channel";
+
+  private String slackApiToken;
+  private Thread thread;
+  private SlackConsumer consumer;
+
+  public SlackAdapter() {
+    super();
+  }
+
+  public SlackAdapter(SpecificAdapterStreamDescription adapterStreamDescription) {
+    super(adapterStreamDescription);
+    ParameterExtractor extractor = new ParameterExtractor(adapterStreamDescription.getConfig());
+    this.slackApiToken = extractor.singleValue(SlackToken);
+  }
+
+  @Override
+  public SpecificAdapterStreamDescription declareModel() {
+    return SpecificDataStreamAdapterBuilder.create(ID, "Slack", "Subscribes to a Slack channel")
+            .category(AdapterType.SocialMedia)
+            .iconUrl("slack.png")
+            .requiredTextParameter(Labels.from(SlackToken, "Slack API Token", "The API token of " +
+                    "your Slack workspace"))
+            .build();
+  }
+
+  @Override
+  public void startAdapter() throws AdapterException {
+    this.consumer = new SlackConsumer(adapterPipeline, slackApiToken);
+    this.thread = new Thread(consumer);
+    this.thread.start();
+  }
+
+  @Override
+  public void stopAdapter() throws AdapterException {
+    this.consumer.stop();
+    this.thread.stop();
+  }
+
+  @Override
+  public Adapter getInstance(SpecificAdapterStreamDescription adapterDescription) {
+    return new SlackAdapter(adapterDescription);
+  }
+
+  @Override
+  public GuessSchema getSchema(SpecificAdapterStreamDescription adapterDescription) throws AdapterException, ParseException {
+    return GuessSchemaBuilder.create()
+            .property(timestampProperty(Timestamp))
+            .property(stringEp(Labels.from(Author, "Author", "The username of the sender of the " +
+                            "Slack message"),
+                    Author, SO.Text))
+            .property(stringEp(Labels.from(Channel, "Channel", "The Slack channel"), Channel,
+                    SO.Text))
+            .property(stringEp(Labels.from(Message, "Message", "The Slack message"),
+                    Message, SO.Text))
+            .build();
+  }
+
+  @Override
+  public String getId() {
+    return ID;
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/slack/SlackConsumer.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/slack/SlackConsumer.java
new file mode 100644
index 0000000..ef262dd
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/slack/SlackConsumer.java
@@ -0,0 +1,77 @@
+/*
+ * 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.connect.adapters.slack;
+
+import com.ullink.slack.simpleslackapi.SlackSession;
+import com.ullink.slack.simpleslackapi.SlackUser;
+import com.ullink.slack.simpleslackapi.impl.SlackSessionFactory;
+import com.ullink.slack.simpleslackapi.listeners.SlackMessagePostedListener;
+import org.apache.streampipes.connect.adapter.model.pipeline.AdapterPipeline;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class SlackConsumer implements Runnable {
+
+  private AdapterPipeline adapterPipeline;
+  private String apiToken;
+  private SlackSession session;
+
+  public SlackConsumer(AdapterPipeline adapterPipeline, String slackApiToken) {
+    this.adapterPipeline = adapterPipeline;
+    this.apiToken = slackApiToken;
+  }
+
+  public void run() {
+    SlackMessagePostedListener messagePostedListener = (event, session) -> {
+      String botName = session.sessionPersona().getUserName();
+      String channelOnWhichMessageWasPosted = event.getChannel().getName();
+      String messageContent = event.getMessageContent();
+      SlackUser messageSender = event.getSender();
+
+      if (!messageSender.getUserName().equals(botName)) {
+        Map<String, Object> outEvent = new HashMap<>();
+        outEvent.put("timestamp", System.currentTimeMillis());
+        outEvent.put("channel", channelOnWhichMessageWasPosted);
+        outEvent.put("author", messageSender.getUserName());
+        outEvent.put("message", messageContent);
+
+        adapterPipeline.process(outEvent);
+      }
+    };
+
+    this.session = SlackSessionFactory.createWebSocketSlackSession(apiToken);
+    try {
+      this.session.connect();
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+    this.session.addMessagePostedListener(messagePostedListener);
+  }
+
+  public void stop() {
+    try {
+      this.session.disconnect();
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+  }
+}
+
+
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/ti/TISensorTag.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/ti/TISensorTag.java
new file mode 100644
index 0000000..b0c51f1
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/ti/TISensorTag.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2018 FZI Forschungszentrum Informatik
+ *
+ * Licensed 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.connect.adapters.ti;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.model.pipeline.AdapterPipeline;
+import org.apache.streampipes.connect.adapter.model.specific.SpecificDataStreamAdapter;
+import org.apache.streampipes.connect.protocol.stream.MqttConfig;
+import org.apache.streampipes.connect.protocol.stream.MqttConsumer;
+import org.apache.streampipes.messaging.InternalEventProcessor;
+import org.apache.streampipes.model.AdapterType;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.sdk.StaticProperties;
+import org.apache.streampipes.sdk.builder.adapter.GuessSchemaBuilder;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataStreamAdapterBuilder;
+import org.apache.streampipes.sdk.extractor.StaticPropertyExtractor;
+import org.apache.streampipes.sdk.helpers.Alternatives;
+import org.apache.streampipes.sdk.helpers.Labels;
+import org.apache.streampipes.vocabulary.SO;
+import org.apache.streampipes.vocabulary.SPSensor;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.streampipes.sdk.helpers.EpProperties.*;
+
+public class TISensorTag extends SpecificDataStreamAdapter {
+
+    private Logger logger = LoggerFactory.getLogger(TISensorTag.class);
+
+    public static final String ID = "http://streampipes.org/adapter/specific/tisensortag";
+
+    private static final String ACCESS_MODE = "access_mode";
+    private static final String ANONYMOUS_ACCESS = "anonymous-alternative";
+    private static final String USERNAME_ACCESS = "username-alternative";
+    private static final String USERNAME = "username";
+    private static final String PASSWORD = "password";
+
+
+    private static final String TIMESTAMP = "timestamp";
+    private static final String AMBIENT_TEMP = "ambientTemp";
+    private static final String OBJECT_TEMP = "objectTemp";
+    private static final String HUMIDITY = "humidity";
+    private static final String ACCELERATION_X = "accelX";
+    private static final String ACCELERATION_Y = "accelY";
+    private static final String ACCELERATION_Z = "accelZ";
+    private static final String GYROSCOPE_X = "gyroX";
+    private static final String GYROSCOPE_Y = "gyroY";
+    private static final String GYROSCOPE_Z = "gyroZ";
+    private static final String MAGNETOMETER_X = "magX";
+    private static final String MAGNETOMETER_Y = "magY";
+    private static final String MAGNETOMETER_Z = "magZ";
+    private static final String LIGHT = "light";
+    private static final String KEY_1 = "key1";
+    private static final String KEY_2 = "key2";
+
+    private MqttConsumer mqttConsumer;
+    private MqttConfig mqttConfig;
+    private Thread thread;
+
+    public TISensorTag() {
+        super();
+    }
+
+    public TISensorTag(SpecificAdapterStreamDescription adapterDescription, MqttConfig mqttConfig) {
+        super(adapterDescription);
+        this.mqttConfig = mqttConfig;
+    }
+
+    @Override
+    public SpecificAdapterStreamDescription declareModel() {
+
+        SpecificAdapterStreamDescription description = SpecificDataStreamAdapterBuilder.create(ID, "TI Sensor Tag", "")
+                .iconUrl("ti_sensor_tag.png")
+                .category(AdapterType.Environment, AdapterType.OpenData)
+                .requiredTextParameter(Labels.from("broker_url", "Broker URL",
+                        "Example: tcp://test-server.com:1883 (Protocol required. Port required)"))
+                .requiredAlternatives(Labels.from(ACCESS_MODE, "Access Mode", ""),
+                        Alternatives.from(Labels.from(ANONYMOUS_ACCESS, "Unauthenticated", "")),
+                        Alternatives.from(Labels.from(USERNAME_ACCESS, "Username/Password", ""),
+                                StaticProperties.group(Labels.withId("username-group"),
+                                        StaticProperties.stringFreeTextProperty(Labels.from(USERNAME,
+                                                "Username", "")),
+                                        StaticProperties.secretValue(Labels.from(PASSWORD,
+                                                "Password", "")))))
+                .requiredTextParameter(Labels.from("topic", "Topic","Example: test/topic"))
+                .build();
+
+        description.setAppId(ID);
+        return description;
+    }
+
+    @Override
+    public void startAdapter() throws AdapterException {
+        this.mqttConsumer = new MqttConsumer(this.mqttConfig, new EventProcessor(adapterPipeline));
+
+        thread = new Thread(this.mqttConsumer);
+        thread.start();
+    }
+
+    @Override
+    public void stopAdapter() throws AdapterException {
+        this.mqttConsumer.close();
+    }
+
+    @Override
+    public Adapter getInstance(SpecificAdapterStreamDescription adapterDescription) {
+        MqttConfig mqttConfig;
+        StaticPropertyExtractor extractor =
+                StaticPropertyExtractor.from(adapterDescription.getConfig(), new ArrayList<>());
+
+        String brokerUrl = extractor.singleValueParameter("broker_url", String.class);
+        String topic = extractor.singleValueParameter("topic", String.class);
+        String selectedAlternative = extractor.selectedAlternativeInternalId("access_mode");
+
+        if (selectedAlternative.equals(ANONYMOUS_ACCESS)) {
+            mqttConfig = new MqttConfig(brokerUrl, topic);
+        } else {
+            String username = extractor.singleValueParameter(USERNAME, String.class);
+            String password = extractor.secretValue(PASSWORD);
+            mqttConfig = new MqttConfig(brokerUrl, topic, username, password);
+        }
+
+        return new TISensorTag(adapterDescription, mqttConfig);
+    }
+
+    @Override
+    public GuessSchema getSchema(SpecificAdapterStreamDescription adapterDescription) {
+        return GuessSchemaBuilder.create()
+                .property(timestampProperty(TIMESTAMP))
+                .property(doubleEp(Labels.from(AMBIENT_TEMP, "Ambient Temperature", ""),
+                        AMBIENT_TEMP, SO.Number))
+                .property(doubleEp(Labels.from(OBJECT_TEMP, "Object Temperature", ""),
+                        OBJECT_TEMP, SO.Number))
+                .property(doubleEp(Labels.from(HUMIDITY, "Humidity", ""),
+                        HUMIDITY, SO.Number))
+                .property(doubleEp(Labels.from(ACCELERATION_X, "Acceleration X", ""),
+                        ACCELERATION_X, SPSensor.ACCELERATION_X))
+                .property(doubleEp(Labels.from(ACCELERATION_Y, "Acceleration Y", ""),
+                        ACCELERATION_Y, SPSensor.ACCELERATION_Y))
+                .property(doubleEp(Labels.from(ACCELERATION_Z, "Acceleration Z", ""),
+                        ACCELERATION_Z, SPSensor.ACCELERATION_Z))
+                .property(doubleEp(Labels.from(GYROSCOPE_X, "Gyroscope X", ""),
+                        GYROSCOPE_X, SO.Number))
+                .property(doubleEp(Labels.from(GYROSCOPE_Y, "Gyroscope Y", ""),
+                        GYROSCOPE_Y, SO.Number))
+                .property(doubleEp(Labels.from(GYROSCOPE_Z, "Gyroscope Z", ""),
+                        GYROSCOPE_Z, SO.Number))
+                .property(doubleEp(Labels.from(MAGNETOMETER_X, "Magnetometer X", ""),
+                        MAGNETOMETER_X, SO.Number))
+                .property(doubleEp(Labels.from(MAGNETOMETER_Y, "Magnetometer Y", ""),
+                        MAGNETOMETER_Y, SO.Number))
+                .property(doubleEp(Labels.from(MAGNETOMETER_Z, "Magnetometer Z", ""),
+                        MAGNETOMETER_Z, SO.Number))
+                .property(doubleEp(Labels.from(LIGHT, "Light", ""),
+                        LIGHT, SO.Number))
+                .property(booleanEp(Labels.from(KEY_1, "Key 1", ""),
+                        KEY_1, SO.Boolean))
+                .property(booleanEp(Labels.from(KEY_2, "Key 2", ""),
+                        KEY_2, SO.Boolean))
+                .build();
+    }
+
+    @Override
+    public String getId() {
+        return ID;
+    }
+
+    private class EventProcessor implements InternalEventProcessor<byte[]> {
+        private AdapterPipeline adapterPipeline;
+
+        public EventProcessor(AdapterPipeline adapterpipeline) {
+            this.adapterPipeline = adapterpipeline;
+        }
+
+        @Override
+        public void onEvent(byte[] payload) {
+            Map<String, Object> result = parseEvent(new String(payload));
+            adapterPipeline.process(result);
+        }
+    }
+
+    public static Map<String, Object> parseEvent(String s) {
+       Map<String, Object> result = new HashMap<>();
+       String[] lines = s.split("\n");
+       for (String line : lines) {
+           if (line.startsWith("\"")) {
+              line = line.replaceAll(",", "").replaceAll("\"", "");
+              String[] keyValue = line.split(":");
+
+              // convert keys to boolean, other sensor values are doubles
+              if (keyValue[0].startsWith("key")) {
+                  result.put(keyValue[0], Double.parseDouble(keyValue[1]) == 1.0);
+              } else {
+                  result.put(keyValue[0], Double.parseDouble(keyValue[1]));
+              }
+           }
+       }
+
+       if (!result.containsKey("key1") || !result.containsKey("key2")) {
+           result.put("key1", false);
+           result.put("key2", false);
+       }
+
+       result.put(TIMESTAMP, System.currentTimeMillis());
+
+       return result;
+    }
+}
\ No newline at end of file
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/WikipediaAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/WikipediaAdapter.java
new file mode 100644
index 0000000..971dd4c
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/WikipediaAdapter.java
@@ -0,0 +1,144 @@
+/*
+ * 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.connect.adapters.wikipedia;
+
+import com.google.gson.Gson;
+import org.apache.streampipes.connect.adapter.exception.AdapterException;
+import org.apache.streampipes.connect.adapter.exception.ParseException;
+import org.apache.streampipes.connect.adapter.model.specific.SpecificDataStreamAdapter;
+import org.apache.streampipes.connect.adapters.wikipedia.model.WikipediaModel;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.model.connect.guess.GuessSchema;
+import org.apache.streampipes.sdk.builder.adapter.GuessSchemaBuilder;
+import org.apache.streampipes.sdk.helpers.Labels;
+
+import static org.apache.streampipes.sdk.helpers.EpProperties.*;
+
+public abstract class WikipediaAdapter extends SpecificDataStreamAdapter {
+
+  public static final String TIMESTAMP = "timestamp";
+  public static final String TYPE = "type";
+  public static final String EVENT_ID = "id";
+  public static final String NAMESPACE = "namespace";
+  public static final String TITLE = "title";
+  public static final String USER = "user";
+  public static final String BOT = "bot";
+  public static final String MINOR = "minor";
+  public static final String OLDLENGTH = "oldlength";
+  public static final String NEWLENGTH = "newlength";
+  public static final String OLDREVISION = "oldrevision";
+  public static final String NEWREVISION = "newrevision";
+  public static final String SERVERURL = "serverurl";
+  public static final String SERVERNAME = "servername";
+  public static final String WIKI = "wiki";
+  public static final String URI = "uri";
+  public static final String COMMENT = "comment";
+  public static final String DOMAIN = "domain";
+
+  private static final String VocabPrefix = "http://wikipedia.org/";
+  private static final String WikipediaApiUrl = "https://stream.wikimedia"
+          + ".org/v2/stream/recentchange";
+
+  private Thread thread;
+  private String type;
+  private WikipediaSseConsumer consumer;
+
+  public WikipediaAdapter(SpecificAdapterStreamDescription adapterStreamDescription, String type) {
+    super(adapterStreamDescription);
+    this.type = type;
+  }
+
+  public WikipediaAdapter() {
+    super();
+  }
+
+  @Override
+  public void startAdapter() throws AdapterException {
+    Gson gson = new Gson();
+    Runnable runnable = () -> {
+      this.consumer = new WikipediaSseConsumer();
+      try {
+        this.consumer.consumeEventStream(WikipediaApiUrl,
+                event -> {
+                  WikipediaModel wikipediaModel = gson.fromJson(event, WikipediaModel.class);
+                  if (wikipediaModel != null && wikipediaModel.getType() != null) {
+                    if (wikipediaModel.getType().equals(type)) {
+                      adapterPipeline.process(new WikipediaModelConverter(wikipediaModel).makeMap());
+                    }
+                  }
+                });
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    };
+
+    this.thread = new Thread(runnable);
+    this.thread.start();
+  }
+
+  @Override
+  public void stopAdapter() throws AdapterException {
+    if (this.thread != null) {
+      this.consumer.stop();
+    }
+  }
+
+  @Override
+  public GuessSchema getSchema(SpecificAdapterStreamDescription adapterDescription) throws AdapterException, ParseException {
+    return GuessSchemaBuilder.create()
+            .property(timestampProperty(TIMESTAMP))
+            .property(stringEp(Labels.from(EVENT_ID, "ID", ""), EVENT_ID, dp(EVENT_ID)))
+            .property(stringEp(Labels.from(TYPE, "Type", "The change type (edit|new)"),
+                    TYPE, dp(TYPE)))
+            .property(integerEp(Labels.from(NAMESPACE, "Namespace",
+                    "The Wikipedia namespace"), NAMESPACE, dp(NAMESPACE)))
+            .property(stringEp(Labels.from(TITLE, "Title", "The article title"),
+                    TITLE, dp(TITLE)))
+            .property(stringEp(Labels.from(USER, "User", "The user ID"),
+                    USER, dp(USER)))
+            .property(booleanEp(Labels.from(BOT, "Bot", "Edited by a bot"),
+                    BOT, dp(BOT)))
+            .property(booleanEp(Labels.from(MINOR, "Minor", "Minor edit"),
+                    MINOR, dp(MINOR)))
+            .property(integerEp(Labels.from(OLDLENGTH, "Old length", ""),
+                    OLDLENGTH, dp(OLDLENGTH)))
+            .property(integerEp(Labels.from(NEWLENGTH, "New length", ""),
+                    NEWLENGTH, dp(NEWLENGTH)))
+            .property(longEp(Labels.from(OLDREVISION, "Old revision ID", ""),
+                    OLDREVISION, dp(OLDREVISION)))
+            .property(longEp(Labels.from(NEWREVISION, "New revision ID", ""),
+                    NEWREVISION, dp(NEWREVISION)))
+            .property(stringEp(Labels.from(SERVERURL, "Server URL", ""),
+                    SERVERURL, dp(SERVERURL)))
+            .property(stringEp(Labels.from(SERVERNAME, "Server Name", ""),
+                    SERVERNAME, dp(SERVERNAME)))
+            .property(stringEp(Labels.from(WIKI, "Wiki Name", ""),
+                    WIKI, dp(WIKI)))
+            .property(stringEp(Labels.from(URI, "Internal URI", ""),
+                    URI, dp(URI)))
+            .property(stringEp(Labels.from(COMMENT, "Comment", "Comment field"),
+                    COMMENT, dp(COMMENT)))
+            .property(stringEp(Labels.from(DOMAIN, "Domain", "Wiki Domain"),
+                    DOMAIN, dp(DOMAIN)))
+            .build();
+  }
+
+  public String dp(String domainPropertyName) {
+    return VocabPrefix + domainPropertyName;
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/WikipediaEditedArticlesAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/WikipediaEditedArticlesAdapter.java
new file mode 100644
index 0000000..9d4aca4
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/WikipediaEditedArticlesAdapter.java
@@ -0,0 +1,57 @@
+/*
+ * 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.connect.adapters.wikipedia;
+
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.model.AdapterType;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataStreamAdapterBuilder;
+
+public class WikipediaEditedArticlesAdapter extends WikipediaAdapter {
+
+  public static final String ID = "http://streampipes.org/adapter/specific/wikipedia/edit";
+
+  private static final String Type = "edit";
+
+  public WikipediaEditedArticlesAdapter(SpecificAdapterStreamDescription adapterStreamDescription) {
+    super(adapterStreamDescription, Type);
+  }
+
+  public WikipediaEditedArticlesAdapter() {
+    super();
+  }
+
+  @Override
+  public SpecificAdapterStreamDescription declareModel() {
+    return SpecificDataStreamAdapterBuilder.create(ID, "Wikipedia Edits", "Continuously publishes" +
+            " recent Wikipedia edits")
+            .category(AdapterType.SocialMedia, AdapterType.OpenData)
+            .iconUrl("wikipedia.png")
+            .build();
+  }
+
+  @Override
+  public Adapter getInstance(SpecificAdapterStreamDescription adapterDescription) {
+    return new WikipediaEditedArticlesAdapter(adapterDescription);
+  }
+
+  @Override
+  public String getId() {
+    return ID;
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/WikipediaModelConverter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/WikipediaModelConverter.java
new file mode 100644
index 0000000..09ddb18
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/WikipediaModelConverter.java
@@ -0,0 +1,56 @@
+/*
+ * 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.connect.adapters.wikipedia;
+
+import org.apache.streampipes.connect.adapters.wikipedia.model.WikipediaModel;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.streampipes.connect.adapters.wikipedia.WikipediaAdapter.*;
+
+public class WikipediaModelConverter {
+
+  private WikipediaModel wikipediaModel;
+
+  public WikipediaModelConverter(WikipediaModel wikipediaModel) {
+    this.wikipediaModel = wikipediaModel;
+  }
+
+  public Map<String, Object> makeMap() {
+    Map<String, Object> event = new HashMap<>();
+    event.put(TIMESTAMP, wikipediaModel.getTimestamp());
+    event.put(TYPE, wikipediaModel.getType());
+    event.put(EVENT_ID, wikipediaModel.getId());
+    event.put(NAMESPACE, wikipediaModel.getNamespace());
+    event.put(TITLE, wikipediaModel.getTitle());
+    event.put(USER, wikipediaModel.getUser());
+    event.put(BOT, wikipediaModel.getBot());
+    event.put(MINOR, wikipediaModel.getMinor());
+    event.put(OLDLENGTH, wikipediaModel.getLength().getOld());
+    event.put(NEWLENGTH, wikipediaModel.getLength().getNew());
+    event.put(OLDREVISION, wikipediaModel.getRevision().getOld());
+    event.put(NEWREVISION, wikipediaModel.getRevision().getNew());
+    event.put(SERVERURL, wikipediaModel.getServerUrl());
+    event.put(SERVERNAME, wikipediaModel.getServerName());
+    event.put(WIKI, wikipediaModel.getWiki());
+    event.put(URI, wikipediaModel.getMeta().getUri());
+
+    return event;
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/WikipediaNewArticlesAdapter.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/WikipediaNewArticlesAdapter.java
new file mode 100644
index 0000000..d71278f
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/WikipediaNewArticlesAdapter.java
@@ -0,0 +1,59 @@
+/*
+ * 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.connect.adapters.wikipedia;
+
+import org.apache.streampipes.connect.adapter.Adapter;
+import org.apache.streampipes.model.AdapterType;
+import org.apache.streampipes.model.connect.adapter.SpecificAdapterStreamDescription;
+import org.apache.streampipes.sdk.builder.adapter.SpecificDataStreamAdapterBuilder;
+
+public class WikipediaNewArticlesAdapter extends WikipediaAdapter {
+
+  public static final String ID = "http://streampipes.org/adapter/specific/wikipedia/new";
+
+  private static final String Type = "new";
+
+  public WikipediaNewArticlesAdapter(SpecificAdapterStreamDescription adapterStreamDescription) {
+    super(adapterStreamDescription, Type);
+  }
+
+  public WikipediaNewArticlesAdapter() {
+    super();
+  }
+
+  @Override
+  public SpecificAdapterStreamDescription declareModel() {
+    return SpecificDataStreamAdapterBuilder.create(ID, "Wikipedia New Articles", "Continuously " +
+            "publishes" +
+            " articles recently created on Wikipedia")
+            .category(AdapterType.SocialMedia, AdapterType.OpenData)
+            .iconUrl("wikipedia.png")
+            .build();
+  }
+
+  @Override
+  public Adapter getInstance(SpecificAdapterStreamDescription adapterDescription) {
+    return new WikipediaNewArticlesAdapter(adapterDescription);
+  }
+
+
+  @Override
+  public String getId() {
+    return ID;
+  }
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/WikipediaSseConsumer.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/WikipediaSseConsumer.java
new file mode 100644
index 0000000..a9d5db9
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/WikipediaSseConsumer.java
@@ -0,0 +1,59 @@
+/*
+ * 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.connect.adapters.wikipedia;
+
+import org.glassfish.jersey.media.sse.EventInput;
+import org.glassfish.jersey.media.sse.InboundEvent;
+import org.glassfish.jersey.media.sse.SseFeature;
+import org.apache.streampipes.connect.adapter.util.AdapterOutputCollector;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.WebTarget;
+
+public class WikipediaSseConsumer {
+
+  private Boolean running = true;
+
+  public void consumeEventStream(String url, AdapterOutputCollector consumer) throws Exception {
+    Client client = ClientBuilder.newBuilder().register(new SseFeature()).build();
+    WebTarget target = client.target(url);
+    EventInput e = null;
+    while (running) {
+      Thread.sleep(100);
+      if (e == null || e.isClosed()) {
+        // (re)connect
+        e = target.request().get(EventInput.class);
+        e.setChunkType("text/event-stream");
+      }
+
+      final InboundEvent inboundEvent = e.read();
+      if (inboundEvent == null) {
+        break;
+      } else {
+        String data = inboundEvent.readData();
+        consumer.onEvent(data);
+      }
+    }
+  }
+
+  public void stop() {
+    this.running = false;
+  }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/model/Length.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/model/Length.java
new file mode 100644
index 0000000..b0cdd26
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/model/Length.java
@@ -0,0 +1,50 @@
+/*
+ * 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.connect.adapters.wikipedia.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import javax.annotation.Generated;
+
+@Generated("net.hexar.json2pojo")
+@SuppressWarnings("unused")
+public class Length {
+
+    @SerializedName("new")
+    private Long mNew;
+    @SerializedName("old")
+    private Long mOld;
+
+    public Long getNew() {
+        return mNew;
+    }
+
+    public void setNew(Long newLong) {
+        mNew = newLong;
+    }
+
+    public Long getOld() {
+        return mOld;
+    }
+
+    public void setOld(Long old) {
+        mOld = old;
+    }
+
+}
diff --git a/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/model/Meta.java b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/model/Meta.java
new file mode 100644
index 0000000..9d7a768
--- /dev/null
+++ b/streampipes-connect-adapters/streampipes-connect-adapter/src/main/java/org/apache/streampipes/connect/adapters/wikipedia/model/Meta.java
@@ -0,0 +1,120 @@
+/*
+ * 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
... 84454 lines suppressed ...


Mime
View raw message