Prev Next

Develop Smart Behaviour


Summary

This tutorial will show how to create and package a simple BRAIN-IoT Smart Behaviour. It’s This tutorial is Maven and command-line based.

Here we will create a Security Light System which is composed of three smart behaviours: a light, a sensor and a controller. The sensor and light are ‘virtual’ and implemented as web pages.

In this tutorial we’ll first run, and then re-create and re-run, Security Light System.

A Smart Behaviour is a functional unit deployable in an OSGi container, and it’s built using the BRAIN-IoT smart-behaviour-maven-plugin plugin, different smart behaviours communicate through the BRAIN-IoT Events deliveried in the distributed BRAIN-IoT EventBus.

Build and Run

Download the SmartBehaviourEventBus Git repository, and change directory into brain-iot-EventBus/eventing-example.

~ $ git clone https://github.com/eclipse-researchlabs/brain-iot-EventBus.git
~ $ cd brain-iot-EventBus/eventing-example

Building the example

Build the Application with the following command:

~/brain-iot-EventBus/eventing-example $ mvn verify

Running the example

~/brain-iot-EventBus/eventing-example $ java -jar single-framework-example/target/single-framework-example.jar

To test that the application is running, visit:

Sensor UI: http://localhost:8080/sensor-ui/index.html

Light UI: http://localhost:8080/light-ui/index.html

Click the Trigger the sensor button in sensor page, you will see the virtual lightbulb is switched on, then slowly dims in response to a sensor event.

Recreate a Smart Behaviour

We’ll now recreate the Security Light example locally using the enRoute Archetypes this tutorial to walk through the creation of a REST Microservice comprised of the following structural elements:

  • An API module (light.api)
  • A Implementation module, also including the REST Service Implementation of the light blub (light.impl)

with each module having a POM that describes its dependencies.

Project Setup

First change into a new directory, since we are recreating the project, here we go to the HOME directory:

~/brain-iot-EventBus/eventing-example $ cd ~

Use the bare-project Archetype to create a microservice project:

~ $ mvn archetype:generate \
     -DarchetypeGroupId=org.osgi.enroute.archetype \
     -DarchetypeArtifactId=project-bare \
     -DarchetypeVersion=7.0.0

Filling the project details with appropriate values:

Define value for property 'groupId': com.paremus.brain.iot.example
Define value for property 'artifactId': eventing-example
Define value for property 'version' 1.0-SNAPSHOT: : 0.0.1-SNAPSHOT
Define value for property 'package' com.paremus.brain.iot.example: : 
Confirm properties configuration:
groupId: com.paremus.brain.iot.example
artifactId: eventing-example
version: 0.0.1-SNAPSHOT
package: com.paremus.brain.iot.example
 Y: :

If you’re using an IDE then this would be a good time to import the generated maven project and then import the submodules when they’re created.

This is a maven parent project, which will contain multiple modules for the Security Light example.

Open POM and change the default <bnd.version> property to avoid build failure:

  <bnd.version>5.1.2</bnd.version>

Before implementing the module, append the following BRAIN-IoT runtime dependencies in the <dependencyManagement> section in parent POM, as they are the dependencies of EventBus.

Here assume that you have run through the Prerequisites tutorial and the credentials setup for BRAIN-IoT private Nexus repositories has been done.

  <dependency>
      <groupId>com.paremus.brain.iot</groupId>
      <artifactId>eventing.api</artifactId>
      <version>0.0.1-SNAPSHOT</version>
  </dependency>
  <dependency>
       <groupId>org.apache.aries.jax.rs</groupId>
       <artifactId>org.apache.aries.jax.rs.jackson</artifactId>
       <version>1.0.2</version>
       <scope>runtime</scope>
  </dependency>
  <dependency>
       <groupId>com.paremus.brain.iot</groupId>
       <artifactId>eventing.impl</artifactId>
       <version>0.0.1-SNAPSHOT</version>
       <scope>runtime</scope>
  </dependency>
       <dependency>
       <groupId>com.paremus.brain.iot</groupId>
       <artifactId>message.integrity.insecure.impl</artifactId>
       <version>0.0.1-SNAPSHOT</version>
       <scope>runtime</scope>
  </dependency>
   <dependency>
       <groupId>org.apache.aries.spec</groupId>
       <artifactId>org.apache.aries.javax.jax.rs-api</artifactId>
       <version>1.0.1</version>
       <scope>compile</scope>
   </dependency>

Append the following repositories in <repositories> section for downloading the BRAIN-IoT runtime dependencies:

      <repository>
            <id>brain-iot-releases</id>
            <name>BRAIN-IoT Releases</name>
            <url>https://nexus.repository-pert.ismb.it/repository/maven-releases/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>brain-iot-snapshots</id>
            <name>BRAIN-IoT Snapshots</name>
            <url>https://nexus.repository-pert.ismb.it/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
       </repository>

and append the following plugin repositories in <pluginRepositories> section for downloading the BRAIN-IoT smart-behaviour-maven-plugin:

        <pluginRepository>
            <id>brain-iot-releases</id>
            <name>BRAIN-IoT Releases</name>
            <url>https://nexus.repository-pert.ismb.it/repository/maven-releases/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>brain-iot-snapshots</id>
            <name>BRAIN-IoT Snapshots</name>
            <url>https://nexus.repository-pert.ismb.it/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>

Create Light API Module

Change directory into the newly created eventing-example project directory, then create an API module light.api using the api Archetype as shown:

~ $ cd eventing-example
~/eventing-example $ mvn archetype:generate \
     -DarchetypeGroupId=org.osgi.enroute.archetype \
     -DarchetypeArtifactId=api \
     -DarchetypeVersion=7.0.0

with the following values:

Define value for property 'groupId': com.paremus.brain.iot.example
Define value for property 'artifactId': light.api
Define value for property 'version' 1.0-SNAPSHOT: : 0.0.1-SNAPSHOT
Define value for property 'package' com.paremus.brain.iot.example.light.api: : 
Confirm properties configuration:
groupId: com.paremus.brain.iot.example
artifactId: light.api
version: 0.0.1-SNAPSHOT
package: com.paremus.brain.iot.example.light.api
 Y: :

This API module defines a sort of BRAIN-IoT Events via the use of Data Transfer Objects (DTOs) transfered between light smart behaviour and others. Each event has to extend the common super-type BrainIoTEvent shown in the following BrainIoTEvent.java which contains information that must exist for all events.

/* Copyright 2019 Paremus, Ltd - All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
 */

package eu.brain.iot.eventing.api;

import java.time.Instant;

import org.osgi.annotation.versioning.ConsumerType;
import org.osgi.dto.DTO;

/**
 * An common super-type for all Brain IoT events containing 
 * information that must exist for all events.
 */
@ConsumerType
public abstract class BrainIoTEvent extends DTO {

	/**
	 * The identifier of the node creating the event   
	 */
    public String sourceNode;
 
    /**   
     * The time at which this event was created  
     */
    public Instant timestamp;
 
    /**   
     * The security token that can be used to authenticate/validate the event   
     */
    public byte[] securityToken;
}

Dependencies

Open pom.xml of light.api and add following dependency of the BRAIN-IoT Events and EventBus:

<dependency>
    <groupId>com.paremus.brain.iot</groupId>
    <artifactId>eventing.api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

which provides the BrainIoTEvent, EventBus, SmartBehaviour and UntypedSmartBehaviour interfaces and others.

Note that a Smart Behaviour must consume typed events and cannot be used to consume unknown event types. If unknown event types are to be consumed then an UntypedSmartBehaviour must be used.

Visibility

light.api is an API package which is imported by other implementation modules, hence it must must be exported. This is indicated by the automatically generated file ~/eventing-example/light.api/src/main/java/com/paremus/brain/iot/example/light/api/package-info.java:

