sap dynamic edge processing - sap help portal a custom plugin (java)..... 3 iprotocolplugin...

22
[Type here] SAP Dynamic Edge Processing IoT Edge Services Developer Guide Version 2.0 FP02

Upload: hoangthuy

Post on 30-Apr-2018

229 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

[Type here]

SAP Dynamic Edge Processing IoT Edge Services – Developer Guide Version 2.0 FP02

Page 2: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

2

TABLE OF CONTENTS

PLUGIN DEVELOPMENT ............................................................................................................................ 3 Introduction to Plugins for IoT Edge Services ......................................................................................... 3 Protocol Plugins ............................................................................................................................................ 3 Enterprise Plugins ......................................................................................................................................... 3 Engine Plugins .............................................................................................................................................. 3 Writing a Custom Plugin (Java) ................................................................................................................. 3 IProtocolPlugin Interface ............................................................................................................................... 4 IProtocolAdapter Interface ............................................................................................................................ 5 IEnterprisePlugin Interface ............................................................................................................................ 7 IEnginePlugin Interface ............................................................................................................................... 10 Supporting Whitelisting with a Custom Enterprise Plugin ................................................................... 12 WhitelistClient Interface .............................................................................................................................. 12 Whitelist Constructor Properties Object Configuration ............................................................................... 14 Configuring a Custom Plugin .................................................................................................................. 16 Location of Custom Plugin JAR .................................................................................................................. 16 Registering and Configuring a Custom Protocol Plugin .............................................................................. 16 Registering and Configuring a Custom Enterprise Plugin .......................................................................... 16 Registering and Configuring a Custom Engine Plugin ................................................................................ 16

EXTERNAL CUSTOM RULE - CUSTOM CCL PROJECT DEVELOPMENT ........................................... 17 Input Schema ............................................................................................................................................. 17 Output Schema .......................................................................................................................................... 17 Input Schema Details ................................................................................................................................ 18 Debugging.................................................................................................................................................. 18 Compiling the CCL into a CCX File ......................................................................................................... 18 Start the Custom Project – Linux Only ................................................................................................... 18 Starting the Custom Project with User Authentication – Linux Only .................................................. 18 Start the Custom Project – Windows Only ............................................................................................. 18

APPENDIX .................................................................................................................................................. 20 Custom CCL Sample Template ................................................................................................................ 20

Page 3: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

3

PLUGIN DEVELOPMENT

Introduction to Plugins for IoT Edge Services IoT edge services has been designed to be extensible. Plugins can be written in the form of Java classes conforming to a particular interface. This allows support for a multitude of IoT devices and enterprise destinations. There are three types of plugins that can be written by developers: protocol plugins, enterprise plugins, and engine plugins.

Protocol Plugins

Protocol plugins are the entry point for data ingestion into IoT edge services. They are used to listen for and receive messages from other aggregation systems (for example, SAP Plant Connectivity) or from messages sent from smart devices. Protocol plugins format the received

data into an Object representing the sensor’s value or state, and send it to the IoT edge

services IIoTAdapter. As such, custom protocol plugins can be written to support any type of

desired protocol in order to get data into IoT edge services. Protocol plugins must also support receiving messages from the IoT edge services

IIoTAdapter. However, the plugin does not necessarily need to do anything with the message.

For example, message output is not supported via the REST portion of the provided

HttpProtocolPlugin. Messages are sent from the IIoTAdapter to the plugin if a field message is

generated as an action in response to an event. The plugin can make use of the received data as it sees fit. Security Notes A custom protocol plugin is responsible for implementation of authentication and authorization of the inbound messages. This implementation will be dependent on the protocol support and also the level of desired security in the solution.

Enterprise Plugins

Enterprise plugins are output end points for IoT edge services. If a rule is configured to send to an enterprise plugin, then every time an event or fidelity reading is generated by the rule, it is forwarded to the configured enterprise plugin(s). Enterprise plugins are a flexible way of using IoT edge services because the received information can be used in any way the developer wishes.

Engine Plugins Custom engine plugins are used to add custom processing logic that is outside the scope of the existing IoT edge services streaming rules engine. IoT edge services ships with a single engine plugin (Streaming Lite Plugin) that processes the incoming messages from the protocol plugins and runs the rules configured by an administrator in the Edge Console.

Writing a Custom Plugin (Java)

To implement a plugin, a number of interfaces must be satisfied. The IPlugin interface outlines

methods common to all types of plugins. The IProtocolPlugin interface outlines methods for protocol

plugins, while the IEnterprisePlugin interface outlines methods for enterprise plugins. Both of these

interfaces extend the IPlugin interface, so both protocol plugins and enterprise plugins must implement

these methods. Protocol plugins must implement the IProtocolPlugin interface and all of its methods

and enterprise plugins must implement the IEnterprisePlugin interface and all of its methods.

These interfaces as well as all other com.sap.dep.* classes referenced in this guide are located in the

DEPPluginClient JAR file located in <dep_install_directory>/java_lib. In addition, this JAR

contains the com.sap.dep.logging.LogManager class through which you can get access to a

com.sap.dep.logging.ILogger logger instance for your plugin via the

getLogger(Class component) method. If a logger is retrieved by a plugin, the logger will write to a

