---
id: extend-tutorial-adapters
title: "Tutorial: Build Custom Adapters"
sidebar_label: "Tutorial: Adapters"
---

In this tutorial, we will create a new data source consisting of a single data stream.
By the end of the tutorial, you will be able to implement custom adapters that allow you to connect to data sources
other than those officially supported by StreamPipes.
To do this, we will split the tutorial into two parts.
The [first part](#building-a-basic-adapter) focuses on creating the adapter and defining the event stream.
At the end, we will have a working adapter that produces an event stream that can be used in StreamPipes.
This adapter does not provide any way to configure its behavior, so in
the [second part](#building-a-more-advanced-adapter-by-processing-ui-input) of the tutorial
to show how we can extend our existing adapter to be configurable via the UI.

:::info
This tutorial shows how to build your own type of adapter.
It is intended for people who are interested in extending StreamPipes to meet their own needs.
If you are here to explore StreamPipes and are interested in using an adapter, you may want to
continue [here](./03_use-connect.md).
:::

## Objective

We are going to create an adapter that will simulate a stream of data generated by a control station in a logistics
center that is used to sort packages.
This station consists of two sensors: a light barrier that detects when a package passes through, and a weight sensor.

This sensor produces a continuous stream of events containing the current time stamp, an indicator of whether a package
is present or the conveyor is empty, and the weight of the package in kilograms.
The events are published in JSON format as follows

```json
{
  "timestamp": 1697720916959,
  "parcelPresent": true,
  "weight": 3.520
}
```

In the following section, we will show you how to develop an adapter that is capable of generating this stream so that
it is available for further processing in StreamPipes.

## Project Set Up

Instead of creating a new project from scratch, we recommend to use our Maven archetype to create a new project
skeleton (`streampipes-archetype-extensions-jvm`).
Enter the following command in a command line of your choice (please ensure
that [Apache Maven](https://maven.apache.org/install.html) isinstalled):

```bash
mvn archetype:generate \
-DarchetypeGroupId=org.apache.streampipes -DarchetypeArtifactId=streampipes-archetype-extensions-jvm \
-DarchetypeVersion=0.93.0 -DgroupId=org.apache.streampipes \
-DartifactId=streampipes-archetype-extensions-jvm -DclassNamePrefix=ParcelControlStation -DpackageName=parcelcontrol
```

This command will ask you for input twice, you can just skip both of them by hitting *enter*.
The first dialog sets the version to use for our `streampipes-archetype-extensions-jvm` module.
Feel free to change this if you like.

```bash
Define value for property 'version' 1.0-SNAPSHOT: : 

 Y: : 
```

The `mvn archetype:generate` command generates some required files, the required file structure, and some boilerplate
code.
The generated file structure should look like the following:

:::info
Note that you can customize the parameters of the mvn command to affect the file structure and file naming.
:::

```bash

|streampipes-archetype-extensions  # name is determined by '-DartifactId'
|-- development
|   |-- env 
|-- src
|   |-- main
|   |   |-- java.org.apache.streampipes  # name after .java. is determined by '-DgroupId'
|   |   |   |-- pe.parcelcontrol  # name after .pe. is determined by '-DpackageName'
|   |   |   |   |-- ParcelControlStationDataProcessor.java  # class name is determined by '-DclassNamePrefix'
|   |   |   |   |-- ParcelControlStationDataSink.java
|   |   |   |   |-- ParcelControlStationGenericAdapter.java
|   |   |   |   |-- ParcelControlStationSpecificAdapter.java
|   |   |   |-- Init.java
|   |   |-- resources
|   |   |   |-- org.apache.streampipes.pe.parcelcontrol.genericadapter
|   |   |   |   |-- documentation.md
|   |   |   |   |-- icon.png
|   |   |   |   |-- strings.en
|   |   |   |-- org.apache.streampipes.pe.parcelcontrol.processor
|   |   |   |   |-- documentation.md
|   |   |   |   |-- icon.png
|   |   |   |   |-- strings.en
|   |   |   |-- org.apache.streampipes.pe.parcelcontrol.sink
|   |   |   |   |-- documentation.md
|   |   |   |   |-- icon.png
|   |   |   |   |-- strings.en
|   |   |   |-- org.apache.streampipes.pe.parcelcontrol.specificadapter
|   |   |   |   |-- documentation.md
|   |   |   |   |-- icon.png
|   |   |   |   |-- strings.en
|   |-- test.java.org.apache.streampipes  # name after .java. is determined by '-DgroupId'
|   |   |-- InitTest.java
|-- Dockerfile
|-- pom.xml

```

:::tip
In addition to the basic project skeleton, the sample project also includes a sample `Dockerfile` that you can use to
package your application into a Docker container.
:::

## Building a Basic Adapter

In the following, we will demonstrate how to use the boilerplate code generated by the Maven plugin (
see [Project setup](#project-setup)).
Within this section, we will focus on creating an event stream that can be used within StreamPipes.
The following section shows how to configure the created adapter with UI input.

Attentive readers may have noticed that two adapter classes have been generated.
We will focus on the `ParcelControlStationSpecificAdapter` first, the `ParcelControlStationSimulatorGenericAdapter` will
be used later for more advanced adapter features.
First, let us take a look at the `ParcelControlStationSpecificAdapter.java` file as generated by the Maven
archetype.

```java jsx showLineNumbers
package org.apache.streampipes.pe.parcelcontrol;

import org.apache.streampipes.commons.exceptions.connect.AdapterException;
import org.apache.streampipes.extensions.api.connect.IAdapterConfiguration;
import org.apache.streampipes.extensions.api.connect.IEventCollector;
import org.apache.streampipes.extensions.api.connect.StreamPipesAdapter;
import org.apache.streampipes.extensions.api.connect.context.IAdapterGuessSchemaContext;
import org.apache.streampipes.extensions.api.connect.context.IAdapterRuntimeContext;
import org.apache.streampipes.extensions.api.extractor.IAdapterParameterExtractor;
import org.apache.streampipes.model.AdapterType;
import org.apache.streampipes.model.connect.guess.GuessSchema;
import org.apache.streampipes.sdk.builder.adapter.AdapterConfigurationBuilder;
import org.apache.streampipes.sdk.builder.adapter.GuessSchemaBuilder;
import org.apache.streampipes.sdk.helpers.Labels;
import org.apache.streampipes.sdk.helpers.Locales;

import java.util.HashMap;
import java.util.Map;

public class ParcelControlStationSpecificAdapter implements StreamPipesAdapter {

  private boolean running = false;

  @Override
  public IAdapterConfiguration declareConfig() {
    return AdapterConfigurationBuilder.create(
        "org.apache.streampipes.pe.parcelcontrol.specificadapter",
        ParcelControlStationSpecificAdapter::new
      )
      .withAssets(Assets.DOCUMENTATION, Assets.ICON)
      .withCategory(AdapterType.Manufacturing)
      .withLocales(Locales.EN)
      .buildConfiguration();
  }

  @Override
  public void onAdapterStarted(IAdapterParameterExtractor extractor,
                               IEventCollector collector,
                               IAdapterRuntimeContext adapterRuntimeContext) throws AdapterException {

    Runnable demo = () -> {
      while (running) {
        // make event
        Map<String, Object> event = new HashMap<>();
        // forward the event to the adapter pipeline
        collector.collect(event);
      }
    };
    running = true;
    new Thread(demo).start();
  }

  @Override
  public void onAdapterStopped(IAdapterParameterExtractor extractor,
                               IAdapterRuntimeContext adapterRuntimeContext) throws AdapterException {

    // do cleanup
    running = false;
  }

  @Override
  public GuessSchema onSchemaRequested(IAdapterParameterExtractor extractor,
                                       IAdapterGuessSchemaContext adapterGuessSchemaContext) throws AdapterException {

    // build the schema by adding properties to the schema builder and a preview if possible
    return GuessSchemaBuilder
      .create()
      .build();
    }
  }

```

The class extends `StreamPipesAdapter`, which is the interface that all adapters within StreamPipes must implement.
This interface requires us to implement four methods:

* `declareConfig()`: This method is expected to return the configuration of the adapter. The configuration includes
  metadata about the adapter and its input parameters.
* `onAdapterStarted()`: This method is expected to contain the actual adapter logic. It is called when the adapter is
  started, and is responsible for sending incoming data to StreamPipes as an event.
* `onAdapterStopped()`: This method is called when the adapter is stopped and is responsible for gracefully exiting the
  adapter.
  gracefully and usually performs some cleanup tasks.
* `onSchemaRequested()`: This method is expected to return the schema of the event stream. This is ideally done
  dynamically based on some incoming data (*guess*) or provided statically if not otherwise possible.

### Describing the Adapter via the Configuration

The standard code generated here is already sufficient for us.
So let's have a quick look at the important aspects:

* `Line 4`: Here we define a unique identifier for our adapter. This allows us to identify all instances of the same
  adapter. Including your own namespace is always a good choice to avoid conflicts.
* `Line 7`: Here we define what assets are available for this adapter. In this case, we provide a documentation file and
  an icon. Both assets are located in the `resource' directory (see file tree above).
* `Line 8`: This defines a rough categorization along predefined adapter types.
* `Line 9`: Here we define which locales are available for this adapter. Since we only provide one `strings.en' file so
  far (see file tree above), the current selection is sufficient. Theoretically you can support multiple languages, but
  this is not fully supported yet.

```java jsx {4,7-9} showLineNumbers
  @Override
  public IAdapterConfiguration declareConfig() {
    return AdapterConfigurationBuilder.create(
        "org.apache.streampipes.pe.parcelcontrol.specificadapter",
        ParcelControlStationSpecificAdapter::new
      )
      .withAssets(Assets.DOCUMENTATION, Assets.ICON)
      .withCategory(AdapterType.Manufacturing)
      .withLocales(Locales.EN)
      .buildConfiguration();
  }
```

Before we continue, let's quickly have a look at the `strings.en` file that defines our locales.
Here we can define a meaningful and human-readable adapter tile in the first line and a short description:

```text
org.apache.streampipes.pe.parcelcontrol.specificadapter.title=Parcel Control Station (simple)
org.apache.streampipes.pe.parcelcontrol.specificadapter.description=This adapter simulates data coming from a parcel control station in a logistics center.
```

Now we have successfully configured our adapter and prepared all descriptive elements, we can focus on the actual logic.

### Creating the Data Stream

The logic that creates events that are then populated via StreamPipes is defined in `onAdapterStarted()`.
Within this method, connectors usually connect to the data source and extract data.
In our case, however, we simply want to create some sample data directly.
The two main parts that should always happen within this method are highlighted in the provided skeleton code:

* `Line 10`: Creating an event is crucial for our adapters. This event is then filled with data by the adapter before it
  is distributed.
* `Line 13`: The event must finally be passed to the `collector`, which then takes the data and distributes it within
  StreamPipes in the form of a [data stream](./02_concepts-overview.md#data-stream).

```java jsx {10,13} showLineNumbers
@Override
public void onAdapterStarted(IAdapterParameterExtractor extractor,
                             IEventCollector collector,
                             IAdapterRuntimeContext adapterRuntimeContext) throws AdapterException {

  Runnable demo = () -> {
    while (running) {
    
      // make event
      Map<String, Object> event = new HashMap<>();
      
      // forward the event to the adapter pipeline
      collector.collect(event);
    }
  };
  running = true;
  new Thread(demo).start();
}
```

So the only thing left to do is to create the actual events.
In our scenario, we want to create two types of events: one describing an empty conveyor and one describing a detected
and weighed package.
To keep the implementation simple, we simply want to have a parcel event every five seconds. We can implement this as
follows:

```java
 Runnable parcelControl = () -> {
    while (running) {
    
      // get the current time in seconds
      long timestamp = System.currentTimeMillis();
      long timeInSeconds = (int) timestamp / 1000;
    
      // make event
      Map<String, Object> event = new HashMap<>();
      event.put("timestamp", timestamp);
      
      if (timeInSeconds % 5 == 0) {
        event.put("parcelPresent", true);
        event.put("weight", ThreadLocalRandom.current().nextDouble(0, 10));
        
      } else {
        event.put("parcelPresent", false);
        event.put("weight", 0);
      }
      
      // forward the event to the adapter pipeline
      collector.collect(event);

      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        throw new RuntimeException(e);
      }
    }
  };
  running = true;
  new Thread(parcelControl).start();
```

This is already enough to get a data stream into StreamPipes.
As the next step we need to describe to event schema.

### Defining the Event Schema

In StreamPipes, each data stream comes with an event schema that describes what information the event contains,
in what data formats, and some semantic type information.
This allows StreamPipes to provide easy and convenient stream handling with a lot of automatic conversions and
validations.
For example, whether a particular data processor is suitable for a given event stream.
This event schema is provided by `onSchemaRequested()`:

```java
@Override
public GuessSchema onSchemaRequested(IAdapterParameterExtractor extractor,
                                     IAdapterGuessSchemaContext adapterGuessSchemaContext) throws AdapterException {

  // build the schema by adding properties to the schema builder and a preview if possible
  return GuessSchemaBuilder
    .create()
    .build();
  }

```

Normally, the event schema is determined automatically and dynamically, since an adapter is usually quite generic (read
more in the [Advanced section](#advanced)).
But in our case, we already know the event schema, and it never changes, so we can just define it:

```java jsx {3,13-20} showLineNumbers
@Override
public GuessSchema onSchemaRequested(IAdapterParameterExtractor extractor,
                                     IAdapterGuessSchemaContext adapterGuessSchemaContext) throws AdapterException {

  // build the schema by adding properties to the schema builder and a preview if possible
  return GuessSchemaBuilder.create()
          .property(timestampProperty("timestamp"))
          .sample("timestamp", System.currentTimeMillis())
          .property(PrimitivePropertyBuilder
                  .create(Datatypes.Boolean, "parcelPresent")
                  .label("Parcel Present")
                  .description("Indicates if a parcel is weighed.")
                  .domainProperty(SO.BOOLEAN)
                  .scope(PropertyScope.MEASUREMENT_PROPERTY)
                  .build())
          .sample("parcelPresent", true)
          .property(PrimitivePropertyBuilder
                  .create(Datatypes.Double, "weight")
                  .label("Parcel Weight")
                  .description("Parcel weight")
                  .domainProperty(SO.WEIGHT)
                  .scope(PropertyScope.MEASUREMENT_PROPERTY)
                  .build())
          .sample("weight", 3.520)
          .build();
```

An attribute of an Event is referred to as `property` in StreamPipes.
So in our case we have three properties.
Since StreamPipes creates a sample event in the UI when configuring the adapter (
see [here](./03_use-connect.md#schema-editor)),
providing a meaningful sample value for every property allows StreamPipes to demonstrate its full potential.

Since every event schema is required to have a timestamp property, we provide a convenience definition (see `line 3`).
For all other properties the recommend way of definition is using the `PrimitivePropertyBuilder` (see `line 13-20`) and
consists of the following steps:

* `Line 14`: every property must have a data type specified and a property name
* `Line 15`: In addition to the property name we can define a label that is designed for the end user and shown in the
  UI.
* `Line 16`: Assigns a human-readable description to the event property. The description is used in the StreamPipes UI
  for better explaining users the meaning of the property.
* `Line 17`: Specifies the semantics of the property (e.g., whether a double value stands for weight or temperature
  value).
* `Line 18`: Assigns a property scope to the event property. This determines how the property is handled internally.

:::note
StreamPipes does not require you to provide all of this information about a property.
Anything beyond line `14` (up to line `20`) is optional, but the more you provide, the better StreamPipes can show it's
full potential and feature richness.
:::

This makes our adapter almost complete, there is only one little step left.

### Defining the Adapter Termination

As a final step, we need to define what should happen if the adapter is stopped.
In general, the adapter should not fire any events after that.
Normally, this step includes things like closing connections and clearing resources.
In our case this is quite simple, we just need to stop our thread:

```java
@Override
public void onAdapterStopped(IAdapterParameterExtractor extractor,
                             IAdapterRuntimeContext adapterRuntimeContext) throws AdapterException {

  // do cleanup
  running = false;
}
```

Now it's time to start our adapter and observe it in action!

### Register and Run the Adapter

Before we actually use our adapter, let's take a quick look at the `Init` class. This class is responsible for
registering our adapter service with the core to make the adapter available in StreamPipes.
This is done within `provideServiceDefinition()`. Since we don't have the generic adapter ready yet,
we'll comment out its registration (`line 7`). Now we can run the `Init` class to register the adapter with your running
StreamPipes instance. If you don't have a running instance at your hand,
you can take a look at our [Installation Guide](./01_try-installation.md).

```java jsx {7-8} showLineNumbers
@Override
public SpServiceDefinition provideServiceDefinition() {
  return SpServiceDefinitionBuilder.create("org.apache.streampipes",
          "human-readable service name",
          "human-readable service description", 8090)
      .registerRuntimeProvider(new StandaloneStreamPipesRuntimeProvider())
      //.registerAdapter(new ParcelControlStationGenericAdapter())
      .registerAdapter(new ParcelControlStationSpecificAdapter())
      .registerMessagingFormats(
          new JsonDataFormatFactory(),
          new CborDataFormatFactory(),
          new SmileDataFormatFactory(),
          new FstDataFormatFactory())
      .registerMessagingProtocols(
          new SpKafkaProtocolFactory(),
          new SpJmsProtocolFactory(),
          new SpMqttProtocolFactory(),
          new SpNatsProtocolFactory(),
          new SpPulsarProtocolFactory())
      .build();
}
 ```

:::tip
When executing the `main()` method of the `Init` class, make sure that all environment variables are set from
the `development/env` file are set.
If they are not set, the adapter may not be able to register with StreamPipes.
:::

Once you see the following log message in the console, the adapter is ready, and you can switch to the UI of your
StreamPipes instance.

```bash
s.s.e.c.ConnectWorkerRegistrationService : Successfully connected to master. Worker is now running.
```

Please go to the connect module and click on `New Adapter`,
you should now be able to see your adapter `Parcel Control Station (simple)`:
<img src="/img/06_tutorial_adapter/adapter-demo.gif" alt="Demo of parcel adapter"/>

The adapter runs successfully in StreamPipes, you can now play around with the data stream that the
adapter, or continue with the next section to learn how to make an adapter configurable through the UI.

### Building a more Advanced Adapter by Processing UI Input

In this section, we will extend our previous build apter by adding the ability to configure the minimum and maximum
package
in the UI from which the weight value is retrieved.
The beauty of building adapters for StreamPipes is that you don't have to worry about the UI.
StreamPipes provides a set of pre-built input elements for adapters that you can simply add to your adapter
configuration.
So the first thing we need to customize is `declareConfig()`:

```java jsx {10-11} showLineNumbers
@Override
public IAdapterConfiguration declareConfig() {
  return AdapterConfigurationBuilder.create(
                  "org.apache.streampipes.pe.parcelcontrol.specificadapter",
                  ParcelControlStationSpecificAdapter::new
          )
          .withAssets(Assets.DOCUMENTATION, Assets.ICON)
          .withCategory(AdapterType.Manufacturing)
          .withLocales(Locales.EN)
          .requiredFloatParameter(Labels.withId("min-weight"), 0.0f)
          .requiredFloatParameter(Labels.withId("max-weight"), 10.f)
          .buildConfiguration();
}

```

In line `9-10` we have introduced two input parameters that expect float values as input. They have a default value
of `0` or `10` resp. The defined identifier (`min-weight` and `max-weight`) can be used two provide a caption and
a description via the `strings.en` file:

```text
min-weight.title=Minimum Parcel Weight
min-weight.description=The lower bound from which the weight values are sampled randomly.

max-weight.title=Maximum Parcel Weight
max-weight.description=The upper bound from which the weight values are sampled randomly.
```

As a last step, we now need to modify the calculation of the parcel weight, so that the provided parameters are actually
applied.
This is done in `onAdapterStarted()`.

```java jsx {6-9,24} showLineNumbers
@Override
public void onAdapterStarted(IAdapterParameterExtractor extractor,
                             IEventCollector collector,
                             IAdapterRuntimeContext adapterRuntimeContext) throws AdapterException {

  var ex = extractor.getStaticPropertyExtractor();
  
  float minWeight = ex.singleValueParameter("min-weight", Float.class);
  float maxWeight = ex.singleValueParameter("max-weight", Float.class);

  Runnable parcelControl = () -> {
    while (running) {

      // get the current time in seconds
      long timestamp = System.currentTimeMillis();
      long timeInSeconds = (int) timestamp / 1000;

      // make event
      Map<String, Object> event = new HashMap<>();
      event.put("timestamp", timestamp);

      if (timeInSeconds % 5 == 0) {
        event.put("parcelPresent", true);
        event.put("weight", ThreadLocalRandom.current().nextDouble(minWeight, maxWeight));

      } else {
        event.put("parcelPresent", false);
        event.put("weight", 0);
      }

      // forward the event to the adapter pipeline
      collector.collect(event);

      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        throw new RuntimeException(e);
      }
    }
  };
  running = true;
  new Thread(parcelControl).start();
}
```

* line `6-9`: We use an `StaticPropertyExtractor` to retrieve both user inputs
* line `24`: We calculate the parcel weight by passing the configured values vor the minimum and maximum value.

You can now run the `main()` method of the `Init` class to register the adapter at StreamPipes.
The UI dialog to create a new instance of our parcel control station adapter looks now the following:
<img src="/img/06_tutorial_adapter/adapter-with-ui-dialog.png" alt="Adapter with UI dialog"/>

:::caution
Please make sure that you uninstall the parcel adapter in `Install Pipeline Elements` before 
you restart the execution of the `Init` class, if you have already done so.
Otherwise, the changes made in this section will have no effect.
:::

### Read More

Congratulations! You've just created your first StreamPipes adapter 🎉 <br />

There are many more things to explore and data sources can be defined in much more detail.
If this is of interest to you, the [advanced section](#advanced) will satisfy your needs.

If anything within this tutorial did not work for you or you had problems following it,
please feel free to provide some feedback by opening an [issue on GitHub](https://github.com/apache/streampipes/issues/new?assignees=&labels=bug%2Cdocumentation%2Cwebsite&projects=&template=doc_website_issue_report.yml).

<!-- ## Advanced

There is more to come about advanced features of our adapters. Stay tuned!

### Forward Log Messages to the UI to Allow Debugging for the End User

### Determine the Event Schema Based on the Concrete Data Structure

### Implement a Generic Adapter that is Capable of Multiple Input Formats

### Extend the Existing Pool of Parsers by Your Own Parser

### Introduce a Vew Version of an Adapter and Ensure Migration of Existing Adapters -->