@org.osgi.annotation.bundle.Export
@org.osgi.annotation.versioning.Version("1.0.0")
package com.paremus.brain.iot.example.light.api;

Defining the BRAIN-IoT Events

The customized events should be defined as following:

public class XXX extends BrainIoTEvent {
    // TODO: add other fields if need
}

Remove original auto-generated java classes in src package:

~/eventing-example/light.api/src/main/java/com/paremus/brain/iot/example/light/api/ProviderInterface.java

~/eventing-example/light.api/src/main/java/com/paremus/brain/iot/example/light/api/ConsumerInterface.java

and create the following four files:

~/eventing-example/light.api/src/main/java/com/paremus/brain/iot/example/light/api/AbstractLightDTO.java

~/eventing-example/light.api/src/main/java/com/paremus/brain/iot/example/light/api/LightCommand.java

~/eventing-example/light.api/src/main/java/com/paremus/brain/iot/example/light/api/LightQuery.java

~/eventing-example/light.api/src/main/java/com/paremus/brain/iot/example/light/api/LightQueryResponse.java

/* Copyright 2019 Paremus, Ltd - All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
 */
package com.paremus.brain.iot.example.light.api;

import eu.brain.iot.eventing.api.BrainIoTEvent;

public abstract class AbstractLightDTO extends BrainIoTEvent {
	
	public boolean status;
	
	public int brightness;

}
/* Copyright 2019 Paremus, Ltd - All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
 */
package com.paremus.brain.iot.example.light.api;

public class LightCommand extends AbstractLightDTO {

}
/* Copyright 2019 Paremus, Ltd - All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
 */
package com.paremus.brain.iot.example.light.api;

import eu.brain.iot.eventing.api.BrainIoTEvent;

public class LightQuery extends BrainIoTEvent {

}
/* Copyright 2019 Paremus, Ltd - All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
 */
package com.paremus.brain.iot.example.light.api;

public class LightQueryResponse extends AbstractLightDTO {
	
	public String requestor;

}

Alternatly, you can copy all source java files from the light.api sub-project of downloaded SmartBehaviourEventBus Git repository to the src package.

Create Light Smart Behaviour Implementation Module

A Smart Behavior is implemented as Declarative Service using the @SmartBehaviourDefinition annotation provided by above eventing.api dependency, and its relevant Capabilities (specified by the types of the consumed BRAIN-IoT events) are configured through the properties of the annotation.

Now, in the eventing-example project directory, create the light.impl module using the rest-component Archetype:

~/eventing-example $ mvn archetype:generate \
     -DarchetypeGroupId=org.osgi.enroute.archetype \
     -DarchetypeArtifactId=rest-component \
     -DarchetypeVersion=7.0.0

with the following values:

Define value for property 'groupId': com.paremus.brain.iot.example
Define value for property 'artifactId': light.impl
Define value for property 'version' 1.0-SNAPSHOT: : 0.0.1-SNAPSHOT
Define value for property 'package' com.paremus.brain.iot.example.light.impl: : 
Confirm properties configuration:
groupId: com.paremus.brain.iot.example
artifactId: light.impl
version: 0.0.1-SNAPSHOT
package: com.paremus.brain.iot.example.light.impl
 Y: :

Dependencies

Append the following dependencies in the <dependencies> section of POM:

    <dependencies>
        <dependency>
            <groupId>com.paremus.brain.iot</groupId>
            <artifactId>eventing.api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot.example</groupId>
            <artifactId>light.api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.osgi.enroute</groupId>
            <artifactId>impl-index</artifactId>
            <type>pom</type>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.aries.jax.rs</groupId>
            <artifactId>org.apache.aries.jax.rs.jackson</artifactId>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot</groupId>
            <artifactId>eventing.impl</artifactId>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot</groupId>
            <artifactId>message.integrity.insecure.impl</artifactId>
        </dependency>
     </dependencies>

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <artifactId>eventing-example</artifactId>
    <groupId>com.paremus.brain.iot.example</groupId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>

    <groupId>com.paremus.brain.iot.example</groupId>
    <artifactId>light.impl</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <description>The light.impl DS component - built using OSGi enRoute R7</description>

    <dependencies>
        <dependency>
            <groupId>org.osgi.enroute</groupId>
            <artifactId>osgi-api</artifactId>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.osgi.enroute</groupId>
            <artifactId>enterprise-api</artifactId>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.osgi.enroute</groupId>
            <artifactId>test-bundles</artifactId>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot</groupId>
            <artifactId>eventing.api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot.example</groupId>
            <artifactId>light.api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.osgi.enroute</groupId>
            <artifactId>impl-index</artifactId>
            <type>pom</type>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.aries.jax.rs</groupId>
            <artifactId>org.apache.aries.jax.rs.jackson</artifactId>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot</groupId>
            <artifactId>eventing.impl</artifactId>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot</groupId>
            <artifactId>message.integrity.insecure.impl</artifactId>
        </dependency>

     </dependencies>


    <build>
        <plugins>
           <!-- Expected to inherit configuration from a parent enRoute 
                pom. This includes -contract definitions and maven-jar-plugin setup -->
            <plugin>
                <groupId>biz.aQute.bnd</groupId>
                <artifactId>bnd-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
            </plugin>
            <!-- Validate that the smart behaviour can resolve -->
            <plugin>
                <groupId>biz.aQute.bnd</groupId>
                <artifactId>bnd-resolver-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>resolve</goal>
                        </goals>
                        <phase>package</phase>
                        <configuration>
                            <bndruns>
                                <bndrun>light.bndrun</bndrun>
                            </bndruns>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
             <plugin>
                <groupId>com.paremus.brain.iot.maven</groupId>
                <artifactId>smart-behaviour-maven-plugin</artifactId>
                <version>0.0.1-SNAPSHOT</version>
                <executions>
					<execution>
						<goals>
							<goal>smart-behaviour</goal>
						</goals>
						<configuration>
						    <bndrun>light.bndrun</bndrun>
						</configuration>
					</execution>
				</executions>
            </plugin>
        </plugins>
    </build>

</project>

Implement the light smart behaviour

Remove original auto-generated java classes in src package:

~/eventing-example/light.impl/src/main/java/com/paremus/brain/iot/example/light/impl/RestComponentImpl.java

And create the following two files:

~/eventing-example/light.impl/src/main/java/com/paremus/brain/iot/example/light/impl/LightDTO.java

~/eventing-example/light.impl/src/main/java/com/paremus/brain/iot/example/light/impl/RestComponentImpl.java

/* Copyright 2019 Paremus, Ltd - All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
 */
package com.paremus.brain.iot.example.light.impl;

public class LightDTO {
	
	public boolean status;
	
	public int brightness;

}
/* Copyright 2019 Paremus, Ltd - All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
 */
package com.paremus.brain.iot.example.light.impl;

import com.paremus.brain.iot.example.light.api.LightCommand;
import com.paremus.brain.iot.example.light.api.LightQuery;
import com.paremus.brain.iot.example.light.api.LightQueryResponse;
import eu.brain.iot.eventing.annotation.SmartBehaviourDefinition;
import eu.brain.iot.eventing.api.BrainIoTEvent;
import eu.brain.iot.eventing.api.EventBus;
import eu.brain.iot.eventing.api.SmartBehaviour;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.http.whiteboard.propertytypes.HttpWhiteboardResource;
import org.osgi.service.jaxrs.whiteboard.propertytypes.JSONRequired;
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsResource;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Providers;
import javax.ws.rs.sse.Sse;
import javax.ws.rs.sse.SseBroadcaster;
import javax.ws.rs.sse.SseEventSink;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;

/**
 * This component represents two things:
 *
 *  1. A Smart Light Bulb controlled using events
 *  2. A set of REST resources used by a web ui to display the light bulb
 *
 */