file in <dep_install_directory>/log/ named <YourPluginClassName>.log. If any other class

retrieves a logger, the logger will write to <dep_install_directory>/log/IoTAdapter.log.

Page 4: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

4

IPlugin Interface

/**

* Signals to the plug-in that it should clean up resources and

* shutdown

*/

public void stopPlugin();

/**

* Allows the IIoTAdapter to periodically verify that the plug-in has

* the active connections it requires.

* If false is returned, reconnectRequest will be

* called.

*/

boolean isConnected();

/**

* Called by the IIoTAdapter after isConnected returns {@code

* false}.

*/

void reconnectRequest();

/**

* Allows the IIoTAdapter to notify the plug-in of a change to the

* plug-ins log level.

*/

void changeLogLevel(ILogger.Level level);

The stopPlugin method, defined as part of the IPlugin interface, is called by the

IIoTAdapter before IoT edge services is shut down. This method has no parameters. An

implementation of this method should close any closeable objects the plugin is using and do any necessary cleanup.

The isConnected method is defined in order for the plugin to report its connection status in the

form of a boolean to the IIoTAdapter. This method has no parameters. An implementation of

this method should return false if the plugin requires a reconnection attempt. Otherwise, true

should be returned. If false is returned, reconnectRequest is called.

The counterpart to isConnected is reconnectRequest which is called when isConnected

returns false. This method has no parameters. The implementation of this method should

ensure that the plugin is in a valid state for interactions with smart devices and/or the

IIoTAdapter.

Lastly, a changeLogLevel method is defined. An implementation of this method should switch

the logging level to the given ILogger.Level enum argument. Following is an example of

where logger is an ILogger object that handles logging for the plugin and level is the passed

ILogger.Level.

logger.setLevel(level);

IProtocolPlugin Interface

/**

* Starts the plug-in

*

Page 5: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

5

* @param adapter an IProtocolAdapter which can be used to

* input messages destined for IEnginePlugins

* @param pluginConfig a Properties instance that holds the

* mapped configuration for the plug-in

*

* @throws StartupFailureException if the plugin fails to startup

* properly and cannot recover

*/

void startPlugin(IProtocolAdapter adapter, Properties pluginConfig)

throws StartupFailureException;

/**

* Handles a message being output from one of the IEnginePlugin

* plug-ins to this plug-in

*

* @param message The message being given for the plug-in to handle.

* Class type is specific to the IEnginePlugin sending the

* message

*/

void handleEngineMessage(Message message);

The IProtocolPlugin interface defines a startPlugin method with two parameters: an

IProtocolAdapter object used to route messages to the IIoTAdapter, and a Properties

object containing all configuration information stored in the database (see Registering and Configuring a Custom Protocol Plugin). This method is called from the main thread of the

IIoTAdapter so that any blocking calls should be made on a separate thread. If at any point the

plugin startup fails, a StartupFailureException should be thrown by the method.

Implementation of the startPlugin method should prepare the plugin for use, which may

require making use of the Properties object. The method should also continuously listen for

messages over the desired protocol.

The IProtocolPlugin interface also defines a handleEngineMessage method that takes a

com.sap.dep.client.Message object to be handled by the plugin. The actual subclass for

the message differs for each source IEnginePlugin. For instance, the Streaming Lite Engine

Plugin will send instances of com.sap.dep.client.FieldMessage. The .toString()

method of FieldMessage returns a JSON formatted version of the message.

The handleEngineMessage method will only be called if the plugin is configured with IS-

FIELD-PLUGIN set to 1 and Field Messages are created that use the plugin. Refer to the

“Configuring a Protocol Plugin” section in the SAP Dynamic Edge Processing IoT edge services - Configuration Guide.

IProtocolAdapter Interface

/**

* Passes the provided input message to the configured Engine

* plug-in(s). The input message must first be authenticated and

* authorized custom protocol plugin before calling

* sendMessageToEnginPlugins().

*

* @param message the message to forward on.

* The plug-in you are attempting to input a message into likely

* has a format or object it is expecting to receive. Ensure you

Page 6: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

6

* are conforming to these expectations.

*

* @param sourcePlugin the IProtocolPlugin object that is sending to

* its registered destination IEnginePlugin(s)

* This is done using the canonical name of the Protocol plug-in

* class sending the message.

* Example:

* com.example.plugins.MyExampleProtocolPlugin

* @throws UnsupportedSensorException

* @throws UnsupportedMessageTypeException

*/

void sendMessageToEnginePlugins(Message message, IProtocolPlugin

sourcePlugin) throws UnsupportedMessageTypeException,

UnsupportedSensorException;

The IProtocolAdapter interface defines one method, sendMessageToEnginePlugins

method, which sends the given message com.sap.dep.client.Message to all registered

engine plugins (see Plugin Development) using the sourcePlugin argument to identify the

sending plugin. To input sensor readings to the Streaming Lite Engine Plugin, the message

should be an instance of com.sap.dep.client.InboundMessage populated with the reading

data via the InboundMessage.fromJSON(jsonMessage) method. The required JSON format

