SAP Home Learn Build Integrate Model Operate Extend with AI ConnectTutorial navigator Knowledge Graph API Devtoberfest Developer Advocates App Space

Manage my Account SAP Devs YouTube ↗ Learnings ↗ Community ↗ Provide Feedback ↗
Logout
โคข Open full site

Creating Custom Adapter Modules

Create a Transporter Module and a Formatter module for your Custom Adapter using Java PAHO Library.

Overview

🎓 intermediate 15 min. SAP HANA Streaming AnalyticsIntermediateInternet Of ThingsSAP HANAExpress Edition

You will learn

  • โœ”How to create Transporter and Formatter modules
Robert Waywell R Robert Waywell January 15, 2025
Created by March 13, 2018
Contributors

Prerequisites

Steps

Next Steps

Time to Complete

20 Min


Step 1 Create a Transporter Module
โ€”

A transporter module is the interface that interacts with external data sources by obtaining data from a data source or outputting data to a data destination.

SAP HANA Streaming Analytics supports two types of transporters: row-based and stream-based.

Row-based transporters obtain and output data in row format, such as a database transporter. These transporters work with AdapterRow instances, which are containers for one or more records or rows as they flow from one module (transporter, formatter, or Streaming Analytics connector) to the next. You can add multiple records as objects within a List of a single AdapterRow object. The AdapterRow has a timestamp and block flags that control how its records are communicated to and from Streaming Analytics.

Stream-based transporters deal with streaming data, such as a socket transporter. These transporters work with ByteStream or ByteBuffer instances, which represent a continuous stream of data.

In this tutorial, we will be creating a row based transporter module as it lends itself well to MQTT.

Before we begin, you can check out the $STREAMING_HOME/adapters/framework/examples/src directory for source code of sample transporters.

The full source code for the Transporter Module is provided in the Appendix Section

First, we will set up the Custom Adapter Project.

  1. Start by opening your IDE and creating a new java project called mqtt-input

  2. Create a package com.sap

  3. Create a Java class called MqttTransporter.java

  4. Create a Java class called MqttCB.java. The code for this file is provided in the appendix section of this tutorial.

  5. We will now add a number of .jar dependencies to our class path:

    • Java PAHO library

    • The other dependencies will be from the Adapter Toolkit and can be found in %STREAMING_HOME%\adapters\framework\libj

      • Commons-configuration-<version>.jar
      • Streaming-client.jar
      • Streaming-system.jar
      • Streaming-adapter-framework.jar

Then, have MqttTransporter extend the Transporter class.

We will start by defining a number of instance variables, which will be assigned values in the init() method (more on that later).

  • MqttClient client;
  • String topic;
  • MqttCB cb;

Having done this, we will need to implement a number of abstract methods in Transporter. We will cover the methods in the same order they will be called by the adapter framework.

The first abstract method we will implement is void init(). The purpose of this method is to prepare the module for the actions it is responsible for performing. We will use this method to initialize various global variables as well as grab the user defined parameters for the adapter.

  1. First, we want to get the Topic parameter value. This value is set by the streaming developer when configuring the adapter in Studio.
We can get the value of Topic by calling:

```java
utility.getParameters().getString("MQTTInputTransporterParamet
ers.Topic");
```
> The `MQTTInputTransporterParameters` prefix is defined in our adapter configuration file.
  1. Next, create an MqttClient. The constructor takes serverURI - the address of the server to connect to, specified as a URI and clientId - a client identifier that is unique on the server being connected to.
We will use the `MosquittoServerAddress` defined by the streaming developer and a unique string

```java
client = new
MqttClient(utility.getParameters().getString("MQTTInputTranspo
rterParameters.MosquittoServerAddress"), "MQTT_ESP");
```
  1. Connect the MqttClient with client.connect();

  2. Subscribe the MqttClient to the topic with client.subscribe(topic);

  3. Instantiate an MqttCB object and assign it to our MqttClient. MqttCB is a custom MqttCallback class written for this adapter. The code for it is provided in the appendix section of this tutorial.

```java
cb = new MqttCB();
client.setCallback(cb);
```

The second abstract method we have to implement is void start(). The purpose of this method is to perform any necessary tasks when the adapter is started. For our purposes, it is not necessary to include any instructions in this method so we will leave it empty.

The third and most important method to implement is void execute(). When the adapter framework calls this method, it is expected to run continuously until the adapter is requested to stop or until the adapter completes its work.

  1. As such, we will wrap our functionality in a loop that iterates until the adapter has been issued a stop request. Following this loop โ€“ and ending the method โ€“ is an instruction to change the adapter RunState to done.
```java
while(!utility.isStopRequested())
{
//steps b-d
}
utility.setAdapterState(RunState.RS_DONE);
```
  1. While the adapter has not been requested to stop, we will continuously check for new MQTT messages. The takeNewMsg() method will return null if there are no new messages, or take the message out of the message queue and return it. When a new message is received, we will process it within the if statement.
```java
String msg;
if ((msg = cb.takeNewMsg()) != null){
//steps c-d
}
```
  1. Once we have received a message, we need to create an AdapterRow and send it to our Formatter module.
```java
AdapterRow row = utility.createRow(cb.getRcvdMsg());
utility.sendRow(row);
```

The fourth overridden method is void stop(). Its purpose is to perform any necessary tasks when the adapter is stopped. We will use this method to disconnect our MqttClient by issuing

Java
client.disconnect();

The fifth and last method is void destroy(). Its purpose is to perform any cleanup tasks for your input or output transporter. For our purposes, it is not necessary to include any instructions in this method so we will leave it empty.

Step 2 Create a Formatter Module
+
Step 3 Package Modules into a .jar file
+
Step 4 Appendix
+

Resources

Discussion

Share feedback on this tutorial or join the conversation in SAP Community.

Submit detailed feedback Discuss in Community
Steps
Step 1 of 4
1. Create a Transporter Module 2. Create a Formatter Module 3. Package Modules into a .jar file 4. Appendix

Learn more →