@Component(service= {SmartBehaviour.class, RestComponentImpl.class})
@JaxrsResource
@HttpWhiteboardResource(pattern="/light-ui/*", prefix="/static")
@JSONRequired
@SmartBehaviourDefinition(consumed = {LightCommand.class, LightQuery.class}, filter = "(brightness=*)",
        author = "Paremus", name = "Example Smart Light Bulb",
        description = "Implements a Smart Light Bulb and UI to display it.")
public class RestComponentImpl implements SmartBehaviour<BrainIoTEvent>{

	/*
	 * A Smart Behaviour representing a lightbulb
	 */

	@Reference
	private EventBus eventBus;

	private boolean status;

	private int brightness;

	@Override
	public void notify(BrainIoTEvent event) {
		if(event instanceof LightQuery) {
			LightQueryResponse response = new LightQueryResponse();
			response.requestor = event.sourceNode;
			synchronized (this) {
				response.brightness = brightness;
				response.status = status;
			}
			eventBus.deliver(response);
		} else if (event instanceof LightCommand) {
			LightCommand command = (LightCommand) event;
			LightDTO dto = new LightDTO();
			synchronized (this) {
				status = command.status;
				brightness = command.brightness;

				dto.status = status;
				dto.brightness = brightness;
			}
			brightnessChanged(dto);
		} else {
			System.out.println("Argh! Received an unknown event type " + event.getClass());
		}

	}

	/*
	 *
	 * JAX-RS logic for the lightbulb UI
	 *
	 */

	private SseBroadcaster broadcaster;
	private Sse sse;
	private Providers providers;

	private void brightnessChanged(LightDTO brightness) {
		SseBroadcaster broadcasterToUse;
		Sse sseToUse;
		Providers providersToUse;
    	synchronized (this) {
			sseToUse = sse;
			broadcasterToUse = broadcaster;
			providersToUse = providers;
		}

    	if(broadcasterToUse != null) {
    		try(ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
				MessageBodyWriter<LightDTO> writer = providersToUse.getMessageBodyWriter(LightDTO.class, null, null, APPLICATION_JSON_TYPE);
    			writer.writeTo(brightness, LightDTO.class, null, null, APPLICATION_JSON_TYPE, null, baos);
    			broadcasterToUse.broadcast(sseToUse.newEvent(baos.toString()));
    		} catch (IOException e) {
				broadcaster.broadcast(sseToUse.newEvent("error", e.getMessage()));
			}

    	}
	}

	@Path("light")
	@GET
	@Produces(APPLICATION_JSON)
	public LightDTO light() {
		LightDTO dto = new LightDTO();

		synchronized (this) {
			dto.status = status;
			dto.brightness = brightness;
		}

		return dto;
	}

	@Path("light/stream")
	@GET
	@Produces("text/event-stream")
	public void getLiveUpdates(@Context SseEventSink eventSink, @Context Sse sse, @Context Providers providers) {

		SseBroadcaster toUse;
		synchronized (this) {
			if (this.sse == null) {
				this.sse = sse;
				broadcaster = sse.newBroadcaster();
				this.providers = providers;
			}
			toUse = broadcaster;
		}

		toUse.register(eventSink);

		brightnessChanged(light());
	}
}

You can copy the RestComponentImpl.java, LightDTO.java source files from the light.impl sub-project of downloaded SmartBehaviourEventBus Git repository to this new module.

A part of the implementation of the light Smart Behavior in RestComponentImpl.java is:

/**
 * This component represents two things:
 *  1. A Smart Light Bulb controlled using events
 *  2. A set of REST resources used by a web ui to display the light bulb
 */
import com.paremus.brain.iot.example.light.api.LightCommand;
import com.paremus.brain.iot.example.light.api.LightQuery;
import com.paremus.brain.iot.example.light.api.LightQueryResponse;
import eu.brain.iot.eventing.annotation.SmartBehaviourDefinition;
import eu.brain.iot.eventing.api.BrainIoTEvent;
import eu.brain.iot.eventing.api.EventBus;
import eu.brain.iot.eventing.api.SmartBehaviour;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

@Component(service= {SmartBehaviour.class, RestComponentImpl.class})
@JaxrsResource
@HttpWhiteboardResource(pattern="/light-ui/*", prefix="/static")
@JSONRequired
@SmartBehaviourDefinition(consumed = {LightCommand.class, LightQuery.class}, filter = "(brightness=*)",
        author = "Paremus", name = "Example Smart Light Bulb",
        description = "Implements a Smart Light Bulb and UI to display it.")
public class RestComponentImpl implements SmartBehaviour<BrainIoTEvent>{

	@Reference
	private EventBus eventBus;
   //**
	@Override
	public void notify(BrainIoTEvent event) {
		if(event instanceof LightQuery) {
			LightQueryResponse response = new LightQueryResponse();
			response.requestor = event.sourceNode;
			//**  The internal process for consuming the event
			eventBus.deliver(response);

		} else if (event instanceof LightCommand) {
			LightCommand command = (LightCommand) event;	
         //**  The internal process for consuming the event 
		}
         //**  other code
	}
}

The important annotations include:

  • The @Component is used to register this component as an OSGi service.
  • The @JaxrsResource annotation is used to mark this as a JAX-RS whiteboard resource
  • The @JSONRequired is used to declare its JSON support requirement
  • The @SmartBehaviourDefinition is used to define the Provide-Capability of the smart behaviour using the following properties:
    1. ‘consumed’: Specifies the typed events to be consumed by the smart behaviour. Here they are the LightCommand and the LightCommand events.
    2. ‘filter’: A filter used to select the properties of the events that should be passed to this smart behaviour (only LightCommand here) from EventBus
    3. ‘author’: The author of this smart behaviour
    4. ‘name’: The name of this smart behaviour
    5. ‘description’: The description of this smart behaviour

Integration with BRAIN-IoT EventBus

A smart behaviour has to integrate with BRAIN-IoT EventBus which is a referenced service in implementation as shown in above code:

@Reference
private EventBus eventBus;

In addition, two important methods must be used:

  • The notify(T extends BrainIoTEvent) method provided by the SmartBehaviour API, for asynchronously receiving an event
  • The deliver(T extends BrainIoTEvent) method provided by the EventBus, for asynchronously sending an event

Light Bulb REST Service Implementation

The web page of the light bulb will be implemented also in this light.impl module.

Create the directory ~/eventing-example/light.impl/src/main/resources and copy the downloaded light.impl/src/main/resources/static folder which is the implementation of the light bulb page to the same place of current light.impl module (i.e. ~/eventing-example/light.impl/src/main/resources/static).

~/eventing-example $ ls light.impl/src/main/resources/static
css  img  index.html  js  lib

Visibility

Implementations should NOT be shared; hence no package-info.java file.

Build

It’s now time to build the light API and implementation modules and package it as a smart behaviour using the smart-behaviour-maven-plugin provided by BRAIN-IoT project. This plugin provides the smart-behaviour goal bound to the package phase for gathering all dependencies specified in the project pom file, as well as the project output jar by default and building a smart behaviour jar. The resulting smart behaviour jar file has the name in the form of ${project.artifactId}-${project.version}-brain-iot-smart-behaviour.jar. And the smart-behaviour goal is not executed by default, therefore at least one explicit execution needs to be configured.

This plugin is optionally configurable using a bndrun file in its plugin’s configuration in the POM. The bndrun file is located in the base directory of the project. And this can be configured to specify an alternate path which can be absolute or relative to the base directory of the project. The bndrun file is used as a source of initial requirements or a list of bundles to be deployed on a BRAIN-IoT Fabric Fibre when Behaviour Management Service (BMS) searches in a marketplace. So, in general, this plugin can be used together with the bnd-resolver-maven-plugin for resolving the bndrun file in advance.

Build Setup