can be found in the “Sending Data to a Protocol Plugin” section of the SAP Dynamic Edge Processing IoT edge services - Configuration Guide. Security Notes A custom protocol plugin is responsible for implementation of authentication and authorization of the inbound messages. This implementation will be dependent on the protocol support and also the level of desired security in the solution. The custom protocol plugin must perform this

authentication and authorization before calling the sendMessageToEnginePlugins

method. Whitelist support If global deviceId whitelisting is enabled (configured by the setting

whitelist.enableInboundWhitelisting), then the deviceId whitelist filtering will be

automatically applied by the IoT edge services after the sendMessageToEnginePlugins

method is called. No further work is required by the custom protocol plugin to leverage the device id global whitelist filtering.

Following is an example using this method, where protocolAdapter is an

IProtocolAdapter object, message is a com.sap.dep.client.InboundMessage, and

this implements IProtocolPlugin.

protocolAdapter.sendMessageToEnginePlugins(message, this);

In order for Protocol Plugins to be loaded by IoT edge services, the JAR file containing the plugin classes must have the appropriate service provider interface file in the META-INF directory, as outlined below. This only applies to protocol plugins.

File Path & Name File Contents

META-INF/services/com.sap.dep.interfaces.IProtocolPlugin

Canonical Name for the class implementing IProtocolPlugin

Page 7: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

7

Example: com.example.protocolplugin.MyPluginClass

IEnterprisePlugin Interface

/**

* Starts the plug-in

*

* @param config A Properties instance that holds mapping of

* configuration for the plugin

* @param pluginInstanceId The configured Id for this instance of the

* IEnterprisePlugin

* @throws Exception

*/

void startPlugin(Properties config, String pluginInstanceId)

throws Exception;

/**

*

* @param event

* @throws Exception The plugin must throw an exception if it fails to

* handle an event and wants it to be put in a retry queue

*/

void handleEnterpriseEvent(EnterpriseEvent event) throws Exception;

/**

*

* @param event

* @throws Exception The plugin must throw an exception if it fails to

* handle an event and wants it to be put in a retry queue

*/

void handleFidelityEvent(SensorFidelityEvent event) throws Exception;

/**

* @return the pluginInstanceId given to the instance when startPlugin

* is called

*/

String getPluginInstanceId();

/**

* Gets the WhitelistType that the plugin uses or

* supports. See the values of WhitelistType for

* details of what each type indicates.

*

* The default implementation returns WhitelistType.NONE.

* This means no calls will be made to get the plugin's

* whitelist

*

* @return the WhitelistType that the plugin uses

* or supports

*/

default WhitelistType getPluginWhitelistType() {

return WhitelistType.NONE;

}

/**

Page 8: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

8

* Gets the full set of whitelisted devices that the plugin trusts. Any

* existing trusted devices for the plugin will be wiped away.

*

* Only called if getPluginWhitelistType() returns WhitelistType.FULL

*

* The default implementation returns an empty set.

*

* @return a Set of Strings of all of the whitelisted device Ids for

* the plugin

* @throws WhitelistFetchException thrown if any errors are encountered

* while attempting to fetch the whitelist

*/

default Set<String> getAllWhitelistDevices() throws

WhitelistFetchException {

return Collections.<String>emptySet();

}

/**

* Gets the set of newly whitelist devices added since

* lastRetrievalTimestamp

*

* Only called if getPluginWhitelistType() returns WhitelistType.DELTA

*

* The default implementation returns an empty srt.

*

* @return a Set of Strings of the newly whitelisted device Ids for

* the plugin

* @throws WhitelistFetchException thrown if any errors are encountered

* while attempting to fetch the whitelist.

* The last retrieval timestamp will not be updated if this is

* thrown.

*/

default Set<String> getNewWhitelistDevices(Date lastRetrievalTimestamp)

throws WhitelistFetchException {

return Collections.<String>emptySet();

}

/**

* Gets the set of whitelist devices which have been removed since

* lastRetrievalTimestamp

*

* Only called if getPluginWhitelistType()returns WhitelistType.DELTA

*

* The default implementation returns an empty set.

*

* @return a Set of Strings of the de-whitelisted device Ids for the

* plugin

* @throws WhitelistFetchException thrown if any errors are encountered

* while attempting to fetch the whitelist.

* The last retrieval timestamp will not be updated if this is

* thrown.

*/

default Set<String> getRemovedWhitelistDevices(Date

lastRetrievalTimestamp) throws WhitelistFetchException {

return Collections.<String>emptySet();

}

Page 9: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

9

Enterprise plugins can be configured to allow multiple simultaneous instances of the plugin with different configuration properties. An enterprise plugin is meant to route data to a non-IoT edge services endpoints. For example, a REST endpoint in the cloud or a WebSocket endpoint running on a local machine. In addition, enterprise endpoints act as the source for device whitelisting information.

The IEnterprisePlugin interface defines a startPlugin method with a Properties

object as the first parameter that contains all configuration information stored in the database (see Registering and Configuring a Custom Protocol Plugin). The second parameter,

pluginInstanceId, is a String that is the configured Id for the instance being started. This Id

can also be used to differentiate instances for logging purposes. If at any point the plugin startup

fails, a StartupFailureException should be thrown by the implemented method.

Implementation of this method should prepare the plugin for use, which may require making use

of the Properties object.

Next, the interface defines a handleEnterpriseEvent method which takes a