Add the following <build> section in light.impl POM:

   <build>
        <plugins>
            <!-- Expected to inherit configuration from a parent enRoute 
                pom. This includes -contract definitions and maven-jar-plugin setup -->
            <plugin>
                <groupId>biz.aQute.bnd</groupId>
                <artifactId>bnd-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
            </plugin>
            <!-- Validate that the smart behaviour can resolve -->
            <plugin>
                <groupId>biz.aQute.bnd</groupId>
                <artifactId>bnd-resolver-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>resolve</goal>
                        </goals>
                        <phase>package</phase>
                        <configuration>
                            <bndruns>
                                <bndrun>light.bndrun</bndrun>
                            </bndruns>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
             <plugin>
                <groupId>com.paremus.brain.iot.maven</groupId>
                <artifactId>smart-behaviour-maven-plugin</artifactId>
                <version>0.0.1-SNAPSHOT</version>
                <executions>
					<execution>
						<goals>
							<goal>smart-behaviour</goal>
						</goals>
						<configuration>
						    <bndrun>light.bndrun</bndrun>
						</configuration>
					</execution>
				</executions>
            </plugin>
        </plugins>
    </build>

Create a bndrun file:

~/eventing-example $ touch light.impl/light.bndrun

Then add the following content in light.bndrun:

-runrequires: \
   bnd.identity;id='com.paremus.brain.iot.example.light.impl',\
	bnd.identity;id='org.apache.aries.jax.rs.jackson'

-runfw: org.eclipse.osgi
-runee: JavaSE-1.8

-resolve.effective: active

As shown above, the bndrun contains a runrequires statement that specifies the required bundles to be deployed at runtime. here we put the light.impl module and its JAX-RS whiteboard dependency.

Note that your runee may be different if you chose to use a higher version of Java

However, no runbundles is currently listed(i.e. the actual bundles needed at runtime to run the light smart behaviour). But the bndrun will be automatically resolved using the bnd-resolver-maven-plugin to generate the runtime dependencies. Now we use the package goal to check that the code compiles and can be successfully packaged into a bundle.

Build the eventing-example project:

~/eventing-example $ mvn package
[INFO] Scanning for projects...                                                                    
[INFO] ------------------------------------------------------------------------
[INFO] Building light.impl 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] --- maven-jar-plugin:3.0.2:jar (default-jar) @ light.impl ---
[INFO] Building jar: /home/rui/Documents/SmartBehaviourEventBus/eventing-example/light.impl/target/light.impl-0.0.1-SNAPSHOT.jar
[INFO] 
[INFO] --- bnd-resolver-maven-plugin:5.1.2:resolve (default) @ light.impl ---
[INFO] 
[INFO] --- smart-behaviour-maven-plugin:0.0.1-SNAPSHOT:smart-behaviour (default) @ light.impl ---
[INFO] Gathering dependencies
[INFO] Copying light.api-0.0.1-SNAPSHOT.jar to ~/eventing-example/light.impl/target/smart-behaviour/light.api-0.0.1-SNAPSHOT.jar
[INFO] Copying light.impl-0.0.1-SNAPSHOT.jar to ~/eventing-example/light.impl/target/smart-behaviour/light.impl-0.0.1-SNAPSHOT.jar
[INFO] Copying .....
[INFO] Processing ~/eventing-example/light.impl/light.bndrun for dependencies
[INFO] Building jar: ~/eventing-example/light.impl/target/light.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

If we had tests or other post-packaging checks then we could have used the verify goal instead.

If the package fails then check your code and try again. Once you can package it cleanly then continue to the next stage.

You can see each module has been packaged as an OSGi bundle in their target directories. Check the output of the light.impl module:

~/eventing-example $ cd light.impl
~/eventing-example/light.impl $ ls target
classes                                                  maven-status
generated-sources                                        smart-behaviour
generated-test-sources                                   surefire-reports
light.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour.jar  test-classes
light.impl-0.0.1-SNAPSHOT.jar                            tmp
maven-archiver

In the light.impl/target folder, there is the light.impl-0.0.1-SNAPSHOT.jar module output bundle, but also the light.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour.jar smart behaviour jar, and a smart-behaviour folder with all the gathered dependencies for the light smart behaviour and a an OSGi repository index file is generated from the dependencies. The index.xml can be used for resolving the smart behaviour at runtime. You can also use the mvn install to deploy the jars in maven local repository for creating a marketplace later.

Check the content of the output bundle, run:

~/eventing-example/light.impl $ bnd print target/light.impl-0.0.1-SNAPSHOT.jar
[MANIFEST light.impl-0.0.1-SNAPSHOT]
......                                    
Bundle-Description                       "The light.impl DS component - built using OSGi enRoute R7"
Bundle-ManifestVersion                   2                                       
Bundle-Name                              light.impl                              
Bundle-SymbolicName                      com.paremus.brain.iot.example.light.impl
Bundle-Version                           0.0.1.202009251653                      
Created-By                               1.8.0_221 (Oracle Corporation)
Import-Package: com.paremus.brain.iot.example.light.api;version="[1.0,2)"....
Require-Capability:....
Service-Component: OSGI-INF/com.paremus.brain.iot.example.light.impl.RestComponentImpl.xml
Provide-Capability: osgi.service;objectClass:List<String>="com.paremus.brain.iot.example.light.impl.RestComponentImpl,
    eu.brain.iot.eventing.api.SmartBehaviour",
    eu.brain.iot.behaviour;consumed:List<String>="com.paremus.brain.iot.example.light.api.LightCommand,
    com.paremus.brain.iot.example.light.api.LightQuery";author=Paremus;name="Example Smart Light Bulb";
    description="Implements a Smart Light Bulb and UI to display it."
Service-Component: OSGI-INF/com.paremus.brain.iot.example.light.impl.RestComponentImpl.xml

As shown, the event types to be consumed by the bundle are listed in the consumed property.

If you look again at the light.bndrun file you will now see a number of bundles required at runtime are now listed by runbundles instruction.

-runrequires: \
	bnd.identity;id='com.paremus.brain.iot.example.light.impl',\
	bnd.identity;id='org.apache.aries.jax.rs.jackson'
	
-runfw: org.eclipse.osgi
-runee: JavaSE-1.8

-runproperties: org.osgi.service.http.port=8082

-resolve.effective: active
-runbundles: \
	ch.qos.logback.classic;version='[1.2.3,1.2.4)',\
	ch.qos.logback.core;version='[1.2.3,1.2.4)',\
	com.paremus.brain.iot.eventing.api;version='[0.0.1,0.0.2)',\
	com.paremus.brain.iot.eventing.impl;version='[0.0.1,0.0.2)',\
	com.paremus.brain.iot.example.light.api;version='[0.0.1,0.0.2)',\
	com.paremus.brain.iot.example.light.impl;version='[0.0.1,0.0.2)',\
	org.apache.aries.jax.rs.whiteboard;version='[1.0.1,1.0.2)',\
	org.apache.felix.configadmin;version='[1.9.8,1.9.9)',\
	org.apache.felix.http.jetty;version='[4.0.6,4.0.7)',\
	org.apache.felix.http.servlet-api;version='[1.1.2,1.1.3)',\
	org.apache.felix.scr;version='[2.1.10,2.1.11)',\
	org.apache.servicemix.specs.annotation-api-1.3;version='[1.3.0,1.3.1)',\
	org.osgi.service.jaxrs;version='[1.0.0,1.0.1)',\
	org.osgi.util.function;version='[1.1.0,1.1.1)',\
	org.osgi.util.promise;version='[1.1.0,1.1.1)',\
	slf4j.api;version='[1.7.25,1.7.26)',\
	com.fasterxml.jackson.core.jackson-annotations;version='[2.9.0,2.9.1)',\
	com.fasterxml.jackson.core.jackson-core;version='[2.9.6,2.9.7)',\
	com.fasterxml.jackson.core.jackson-databind;version='[2.9.6,2.9.7)',\
	com.fasterxml.jackson.jaxrs.jackson-jaxrs-base;version='[2.9.6,2.9.7)',\
	com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider;version='[2.9.6,2.9.7)',\
	com.fasterxml.jackson.module.jackson-module-jaxb-annotations;version='[2.9.6,2.9.7)',\
	org.apache.aries.jax.rs.jackson;version='[1.0.2,1.0.3)',\
	org.osgi.util.pushstream;version='[1.0.0,1.0.1)',\
	org.apache.aries.javax.jax.rs-api;version='[1.0.1,1.0.2)',\
	com.paremus.brain.iot.message.integrity.api;version='[0.0.1,0.0.2)',\
	com.paremus.brain.iot.message.integrity.insecure.impl;version='[0.0.1,0.0.2)'

Smart Behaviour

The light.impl module is also packaged as a smart behaviour jar using the smart-behaviour-maven-plugin.

Check the content of the light smart behaviour jar:

~/eventing-example/light.impl $ bnd print target/light.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour.jar

[MANIFEST light.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour]
BRAIN-IoT-Deploy-Requirement     osgi.identity;filter:="(osgi.identity=com.paremus.brain.iot.example.light.impl)",
                                 osgi.identity;filter:="(osgi.identity=org.apache.aries.jax.rs.jackson)"
BRAIN-IoT-Smart-Behaviour-SymbolicName   com.paremus.brain.iot.example.light.impl
BRAIN-IoT-Smart-Behaviour-Version        0.0.1.SNAPSHOT                          
Build-Jdk                                1.8.0_221                                                                    
Created-By                               Apache Maven 3.3.9                      
Manifest-Version                         1.0

Each smart behaviour will have some OSGi headers. The value of BRAIN-IoT-Deploy-Requirement header is drived from the -runrequires instruction in the bndrun file (e.g. light.bndrun here), and the bundles specified in this header will be resolved and installed together with their dependencies at runtime. If the smart-behaviour-maven-plugin is not configured with any bndrun file, then the default bundle must be deployed is the project output jar.

Create the Sensor and Controller Smart Behaviours

Let’s create sub-modules sensor.api, sensor.impl and behaviour.impl in eventing-example parent project. The controller Smart Behaviour is named as behaviour.impl.

Create Sensor API Module

Change directory into the parent eventing-example project directory, then create an API module sensor.api using the api Archetype as shown:

~ $ cd eventing-example
~/eventing-example $ mvn archetype:generate \
     -DarchetypeGroupId=org.osgi.enroute.archetype \
     -DarchetypeArtifactId=api \
     -DarchetypeVersion=7.0.0

with the following values:

Define value for property 'groupId': com.paremus.brain.iot.example
Define value for property 'artifactId': sensor.api
Define value for property 'version' 1.0-SNAPSHOT: : 0.0.1-SNAPSHOT
Define value for property 'package' com.paremus.brain.iot.example.sensor.api: : 
Confirm properties configuration:
groupId: com.paremus.brain.iot.example
artifactId: sensor.api
version: 0.0.1-SNAPSHOT
package: com.paremus.brain.iot.example.sensor.api
 Y: :

This API module defines the Events via the use of Data Transfer Objects (DTOs) transfered between sensor smart behaviour and others.

Dependencies

Similar with the Light API module, open pom.xml of sensor.api and add following eventing.api dependency:

<dependency>
    <groupId>com.paremus.brain.iot</groupId>
    <artifactId>eventing.api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

Visibility

The sensor.api package is also exported by the automatically generated file ~/eventing-example/sensor.api/src/main/java/com/paremus/brain/iot/example/sensor/api/package-info.java.

Sensor Events

Remove original auto-generated java classes in src package:

~/eventing-example/sensor.api/src/main/java/com/paremus/brain/iot/example/sensor/api/ProviderInterface.java

~/eventing-example/sensor.api/src/main/java/com/paremus/brain/iot/example/sensor/api/ConsumerInterface.java

and create the following file:

~/eventing-example/sensor.api/src/main/java/com/paremus/brain/iot/example/sensor/api/AbstractLightDTO.java

/* Copyright 2019 Paremus, Ltd - All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
 */
package com.paremus.brain.iot.example.sensor.api;

import eu.brain.iot.eventing.api.BrainIoTEvent;

public class SensorReadingDTO extends BrainIoTEvent {

}

Create Sensor Implementation Module

Go to eventing-example project directory, create the sensor.impl module using the rest-component Archetype:

~/eventing-example $ mvn archetype:generate \
     -DarchetypeGroupId=org.osgi.enroute.archetype \
     -DarchetypeArtifactId=rest-component \
     -DarchetypeVersion=7.0.0

with the following values:

Define value for property 'groupId': com.paremus.brain.iot.example
Define value for property 'artifactId': sensor.impl
Define value for property 'version' 1.0-SNAPSHOT: : 0.0.1-SNAPSHOT
Define value for property 'package' com.paremus.brain.iot.example.sensor.impl: : 
Confirm properties configuration:
groupId: com.paremus.brain.iot.example
artifactId: sensor.impl
version: 0.0.1-SNAPSHOT
package: com.paremus.brain.iot.example.sensor.impl
 Y: :

Dependencies

Replace the auto-genearted POM in this module with the following, the content is similar with the light.impl POM with the build configuartion:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <artifactId>eventing-example</artifactId>
    <groupId>com.paremus.brain.iot.example</groupId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>

    <groupId>com.paremus.brain.iot.example</groupId>
    <artifactId>sensor.impl</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <description>The sensor.impl DS component - built using OSGi enRoute R7</description>

    <dependencies>
        <dependency>
            <groupId>org.osgi.enroute</groupId>
            <artifactId>osgi-api</artifactId>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.osgi.enroute</groupId>
            <artifactId>enterprise-api</artifactId>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.osgi.enroute</groupId>
            <artifactId>test-bundles</artifactId>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot.example</groupId>
            <artifactId>sensor.api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot</groupId>
            <artifactId>eventing.api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.osgi.enroute</groupId>
            <artifactId>impl-index</artifactId>
            <type>pom</type>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.aries.jax.rs</groupId>
            <artifactId>org.apache.aries.jax.rs.jackson</artifactId>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot</groupId>
            <artifactId>eventing.impl</artifactId>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot</groupId>
            <artifactId>message.integrity.insecure.impl</artifactId>
        </dependency>
     </dependencies>

    <build>
        <plugins>
            <!-- Expected to inherit configuration from a parent enRoute 
                pom. This includes -contract definitions and maven-jar-plugin setup -->
            <plugin>
                <groupId>biz.aQute.bnd</groupId>
                <artifactId>bnd-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
            </plugin>
            <!-- Validate that the smart behaviour can resolve -->
            <plugin>
                <groupId>biz.aQute.bnd</groupId>
                <artifactId>bnd-resolver-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>resolve</goal>
                        </goals>
                        <phase>package</phase>
                        <configuration>
                            <bndruns>
                                <bndrun>sensor.bndrun</bndrun>
                            </bndruns>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>com.paremus.brain.iot.maven</groupId>
                <artifactId>smart-behaviour-maven-plugin</artifactId>
                <version>0.0.1-SNAPSHOT</version>
                <executions>
					<execution>
						<goals>
							<goal>smart-behaviour</goal>
						</goals>
						<configuration>
                            <bndrun>sensor.bndrun</bndrun>
                        </configuration>
					</execution>
				</executions>
            </plugin>
        </plugins>
    </build>
</project>

Implement the sensor smart behaviour

Overwrite original auto-generated java class in src package for the sensor smart behaviour implementation:

~/eventing-example/sensor.impl/src/main/java/com/paremus/brain/iot/example/sensor/impl/RestComponentImpl.java

/* Copyright 2019 Paremus, Ltd - All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
 */
package com.paremus.brain.iot.example.sensor.impl;