com.sap.dep.client.EnterpriseEvent object as an argument. This method is called

every time an event is generated by a rule that has this plugin associated to it. Implementation of

this method should make use of the EnterpriseEvent object and perform any follow-up

actions necessary to handle the particular event. An exception can be thrown by this method in

order for the EnterpriseEvent to be put into a re-attempt queue. The get methods listed

below allow access to the event’s data. /*

* List of EnterpriseEvent object get methods

*/

String getDeviceId();

String getDeviceTag();

String getSensorProfileId();

String getSensorProfileName();

String getSensorId();

String getSensorTag();

String getSourceRuleType();

String getSourceRuleId();

String getSourceRuleName();

String getSensorInformation();

Date getDateCreated();

The final outbound method of the interface is the handleFidelityEvent method that takes a

com.sap.dep.client.SensorFidelityEvent object as an argument. This method is called

every time a sensor fidelity reading is sent to the enterprise plugin, as determined by the sensor’s fidelity rule settings. An exception can be thrown by this method in order for the

SensorFidelityEvent to be put into a re-attempt queue. The get methods listed below allow

access to the event’s data. /*

* List of SensorFidelityEvent object get methods

*/

String getDeviceId();

String getDeviceTag();

String getSensorProfileId();

String getSensorProfileName();

String getSensorId();

String getSensorTag();

String getSensorReadingValue();

Page 10: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

10

String getSourceRuleId();

String getContext();

Date getDateCreated();

The getPluginInstanceId method is used for various purposes, including to check the

whitelist for a specific IEnterprisePlugin instance before sending that instance an event. It

should return the pluginInstanceId value given to the startPlugin method.

For the whitelisting portion of the interface, IEnterprisePlugin defines four methods. The first

method is getPluginWhitelistType, and it is used to determine the whitelist type supported

by the plugin. The IEnterprisePlugin.WhitelistType enumeration defines three values:

NONE, FULL, and DELTA.

The NONE value indicates that the plugin does not support retrieving a whitelist. If this is the case,

none of the three remaining methods will be called.

The FULL value indicates the plugin supports retrieving the full list of currently whitelisted devices.

If this is the case, the getAllWhitelistDevices method will be called when polling for

whitelist data.

Finally, the DELTA value indicates that the plugin supports timestamp-based delta retrieval of both

newly added devices and newly removed devices. If this is the case, first the

getNewWhitelistDevices method will be called with a Date timestamp of the last time an

update was requested and then getRemovedWhitelistDevices will be called with the same

timestamp.

All three of the whitelist retrieval methods (getAllWhitelistDevices,

getNewWhitelistDevices, and getRemovedWhitelistDevices) return Set<String>

containing the corresponding device Ids. IEnginePlugin Interface Custom engine plugins can be used to either replace the Streaming Lite engine, the default IoT edge services rules processing engine, or augment the Streaming Lite engine functionality. If configured to replace the Streaming Lite engine, the messages are sent to the custom engine plugin instead of the Streaming Lite engine. If configured to augment the Streaming Lite engine, the messages are sent to the custom engine plugin, which can perform the custom logic and send additional messages to the Streaming Lite engine. The custom engine plugin can also optionally trigger events that are processed by enterprise plugins. /**

* Starts the plug-in

*

* @param adapter

* an {@link IEngineAdapter} which can be used to output messages

* to {@link IProtocolPlugin}s or {@link IEnterprisePlugin}s.

* @param pluginConfig

* A {@link Properties} instance that holds the mapped

* configuration for the plug-in

*

* @throws StartupFailureException

* if the plugin fails to startup properly and cannot recover

*/

void startPlugin(IEngineAdapter adapter, Properties pluginConfig) throws

StartupFailureException;

Page 11: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

11

/**

* Handles a message being inputted from one of the IProtocolPlugin plug-ins

* to this plug-in

*

* @param message

* The message being given for the plug-in to handle as it sees

* fit

* @throws UnsupportedSensorException

* @throws UnsupportedMessageTypeException

*/

void handleInputMessage(Object message) throws

UnsupportedMessageTypeException, UnsupportedSensorException;

The IEnginePlugin interface defines a startPlugin method with two parameters: an

IEngineAdapter object used to route messages to protocol, enterprise, or other engine plugins, and a

Properties object containing all configuration information stored in the database (see Registering and

Configuring a Custom Engine Plugin). This method is called from the main thread of the IIoTAdapter

so that any blocking calls should be made on a separate thread. If at any point the plugin startup fails, a

StartupFailureException should be thrown by the method.

The IEnginePlugin interface also defines a handleInputMessage method which takes a generic

Java Object as an argument. This allows it to receive any type of message from the protocol plugins

however in the current version only com.sap.dep.client.InboundMessage objects will be passed

in. This method is called every time a protocol plugin generates a message destined for this engine plugin. See Registering and Configuring a Custom Engine Plugin to configure routing protocol plugin

messages to the engine plugin. Implementation of this method should make use of the message object

and perform any custom logic to process the message.

The handleInputMessage can use the IEngineAdapter object passed in the startPlugin method

to:

Send a message to specific protocol plugin or to all protocol plugins.

Send an enterprise event to an enterprise plugin.