import com.paremus.brain.iot.example.sensor.api.SensorReadingDTO;
import eu.brain.iot.eventing.annotation.SmartBehaviourDefinition;
import eu.brain.iot.eventing.api.EventBus;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.http.whiteboard.propertytypes.HttpWhiteboardResource;
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsResource;

import javax.ws.rs.POST;
import javax.ws.rs.Path;

/**
 * This component triggers sensor readings based on web clicks
 */
@Component(service=RestComponentImpl.class)
@JaxrsResource
@HttpWhiteboardResource(pattern="/sensor-ui/*", prefix="/static")
// SmartBehaviourDefinition is just so example sensor is added to repository
@SmartBehaviourDefinition(consumed = {}, // this component does not consume events
        author = "Paremus", name = "Example Smart Security Sensor",
        description = "Implements a Smart Security Sensor and UI to display it.")
public class RestComponentImpl {

    @Reference
    private EventBus eventBus;

    @Path("sensor")
    @POST
    public void trigger() {
        eventBus.deliver(new SensorReadingDTO());
    }

}

The sensor smart behaviour is designed to just send the SensorReadingDTO trigger event, so its consumed property of the @SmartBehaviourDefinition annotation is empty.

In addition, place the following sensor.bndrun file in ~/eventing-example/sensor.impl/ for configuration of smart-behaviour-maven-plugin.

-runrequires: \
	bnd.identity;id='com.paremus.brain.iot.example.sensor.impl',\
	bnd.identity;id='org.apache.aries.jax.rs.jackson'
	
-runfw: org.eclipse.osgi
-runee: JavaSE-1.8

-runproperties: org.osgi.service.http.port=8082

-resolve.effective: active
-runbundles: \
	ch.qos.logback.classic;version='[1.2.3,1.2.4)',\
	ch.qos.logback.core;version='[1.2.3,1.2.4)',\
	com.paremus.brain.iot.eventing.api;version='[0.0.1,0.0.2)',\
	com.paremus.brain.iot.eventing.impl;version='[0.0.1,0.0.2)',\
	org.apache.aries.jax.rs.whiteboard;version='[1.0.1,1.0.2)',\
	org.apache.felix.configadmin;version='[1.9.8,1.9.9)',\
	org.apache.felix.http.jetty;version='[4.0.6,4.0.7)',\
	org.apache.felix.http.servlet-api;version='[1.1.2,1.1.3)',\
	org.apache.felix.scr;version='[2.1.10,2.1.11)',\
	org.apache.servicemix.specs.annotation-api-1.3;version='[1.3.0,1.3.1)',\
	org.osgi.service.jaxrs;version='[1.0.0,1.0.1)',\
	org.osgi.util.function;version='[1.1.0,1.1.1)',\
	org.osgi.util.promise;version='[1.1.0,1.1.1)',\
	slf4j.api;version='[1.7.25,1.7.26)',\
	com.fasterxml.jackson.core.jackson-annotations;version='[2.9.0,2.9.1)',\
	com.fasterxml.jackson.core.jackson-core;version='[2.9.6,2.9.7)',\
	com.fasterxml.jackson.core.jackson-databind;version='[2.9.6,2.9.7)',\
	com.fasterxml.jackson.jaxrs.jackson-jaxrs-base;version='[2.9.6,2.9.7)',\
	com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider;version='[2.9.6,2.9.7)',\
	com.fasterxml.jackson.module.jackson-module-jaxb-annotations;version='[2.9.6,2.9.7)',\
	org.apache.aries.jax.rs.jackson;version='[1.0.2,1.0.3)',\
	org.osgi.util.pushstream;version='[1.0.0,1.0.1)',\
	org.apache.aries.javax.jax.rs-api;version='[1.0.1,1.0.2)',\
	com.paremus.brain.iot.example.sensor.api;version='[0.0.1,0.0.2)',\
	com.paremus.brain.iot.example.sensor.impl;version='[0.0.1,0.0.2)',\
	com.paremus.brain.iot.message.integrity.api;version='[0.0.1,0.0.2)',\
	com.paremus.brain.iot.message.integrity.insecure.impl;version='[0.0.1,0.0.2)'

Sensor REST Service Implementation

Create the directory ~/eventing-example/sensor.impl/src/main/resources and copy the downloaded sensor.impl/src/main/resources/static folder which is the implementation of the sensor web page to the same place of current sensor.impl module (i.e. ~/eventing-example/sensor.impl/src/main/resources/static).

~/eventing-example $ ls light.impl/src/main/resources/static
css  img  index.html  js  lib

Now the sensor smart behaviour is ready to be built using mvn package command as shown before.

Create Controller Implementation Module

Go to eventing-example project directory, create the behaviour.impl module using the ds-component Archetype:

~/eventing-example $ mvn archetype:generate \
     -DarchetypeGroupId=org.osgi.enroute.archetype \
     -DarchetypeArtifactId=ds-component \
     -DarchetypeVersion=7.0.0

with the following values:

Define value for property 'groupId': com.paremus.brain.iot.example
Define value for property 'artifactId': behaviour.impl
Define value for property 'version' 1.0-SNAPSHOT: : 0.0.1-SNAPSHOT
Define value for property 'package' com.paremus.brain.iot.example.behaviour.impl: : 
Confirm properties configuration:
groupId: com.paremus.brain.iot.example
artifactId: behaviour.impl
version: 0.0.1-SNAPSHOT
package: com.paremus.brain.iot.example.behaviour.impl
 Y: :

Dependencies

Replace the auto-genearted POM in this module with the following, specifially, the light.api and sensor.api bundles are its dependencies:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <artifactId>eventing-example</artifactId>
    <groupId>com.paremus.brain.iot.example</groupId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>

    <groupId>com.paremus.brain.iot.example</groupId>
    <artifactId>behaviour.impl</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <description>The behaviour.impl DS component - built using OSGi enRoute R7</description>

    <dependencies>
        <dependency>
            <groupId>org.osgi.enroute</groupId>
            <artifactId>osgi-api</artifactId>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.osgi.enroute</groupId>
            <artifactId>impl-index</artifactId>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot.example</groupId>
            <artifactId>sensor.api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot.example</groupId>
            <artifactId>light.api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot</groupId>
            <artifactId>eventing.api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.osgi.enroute</groupId>
            <artifactId>test-bundles</artifactId>
            <type>pom</type>
        </dependency>
     </dependencies>

    <build>
        <plugins>
            <!-- Expected to inherit configuration from a parent enRoute 
                pom. This includes -contract definitions and maven-jar-plugin setup -->
            <plugin>
                <groupId>biz.aQute.bnd</groupId>
                <artifactId>bnd-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>com.paremus.brain.iot.maven</groupId>
                <artifactId>smart-behaviour-maven-plugin</artifactId>
                <version>0.0.1-SNAPSHOT</version>
                <executions>
					<execution>
						<goals>
							<goal>smart-behaviour</goal>
						</goals>
					</execution>
				</executions>
            </plugin>
        </plugins>
    </build>
</project>

Implement the behaviour.impl smart behaviour

Overwrite auto-generated ComponentImpl.java class in src package:

~/eventing-example/behaviour.impl/src/main/java/com/paremus/brain/iot/example/behaviour/impl/ComponentImpl.java

/* Copyright 2019 Paremus, Ltd - All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
 */
package com.paremus.brain.iot.example.behaviour.impl;

import com.paremus.brain.iot.example.light.api.LightCommand;
import com.paremus.brain.iot.example.sensor.api.SensorReadingDTO;
import eu.brain.iot.eventing.annotation.SmartBehaviourDefinition;
import eu.brain.iot.eventing.api.EventBus;
import eu.brain.iot.eventing.api.SmartBehaviour;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * A Smart Behaviour implementing a security light that slowly turns off
 */
@Component
@SmartBehaviourDefinition(consumed = SensorReadingDTO.class, filter = "(timestamp=*)",
        author = "Paremus", name = "Example Smart Security Light Behaviour",
        description = "Implements a security light that slowly turns off.")
@Designate(ocd = ComponentImpl.Config.class)
public class ComponentImpl implements SmartBehaviour<SensorReadingDTO> {
    @ObjectClassDefinition(
            name = "Smart Security Behaviour",
            description = "Configuration for the Smart Security Behaviour."
    )
    @interface Config {
        enum LightColour {
            WHITE, RED, YELLOW, MAGENTA, GREEN, BLUE, CYAN
        }

        @AttributeDefinition(type = AttributeType.INTEGER,
                name = "Time on",
                description = "How long light stays on after sensor is triggered (seconds)",
                min = "10",
                max = "300"
        )
        int duration() default 10;

        @AttributeDefinition(
                name = "Colour",
                description = "Colour light emits when activated"
        )
        LightColour colour() default LightColour.WHITE;
    }

    private final int MAX_BRIGHTNESS = 10;

	private final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();

	private final AtomicInteger brightness = new AtomicInteger();

	@Reference
	private EventBus eventBus;

	private Config config;

	@Activate
	void activate(Config config) {
	    this.config = config;
    }

    @Modified
    void modify(Config config) {
        this.config = config;
    }

	@Deactivate
	void stop() {
		worker.shutdown();
	}

	@Override
	public void notify(SensorReadingDTO event) {

		int oldValue = brightness.getAndSet(MAX_BRIGHTNESS);

		if(oldValue == 0) {
			worker.execute(this::updateBulb);
		}
	}

	private void updateBulb() {
		int value = brightness.getAndAccumulate(-1, (a,b) -> Math.max(0, a + b));

		LightCommand command = new LightCommand();
		command.brightness = value;
		command.status = value > 0;

		eventBus.deliver(command);

		if (value != 0) {
		    long delayMs = config.duration() * 1000 / MAX_BRIGHTNESS;
			worker.schedule(this::updateBulb, delayMs, TimeUnit.MILLISECONDS);
		}
	}
}

Now the behaviour.impl smart behaviour is ready to be built using mvn package command as shown before.

Build the System

Now build and install all smart behaviours together from the parent root directory:

~/eventing-example $ mvn clean install