Send a sensor fidelity event to an enterprise event.

Send a message to specific engine plugin or to all engine plugins In order for Engine Plugins to be loaded by IoT edge services, the JAR file containing the plugin classes must have the appropriate service provider interface file in the META-INF directory, as outlined below.

File Path & Name File Contents

META-INF/services/com.sap.dep.interfaces.IEnginePlugin

Canonical Name for the class implementing IEnginePlugin Example: com.example.engineplugin.MyPluginClass

A sample implementation of an engine plugin is provided in the samples/plugin/engine/CpkEnginePlugin directory. Refer to the documentation in the README.md in the CpkEnginePlugin directory for full description of the plugin.

Page 12: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

12

Supporting Whitelisting with a Custom Enterprise Plugin If it is desirable to support whitelisting when creating a custom enterprise plugin, the class

com.sap.dep.whitelist.WhitelistClient provides an implementation that is utilized by

RESTPlugin and WebSocketPlugin for their whitelist support. This class supports making HTTP GET calls which return JSON in one of the following formats:

1. Arrays [ "Device1", "Device2", "Device3" ]

2. JSON member with an array value

{ "devices": [ "Device1", "Device2", "Device3" ] }

3. OData JSON

{

"d": {

"results": [

{ "deviceId": "Device1" },

{ "deviceId": "Device2" },

{ "deviceId": "Device3" }

]

}

}

If using formats 2 or 3, the Properties object passed to the constructor should have a value for the key

WHITELIST_JSON_MEMBER_NAME that aligns with the member name in 2 or the object member name in

3. In the provided samples, the values would be "devices" for format 2 and "deviceId" for format 3.

Any extra members in formats 2 or 3 will be ignored.

The public interface for WhitelistClient is outlined below. It is followed by the Whitelist Constructor

Properties Object Configuration table that outlines the configuration values for the Properties object

given to the constructor.

WhitelistClient Interface /**

* Instantiates an instance of WhitelistClient using the specified

* configuration and logging via the passed logger.

*

* @param config A Properties object containing the configuration for

* the instance

* @param logger the ILogger which will be used for logging

* @throws AssertionError Only thrown if run on a platform which

* doesn't support UTF-8 encoding

* @throws IllegalArgumentException thrown if the config object

* contains invalid configuration data

* @throws StartupFailureException thrown if any exception occurs when

* starting the HTTP client

*/

public WhitelistClient(final Properties config, ILogger logger)

throws AssertionError, IllegalArgumentException,

StartupFailureException

/**

* Gets the WhitelistType this instance is configured for

* @return the WhitelistType the instance is configured for

*/

Page 13: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

13

public WhitelistType getWhitelistType()

/**

* Closes the client. Calling {@code close} after the first call

* doesn't do anything.

* Once this has been called, no further calls to

* WhitelistClient.getAllWhitelistDevices(),

* WhitelistClient.getNewWhitelistDevices(Date), or

* WhitelistClient.getRemovedWhitelistDevices(Date) should be made.

* @throws Exception thrown if any exception occurs while closing the

* client.

*/

public void close() throws Exception

/**

* Implementation for

* IEnterprisePlugin.getAllWhitelistDevices() which will make a GET

* request to the configured endpoint to retrieve the full list of

* whitelist devices

*

* @return A set containing all of the parsed device ids

* @throws WhitelistFetchException thrown if the configured

* WhitelistType isn't WhitelistType.FULL or any exception occurs

* while making or processing the request.

*/

public Set<String> getAllWhitelistDevices()

throws WhitelistFetchException

/**

* Implementation for

* IEnterprisePlugin.getNewWhitelistDevices(Date) which will make a GET

* request to the configured endpoint to retrieve the list of whitelist

* devices added since lastRetrievalTimestamp

*

* @return A set containing all of the parsed device ids

* @throws WhitelistFetchException thrown if the configured

* WhitelistType isn't WhitelistType.DELTA or any exception occurs

* while making or processing the request.

*/

public Set<String> getNewWhitelistDevices(Date lastRetrievalTimestamp)

throws WhitelistFetchException

/**

* Implementation for

* IEnterprisePlugin.getRemovedWhitelistDevices(Date) which will make a

* GET request to the configured endpoint to retrieve the list of

* whitelist devices removed since lastRetrievalTimestamp

*

* @return A set containing all of the parsed device ids

* @throws WhitelistFetchException thrown if the configured

* WhitelistType isn't WhitelistType.DELTA or any exception occurs

* while making or processing the request.

*/

public Set<String> getRemovedWhitelistDevices(

Date lastRetrievalTimestamp)

throws WhitelistFetchException

Page 14: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

14

Whitelist Constructor Properties Object Configuration

Setting Name <CONFIG_NAME>

Description Sample Value <CONFIG_VALUE>

WHITELIST_TYPE Whether the configured endpoint returns a full list or a delta list. None is an option, but it doesn’t make sense to do all the configuration

FULL DELTA NONE

WHITELIST_URI_ALL_DEVICES (required only for WHITELIST _TYPE = FULL)

Complete URI for obtaining the full list of whitelisted devices – only called when WHITELIST_TYPE = FULL

https://hana.ondemand.com/whitelist