[INFO] Scanning for projects...
[INFO] Copying .....
[INFO] Processing ~/eventing-example/*/*.bndrun for dependencies
[INFO] Building jar: ~/eventing-example/light.impl/target/light.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour.jar
[INFO] Installing ~/eventing-example/light.impl/target/light.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour.jar to ~/.m2/repository/com/paremus/brain/iot/example/light.impl/0.0.1-SNAPSHOT/light.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour.jar
......
[INFO] Building jar: ~/eventing-example/sensor.impl/target/sensor.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour.jar
[INFO] Installing ~/eventing-example/sensor.impl/target/sensor.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour.jar to ~/.m2/repository/com/paremus/brain/iot/example/sensor.impl/0.0.1-SNAPSHOT/sensor.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour.jar
......
[INFO] Building jar: ~/eventing-example/behaviour.impl/target/behaviour.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour.jar
[INFO] Installing ~/eventing-example/behaviour.impl/target/behaviour.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour.jar to ~/.m2/repository/com/paremus/brain/iot/example/behaviour.impl/0.0.1-SNAPSHOT/behaviour.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

As shown in the logs, finally there are three smart behaviurs generated in the implementation modules.

The install goal will install the smart behaviors together with the OSGi bundles in Maven local repository (~/.m2), which will be used when creating the marketplace, as shown later in this page. Alternativly, the smart behaviours can be deployed to a respository server, and add this repository in the marketplace project.

If there is already a smart behaviour has been generated before rebuilding the project, remember to run the clean goal before the package goal to remove the existing smart-behaviour folder from the project target directory to avoid failure when copying the denpendencies.

The Composite Application

We now pull these Modules together to create the Composite Application to test the whole system work well before deploying it to BRAIN-IoT Fabric.

In the eventing-example project directory, create the single-framework-example application module using the application Archetype:

~/eventing-example $ mvn archetype:generate \
     -DarchetypeGroupId=org.osgi.enroute.archetype \
     -DarchetypeArtifactId=application \
     -DarchetypeVersion=7.0.0

with the following values:

Define value for property 'groupId': com.paremus.brain.iot.example
Define value for property 'artifactId': single-framework-example
Define value for property 'version' 1.0-SNAPSHOT: : 0.0.1-SNAPSHOT
Define value for property 'package' com.paremus.brain.iot.example: : 
Define value for property 'impl-artifactId': light.impl
Define value for property 'impl-groupId' com.paremus.brain.iot.example: : 
Define value for property 'impl-version' 0.0.1-SNAPSHOT: : 
[INFO] Using property: target-java-version = 8
Confirm properties configuration:
groupId: com.paremus.brain.iot.example
artifactId: single-framework-example
version: 0.0.1-SNAPSHOT
package: com.paremus.brain.iot.example
impl-artifactId: light.impl
impl-groupId: com.paremus.brain.iot.example
impl-version: 0.0.1-SNAPSHOT
target-java-version: 8
Y: :

Dependencies

Replace the auto-genearted POM in this module with the following: the content is similar with the light.impl POM with the build configuartion:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <artifactId>eventing-example</artifactId>
    <groupId>com.paremus.brain.iot.example</groupId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>

    <groupId>com.paremus.brain.iot.example</groupId>
    <artifactId>single-framework-example</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <description>The single-framework-example application packaging project - using OSGi enRoute R7</description>

    <dependencies>
        <dependency>
            <groupId>com.paremus.brain.iot.example</groupId>
            <artifactId>behaviour.impl</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot.example</groupId>
            <artifactId>light.impl</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot.example</groupId>
            <artifactId>sensor.impl</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot</groupId>
            <artifactId>eventing.impl</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.aries.jax.rs</groupId>
            <artifactId>org.apache.aries.jax.rs.jackson</artifactId>
            <version>1.0.2</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.osgi.enroute</groupId>
            <artifactId>osgi-api</artifactId>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.osgi.enroute</groupId>
            <artifactId>impl-index</artifactId>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.osgi.enroute</groupId>
            <artifactId>debug-bundles</artifactId>
            <type>pom</type>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>biz.aQute.bnd</groupId>
                <artifactId>bnd-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>biz.aQute.bnd</groupId>
                <artifactId>bnd-indexer-maven-plugin</artifactId>
                <configuration>
                    <includeJar>true</includeJar>
                </configuration>
            </plugin>
            <plugin>
                <groupId>biz.aQute.bnd</groupId>
                <artifactId>bnd-export-maven-plugin</artifactId>
                <configuration>
                    <bndruns>
                        <bndrun>single-framework-example.bndrun</bndrun>
                    </bndruns>
                </configuration>
            </plugin>
            <plugin>
                <groupId>biz.aQute.bnd</groupId>
                <artifactId>bnd-resolver-maven-plugin</artifactId>
                <configuration>
                    <bndruns>
                        <bndrun>single-framework-example.bndrun</bndrun>
                        <bndrun>debug.bndrun</bndrun>
                    </bndruns>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Apart from the light.impl bundle, the sendor.impl and the behaviour.impl bundles should also be the dependencies for the application module.

Define Runtime Entity

Our Security Light System is composed of the following elements:

  • A light smart behaviour
  • A sensor smart behaviour
  • A behaviour controller smart behaviour
  • JAX-RS whiteboard resources for web pages

These dependencies are expressed as runtime Requirements in the ~/eventing-example/single-framework-example/single-framework-example.bndrun file.

Overwrite the content of the single-framework-example.bndrun from:

index: target/index.xml;name="single-framework-example"

-standalone: ${index}

-runrequires: osgi.identity;filter:='(osgi.identity=com.paremus.brain.iot.example.light.impl)'
-runfw: org.eclipse.osgi
-runee: JavaSE-1.8

-resolve.effective: active

to:

index: target/index.xml;name="single-framework-example"

-standalone: ${index}

-runrequires: \
	osgi.identity;filter:='(osgi.identity=com.paremus.brain.iot.example.behaviour.impl)',\
	bnd.identity;id='com.paremus.brain.iot.example.light.impl',\
	bnd.identity;id='com.paremus.brain.iot.example.sensor.impl',\
	bnd.identity;id='org.apache.aries.jax.rs.jackson'
-runfw: org.eclipse.osgi
-runee: JavaSE-1.8

-resolve.effective: active

Now build to generate the index, test index, and resolve this bndrun (you should be able to see the changes in the runbundles list afterwards). Then run whole system in the eventing-example root directory as done in the begining of this tutorial.

~/eventing-example $ cd single-framework-example
~/eventing-example/single-framework-example $ mvn bnd-indexer:index bnd-indexer:index@test-index bnd-resolver:resolve
~/eventing-example/single-framework-example $ cd ..
~/eventing-example $ mvn clean verify
~/eventing-example $ java -jar single-framework-example/target/single-framework-example.jar

If the resolve fails then check your code and try again. Once you can package it cleanly then continue to the next stage.

Create a Marketplace

BRAIN-IoT provides the behaviour-marketplace-maven-plugin for creating a marketplace. A marketplace gathers and unpackages all smart behaviours jars of a system into the marketplace directory in project target folder. In addition, there are a index.xml will be generated for resolving the marketplace and a marketplace site index.html file.

The development of the Security Light System is done, here we’ll create a marketplace for it.

Create a minimal enRoute maven project security-light-marketplace at HOME folder using the bare-project Archetype:

~/eventing-example $ cd
~$ mvn archetype:generate \
     -DarchetypeGroupId=org.osgi.enroute.archetype \
     -DarchetypeArtifactId=project-bare \
     -DarchetypeVersion=7.0.0

with the following values:

Define value for property 'groupId': com.paremus.brain.iot.marketplace
Define value for property 'artifactId': security-light-marketplace
Define value for property 'version' 1.0-SNAPSHOT: : 0.0.1-SNAPSHOT
Define value for property 'package' com.paremus.brain.iot.marketplace: : 
Confirm properties configuration:
groupId: com.paremus.brain.iot.marketplace
artifactId: security-light-marketplace
version: 0.0.1-SNAPSHOT
package: com.paremus.brain.iot.marketplace
Y: :

Dependencies

Open pom and change the <bnd.version> to

<bnd.version>5.1.2</bnd.version>

Similar with the POM setup of eventing.example project above, append the following repositories in <repositories> section for downloading the BRAIN-IoT runtime dependencies:

        <repository>
            <id>brain-iot-releases</id>
            <name>BRAIN-IoT Releases</name>
            <url>https://nexus.repository-pert.ismb.it/repository/maven-releases/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>brain-iot-snapshots</id>
            <name>BRAIN-IoT Snapshots</name>
            <url>https://nexus.repository-pert.ismb.it/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>

and append the following plugin repositories in <pluginRepositories> section for downloading the BRAIN-IoT behaviour-marketplace-maven-plugin:

        <pluginRepository>
            <id>brain-iot-releases</id>
            <name>BRAIN-IoT Releases</name>
            <url>https://nexus.repository-pert.ismb.it/repository/maven-releases/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>brain-iot-snapshots</id>
            <name>BRAIN-IoT Snapshots</name>
            <url>https://nexus.repository-pert.ismb.it/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>

Then create the new <dependencies> section and add the light.iml, sensor.impl, behaviour.impl OSGi artifacts:

    <dependencies>
        <dependency>
            <groupId>com.paremus.brain.iot.example</groupId>
            <artifactId>behaviour.impl</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot.example</groupId>
            <artifactId>light.impl</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.paremus.brain.iot.example</groupId>
            <artifactId>sensor.impl</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

Build

Create the new <build> section and add the behaviour-marketplace-maven-plugin plugin to build the marketplace:

    <build>
        <plugins>
            <plugin>
            <groupId>com.paremus.brain.iot.maven</groupId>
				<artifactId>behaviour-marketplace-maven-plugin</artifactId>
				<version>0.0.1-SNAPSHOT</version>
				<configuration>
				</configuration>
				<executions>
					<execution>
						<goals>
							<goal>generate</goal>
						</goals>
					</execution>
				</executions>
            </plugin>
        </plugins>
    </build>
~ $ cd security-light-marketplace
~/security-light-marketplace $ mvn package
[INFO] Scanning for projects...                                                                        
[INFO] ------------------------------------------------------------------------
[INFO] Building security-light-marketplace 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] --- behaviour-marketplace-maven-plugin:0.0.1-SNAPSHOT:generate (default) @ security-light-marketplace ---
......
[INFO] Unpacking ~/.m2/repository/com/paremus/brain/iot/example/behaviour.impl/0.0.1-SNAPSHOT/behaviour.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour.jar to ~/security-light-marketplace/target/marketplace/behaviour.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour-jar ......
[INFO] Unpacking ~/.m2/repository/com/paremus/brain/iot/example/light.impl/0.0.1-SNAPSHOT/light.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour.jar to ~/security-light-marketplace/target/marketplace/light.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour-jar ......
[INFO] Unpacking ~/.m2/repository/com/paremus/brain/iot/example/sensor.impl/0.0.1-SNAPSHOT/sensor.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour.jar to ~/security-light-marketplace/target/marketplace/sensor.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour-jar ......
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

The logs indicated that the smart behaviours are unpacked from the maven local Repo (~/.m2) to the target directory folder

Enter the target folder and check the geenrated marketplace:

~/security-light-marketplace $ ls target/marketplace
behaviour.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour-jar  light.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour-jar
index.html                                                   sensor.impl-0.0.1-SNAPSHOT-brain-iot-smart-behaviour-jar
index.xml

To make the marketplace index available for configuring the Behaviour Management Service from the BRAIN-IoT UI as shown in the Quick Start tutorial, the marketplace site has to be deployed to a HTTP server. The marketplace index will be also used to create a system document as shown in next Destributed Deployment tutorial.

Deploy Marketplace to a Local HTTP server

Copy the marketplace folder from target directory to the root of the HTTP server, the marketplace index is https://localhost/marketplace/index.xml

~/security-light-marketplace $ sudo cp -rf target/marketplace /var/www/html
~/security-light-marketplace $ ls /var/www/html
marketplace

Deploy to a Nexus server

The Security Light Marketplace is now deployed on the BRAIN-IoT Nexus server. Open the security-light-marketplace POM, then

Add new <distributionManagement> section, then add the site URL:

	<distributionManagement>
		<site>
			<id>brain-iot-nexus-marketplace</id>
			<url>dav:https://nexus.repository-pert.ismb.it/repository/marketplaces/${project.groupId}/${project.artifactId}/${project.version}</url>
		</site>
	</distributionManagement>

Append the org.apache.maven.plugins:maven-site-plugin in the <build> section to deploy the the generated site to site URL specified in pom:

            <plugin>
                <artifactId>maven-site-plugin</artifactId>
                <version>3.4</version>
                <dependencies>
                    <dependency>
                        <groupId>org.apache.maven.wagon</groupId>
                        <artifactId>wagon-webdav-jackrabbit</artifactId>
                        <version>2.8</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <skip>true</skip>
                    <inputDirectory>${project.build.directory}/marketplace</inputDirectory>
                </configuration>
            </plugin>

Run the following command to deploy the site:

~/security-light-marketplace $ mvn clean verify site:deploy

After deployment is successful, then the marketplace index https://nexus.repository-pert.ismb.it/repository/marketplaces/com.paremus.brain.iot.example/security-light-marketplace/0.0.1-SNAPSHOT/index.xml is avilable.

End

That completes this tutorial.