WHITELIST_URI_ADDED_DEVICES (required only for WHITELIST _TYPE = DELTA)

Complete URI for obtaining the list of newly whitelisted devices – only called when WHITELIST_TYPE = DELTA. The value should contain the placeholder

${lastUpdatedTimestamp} which

will be replaced with the last run timestamp using the format configured by WHITELIST_LAST_UPDATED_TIMESTAMP_FORMAT.

https://hana.ondemand.com/whitelist/added?since=${lastUpdatedTimestamp}

WHITELIST_URI_REMOVED_DEVICES (required only for WHITELIST _TYPE = DELTA)

Complete URI for obtaining the list of devices removed from the whitelist – only called when WHITELIST_TYPE = DELTA. The value should contain the placeholder

${lastUpdatedTimestamp} which

will be replaced with the last run timestamp using the format configured by WHITELIST_LAST_UPDATED_TIMESTAMP_FORMAT.

https://hana.ondemand.com/whitelist/removed?since=${lastUpdatedTimestamp}

WHITELIST_PROXY_HOST (optional)

The host portion of the proxy to use when retrieving the whitelist. A proxy port must also be provided.

hana.ondemand.com

WHITELIST_PROXY_PORT (optional)

The port portion of the proxy to use when retrieving the whitelist. A proxy host must also be provided.

80

WHITELIST_AUTH_TYPE (optional)

The type of authorization to use for requests.

- Basic – WHITELIST _USERNAME, WHITELIST _ AUTHENTICATION, and WHITELIST _BASIC_AUTH_REALM are required.

- oAuth – WHITELIST_OAUTH_TOKEN is required.

basic

Page 15: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

15

If this setting isn’t configured, no authentication mechanism is configured.

WHITELIST_BASIC_AUTH_REALM (optional)

The realm to use for BASIC authentication challenges.

example_realm

WHITELIST_USERNAME (optional)

The user name to use for BASIC authentication challenges.

sap_IoT

WHITELIST_AUTHENTICATION (optional)

The password to use for BASIC authentication challenges.

password

WHITELIST_OAUTH_TOKEN (optional)

The bearer token to set as the value for the authentication header. Automatically prefixed with “Bearer “.

a73b15c7d42f272e6212c7010b438317ae198b4a

WHITELIST_KEY_STORE_IN_SECURE_CONFIG_DIRECTORY (optional)

- True - the plugin prepends the path of the secure configuration directory to the configured KEY_STORE_PATH.

- False - the plugin uses the raw value of the KEY_STORE_PATH setting for the path.

true

WHITELIST_KEY_STORE_PATH (optional)

The path for the Java keystore. Value can be the file name or the path, depending on the value of WHITELIST_KEY_STORE_IN_SECURE_CONFIG_DIRECTORY. Defaults to SQL Anywhere 17’s cacerts on x86 Windows and Linux and the running JRE’s cacerts on ARM.

RESTEnterprisePlug

in.jks or

<dep_iot_edge>/store/CustomKeyStore.

jks

WHITELIST_KEY_STORE_AUTHENTICATION (optional)

The password for the configured keystore. May optionally be obfuscated using Jetty.

OBF:1umm1y851z0f1sw61sox1vno1z0f1vne1sot1svs1z0f1y7t1uvk

WHITELIST_TRUST_STORE_PATH (optional)

The path for the Java keystore to use as the truststore. Value must be the full path to the file. If not provided, the configured keystore (WHITELIST_KEY_STORE_PATH) is also used as the truststore.

<dep_iot_edge>/store/CustomTrustStor

e.jks

WHITELIST_TRUST_STORE_AUTHENTICATION (optional)

The password for the configured truststore. May optionally be obfuscated using Jetty.

OBF:1umm1y851z0f1sw61sox1vno1z0f1vne1sot1svs1z0f1y7t1uvk

WHITELIST_CERT_AUTHENTICATION (optional)

The password for the configured WHITELIST_CERT_ALIAS or best matching certificate and key in the keystore. This is the password set

using the -keypass flag when

imported using keytool. If not set,

WHITELIST_KEY_STORE_ AUTHENTICATION is used. As a result, the keypass must either be the same or no keypass must be set. May optionally be obfuscated using Jetty.

OBF:1umm1y851z0f1sw61sox1vno1z0f1vne1sot1svs1z0f1y7t1uvk

Page 16: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

16

WHITELIST_CERT_ALIAS (optional)

Key for selecting which certificate to use from the keystore. If not provided, an attempt is made to find the best matching certificate in the keystore. Keystores use lowercase aliases; therefore, this value must also be lowercase.

whitelistalias

WHITELIST_JSON_MEMBER_NAME (required only if the return result is format 2 or 3 of the examples above)

The name of the member on the returned JSON data to pull device Ids from. See the examples above

deviceId

WHITELIST_LAST_UPDATED_TIMESTAMP_FORMAT (required only if TYPE = DELTA)

This is the format for the value which will replace the ${lastUpdatedTimestamp}

placeholder in Delta URIs. The format string supports the same functionality as the date format string for Enterprise Events and Fidelity Readings sent via RESTPlugin and WebSocketPlugin. Refer to the SAP Dynamic Edge Processing IoT edge services - Configuration Guide for the supported. Defaults to ISO8601 format if left unconfigured.

Y-M-d

Configuring a Custom Plugin Once the java file(s) has/have been written for the custom plugin and a JAR file has been created, it must be placed in the designated installation subdirectory. Next, the custom plugin must be configured via the database. Location of Custom Plugin JAR

The custom JAR file needs to be placed in the <dep_install_directory>/java_lib

directory. This is the directory where IoT edge services will look for plugins to start.

Registering and Configuring a Custom Protocol Plugin The protocol plugin must be configured for integration with IoT edge services. Refer to the SAP Dynamic Edge Processing IoT edge services - Configuration Guide.

Registering and Configuring a Custom Enterprise Plugin

The enterprise plugin must be configured for integration with IoT edge services. Refer to the SAP Dynamic Edge Processing IoT edge services - Configuration Guide.

Registering and Configuring a Custom Engine Plugin

The engine plugin must be configured for integration with IoT edge services. Refer to the SAP Dynamic Edge Processing IoT edge services - Configuration Guide.

Page 17: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

17

EXTERNAL CUSTOM RULE - CUSTOM CCL PROJECT DEVELOPMENT

NOTE: This document assumes you are familiar with CCL development. If this is not the case, please refer to the Smart Data Streaming developer information found at http://help.sap.com/hana_options_sds/ for further information. Streaming Lite does not support the full functionality offered by Smart Data Streaming. NOTE: The CCL supported by a Custom CCL project running in IoT edge services is limited to the CCL support that is standard across Streaming Lite and SAP Event Stream Processor (ESP). In most cases, the lowest common denominator is the CCL supported by Streaming Lite, but this is not guaranteed. The only tested and supported adapter is the “ODBC Database” or in CCL “type db_out”. All other ESP adapters are not supported.

The external custom rule provides the ability define custom processing logic to be used as a rule. The custom CCL project must satisfy these two requirements to integrate into IoT edge services.

1. The custom CCL project has an Input Stream named isCustomSL with a schema matching the

Input Schema outlined below.

2. The custom CCL project has an Output Stream named osCustomSL with a schema matching the

Output Schema outlined below.

The RuleId being output needs to match either the Rule ID or Rule Name of the

External Custom Rule configured to use the custom CCL project. It is recommended to

use the Rule Name as it isn’t system generated and can be consistent across

deployments.

Between these streams, the custom CCL can consume the data from isCustomSL and define the logic

required for the custom rule. Once the conditions for the rule have been met, an output to osCustomSL

must be made with all of the input stream data, except Context, and the Rule ID or Rule Name of the

triggered event. The output is consumed by IoT edge services, and IoT edge services performs scoping and enforces the Max Event Frequency for the rule. If scoping is met and the event hasn’t occurred too recently, the actions configured for the rule will fire, the event will be sent to the configured enterprise endpoints, and the event will be saved to the edge database if the rule has been configured to do so. A basic sample template for a custom CCL project can be found in the appendix. Input Schema SCHEMA (

DeviceId string,

DeviceTag string,

SensorId string,

SensorTag string,

SensorProfileId string,

SensorReadingValue string,

Context string,

DateCreated msdate

)

Output Schema SCHEMA (

DeviceId string,

DeviceTag string,

SensorId string,

SensorTag string,

SensorProfileId string,

SensorReadingValue string,

DateCreated msdate,

RuleId string

)

Page 18: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES - DEVELOPER

18

Input Schema Details

The only required and guaranteed non-null fields are DeviceId, SensorProfileId, SensorReadingValue,

and DateCreated. SensorReadingValue can be cast to an integer or a float using the to_integer() or

to_float() CCL functions.

Debugging

To debug using Streaming Lite, make use of the print(string) function and direct the output to a file or

watch the terminal hosting the streamingproject. If the value of the print statement is null or any of the

values being concatenated are null, an empty line will be output. An easy way to get prevent this is to use

firstnonnull(thePossibleNullValue, 'null').

Compiling the CCL into a CCX File

Note: On Windows replace references to $STREAMING_HOME with %STREAMING_HOME%. On Linux

$STREAMING_HOME is the correct format.

Use the streamingcompiler executable in $STREAMING_HOME/bin to compile the CCL file. Replace the

placeholders in the following example with your path and files. $STREAMING_HOME/bin/streamingcompiler –i <path-to-ccl>/<ccl-file-name>.ccl –o

<output-path>/<compiled-file-name>.ccx

The -i flag is used to specify the input file and the -o flag is used to specify the output file.

Start the Custom Project – Linux Only

Start the project using the streamingproject executable in $STREAMING_HOME/bin to start the compiled

ccx as a process. Replace the placeholder paths and file with those for your CCX file. NOTE: Port 9230 is used by the primary IoT Edge Services streaming project and should not be used for custom projects.

$STREAMING_HOME/bin/streamingproject --ccx <path-to-ccx>/<compiled-file-name>.ccx -

-command-port 9231 --host localhost

The --ccx flag is used to specify the CCX file to run, the --command-port flag is used to specify the port that

the custom project listens to, and the --host flag specifies the host address the custom project listens on.

To redirect the terminal output to a file, add the following to the end of the previous command. Customize the path and file name, as necessary. >> ~/customProjectOutput.log 2>&1

Starting the Custom Project with User Authentication – Linux Only

Starting the project using the streamingproject executable in with the -V flag will enable user authentication.

Custom projects are authenticated using the same user credentials as the main IoT edge services streaming lite project. See the SAP Dynamic Edge Processing: Edge Business Services - Configuration Guide for instructions to configure the Streaming Lite authentication mechanism Start the Custom Project – Windows Only A script is provided to configure the custom CCL project as a Windows service. This script will both install and uninstall a dedicated Windows service to run the custom CCL project.

Page 19: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

19

The script is located here: <dep_iot_edge>\bin\CustomCCLService.bat The script will require a port and path to the compiled ccx file. NOTE: Port 9230 is used by the primary IoT Edge Services streaming project and should not be used for custom projects. To install a custom CCX file as a Windows service, run the following and provide the port and ccx file when prompted:

<dep_iot_edge>\bin\CustomCCLService.bat

To uninstall a custom CCX file as a Windows service (replace <service_name> with “CustomCCLProject_” + ccx file name):

<dep_iot_edge>\bin\CustomCCLService.bat --delete_service <service_name>

Page 20: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

20

APPENDIX

Custom CCL Sample Template /* Copyright (c) 2017 SAP SE or an affiliate company. All rights reserved. */

/** This is a sample template that may be used to create custom CCL project that

integrates with SAP Dynamic Edge Processing – IoT edge services */

/* You MUST have an input stream with this name and this schema */

CREATE INPUT STREAM isCustomSL SCHEMA (

DeviceId string,

DeviceTag string,

SensorId string,

SensorTag string,

SensorProfileId string,

SensorReadingValue string,

Context string,

DateCreated msdate

);

/* You may call this flex operator or any window operation and its output stream

whatever you wish */

CREATE FLEX ThisCanBeRenamed

IN isCustomSL

OUT OUTPUT STREAM ThisCanBeRenamed

SCHEMA (

DeviceId string,

DeviceTag string,

SensorId string,

SensorTag string,

SensorProfileId string,

SensorReadingValue string,

DateCreated msdate,

RuleId string

)

BEGIN

ON isCustomSL {

OUTPUT [

DeviceId=isCustomSL.DeviceId;

DeviceTag=isCustomSL.DeviceTag;

SensorId=isCustomSL.SensorId;

SensorTag=isCustomSL.SensorTag;

SensorProfileId=isCustomSL.SensorProfileId;

SensorReadingValue=isCustomSL.SensorReadingValue;

DateCreated=isCustomSL.DateCreated;

RuleId='This will be the Id or Name of the Rule your custom logic

triggers';

];

};

END;

/* You MUST have an output stream with this name and this schema */

CREATE OUTPUT STREAM osCustomSL

Page 21: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

IOT EDGE SERVICES – DEVELOPER GUIDE Public

21

AS

SELECT

ThisCanBeRenamed.DeviceId DeviceId,

ThisCanBeRenamed.DeviceTag DeviceTag,

ThisCanBeRenamed.SensorId SensorId,

ThisCanBeRenamed.SensorTag SensorTag,

ThisCanBeRenamed.SensorProfileId SensorProfileId,

ThisCanBeRenamed.SensorReadingValue SensorReadingValue,

ThisCanBeRenamed.DateCreated DateCreated,

ThisCanBeRenamed.RuleId RuleId

FROM ThisCanBeRenamed;

Page 22: SAP Dynamic Edge Processing - SAP Help Portal a Custom Plugin (Java)..... 3 IProtocolPlugin Interface ..... 4 IProtocolAdapter Interface ..... 5 ... of the SAP Dynamic Edge Processing

www.sap.com

© 2017 SAP SE or an SAP affiliate company. All rights reserved. No part of this publication may be reproduced or transmitted in any form or for any purpose without the express permission of SAP SE or an SAP affiliate company. SAP and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP SE (or an SAP affiliate company) in Germany and other countries. Please see http://www.sap.com/corporate-en/legal/copyright/index.epx#trademark for additional trademark information and notices. Some software products marketed by SAP SE and its distributors contain proprietary software components of other software vendors. National product specifications may vary. These materials are provided by SAP SE or an SAP affiliate company for informational purposes only, without representation or warranty of any kind, and SAP SE or its affiliated companies shall not be liable for errors or omissions with respect to the materials. The only warranties for SAP SE or SAP affiliate company products and services are those that are set forth in the express warranty statements accompanying such products and services, if any. Nothing herein should be construed as constituting an additional warranty. In particular, SAP SE or its affiliated companies have no obligation to pursue any course of business outlined in this document or any related presentation, or to develop or release any functionality mentioned therein. This document, or any related presentation, and SAP SE’s or its affiliated companies’ strategy and possible future developments, products, and/or platform directions and functionality are all subject to change and may be changed by SAP SE or its affiliated companies at any time for any reason without notice. The information in this document is not a commitment, promise, or legal obligation to deliver any material, code, or functionality. All forward-looking statements are subject to various risks and uncertainties that could cause actual results to differ materially from expectations. Readers are cautioned not to place undue reliance on these forward-looking statements, which speak only as of their dates, and they should not be relied upon in making purchasing decisions.