User Tools

Site Tools


sensorweaver:developer-guide

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
sensorweaver:developer-guide [2014-12-22 13:14] – [SensorWeaver Developer Guide] luigi.fortunatisensorweaver:developer-guide [2015-11-10 16:46] (current) – [Testing your app] luigi.fortunati
Line 1: Line 1:
 ===== SensorWeaver Developer Guide ===== ===== SensorWeaver Developer Guide =====
-SensorWeaver is Java software. Middleware components are available as OSGi bundles available publicly in Maven repositories.+SensorWeaver is Java software. Middleware components are available as OSGi bundlesavailable publicly in Maven repositories
 +This guide shows how to use SensorWeaver Middleware in your software projects.
  
 General requirements: General requirements:
   * Knowledge of Java, OSGi, Maven.   * Knowledge of Java, OSGi, Maven.
-  * Java Development Kit 7 +  * Java Development Kit 8 
-  * An IDE with Maven support (preferably) +  * An IDE, preferably with Maven support 
-  * For testing your app+  * For testing/deployment
     * An OSGi container for testing. [[http://karaf.apache.org/|Karaf]] is strongly suggested     * An OSGi container for testing. [[http://karaf.apache.org/|Karaf]] is strongly suggested
     * A [[http://mosquitto.org/|Mosquitto]] MQTT broker or another     * A [[http://mosquitto.org/|Mosquitto]] MQTT broker or another
  
-A project containing most of the examples shown in this guide can be downloaded at this [[http://ala.isti.cnr.it/svn/wnlab/SensorWeaver/sample-sensor/trunk/|link]] +A project containing most of the examples shown in this guide can be downloaded at this [[http://ala.isti.cnr.it/svn/wnlab/SensorWeaver/sample-sensor/trunk/|location]] 
-==== Project and development environment setup ====+==== Development environment setup ====
  
-You'll need Java JDK to compile and run your project. [[http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html|Download]] and install one for your system.+You'll need Java JDK to compile and run your project. [[http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html|Download]] and install one for your system.
  
 SensorWeaver components are distributed using Maven [[http://ala.isti.cnr.it:8081/nexus/index.html#welcome|WNLab repositories]].  SensorWeaver components are distributed using Maven [[http://ala.isti.cnr.it:8081/nexus/index.html#welcome|WNLab repositories]]. 
 +
 In order to access released and development JARs you need to configure your development environment. In order to access released and development JARs you need to configure your development environment.
 +
 The best way to achieve this is to add third-party repos to your global maven //settings.xml// in the //default profile//. This removes the need of configuring each maven project. The best way to achieve this is to add third-party repos to your global maven //settings.xml// in the //default profile//. This removes the need of configuring each maven project.
  
Line 24: Line 27:
 <profiles> <profiles>
    <profile>    <profile>
-      <id>default</id>+      <id>wnlab</id>
       <repositories>       <repositories>
          <!-- WNlab Repos -->          <!-- WNlab Repos -->
Line 58: Line 61:
    </profile>    </profile>
 </profiles> </profiles>
 +<activeProfiles>
 +   <activeProfile>wnlab</activeProfile>
 +</activeProfiles>
 </file> </file>
  
-As an alternative, you can include the //repositories// tag inside of your maven project //pom.xml//.+As an alternative, you can include just the //repositories// tag listed above, inside of your Maven project //pom.xml//.
  
 Maven repositories include documentation and source code artifacts. Maven repositories include documentation and source code artifacts.
 +
 Source code can be accessed in read-only in [[http://ala.isti.cnr.it/svn/wnlab/SensorWeaver/|WNLab Subversion]] repository if needed. Source code can be accessed in read-only in [[http://ala.isti.cnr.it/svn/wnlab/SensorWeaver/|WNLab Subversion]] repository if needed.
  
-=== Project setup ===+==== Project setup ====
 Create a Maven project using the IDE of choice. Create a Maven project using the IDE of choice.
  
 The project must generate an OSGi bundle, so: The project must generate an OSGi bundle, so:
   *Set packaging type to //bundle//   *Set packaging type to //bundle//
-  *Set Java compiler with [[http://maven.apache.org/plugins/maven-compiler-plugin/|maven compiler plugin]]+  *Set Java compiler with [[http://maven.apache.org/plugins/maven-compiler-plugin/|maven compiler plugin]]
   *Include the [[http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html|maven bundle plugin]] in order to produce a jar bundle with OSGi manifest.   *Include the [[http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html|maven bundle plugin]] in order to produce a jar bundle with OSGi manifest.
  
Line 85: Line 92:
          <version>3.1</version>          <version>3.1</version>
          <configuration>          <configuration>
-            <source>1.7</source> +            <source>1.8</source> 
-            <target>1.7</target>+            <target>1.8</target>
          </configuration>          </configuration>
       </plugin>       </plugin>
Line 110: Line 117:
 **Tip**: You can find a list of manifest headers on the [[http://wiki.osgi.org/wiki/Category:Manifest_Header|OSGI wiki]] **Tip**: You can find a list of manifest headers on the [[http://wiki.osgi.org/wiki/Category:Manifest_Header|OSGI wiki]]
  
-Add the //middleware-api// dependency to your //pom.xml//.+Then add the //middleware-api// dependency to your project //pom.xml//:
 <file xml pom.xml> <file xml pom.xml>
 <dependencies> <dependencies>
Line 116: Line 123:
       <groupId>it.cnr.isti.sensorweaver.middleware</groupId>       <groupId>it.cnr.isti.sensorweaver.middleware</groupId>
       <artifactId>middleware-api</artifactId>       <artifactId>middleware-api</artifactId>
-      <version>2.0.0</version>+      <version>2.1.0</version>
    </dependency>    </dependency>
 </dependencies> </dependencies>
 </file> </file>
  
-Tip: Check the latest //middleware-api// version on [[http://ala.isti.cnr.it:8081/nexus/index.html#nexus-search;gav~it.cnr.isti.sensorweaver.middleware~middleware-api~~~|WNLab Nexus Repo]] or use [[https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html|maven version ranges]] to be up-to-date with the latest API.+Tip: Check the latest //middleware-api// version on [[http://ala.isti.cnr.it:8081/nexus/index.html#nexus-search;gav~it.cnr.isti.sensorweaver.middleware~middleware-api~~~|WNLab Nexus Repo]] or use [[https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html|maven version ranges]] to be up to date with the latest API.
 ==== Getting an instance of the Middleware service ==== ==== Getting an instance of the Middleware service ====
 Inside of the OSGi runtime environment, the Middleware stands as an OSGi service.  Inside of the OSGi runtime environment, the Middleware stands as an OSGi service. 
Line 127: Line 134:
 There are several ways to achieve this. Here we list two solutions: There are several ways to achieve this. Here we list two solutions:
     * Querying the service registry programmatically using //BundleActivator//     * Querying the service registry programmatically using //BundleActivator//
-    * Blueprint+    * Blueprint (strongly recommended)
  
-=== Bundle Activator === 
- 
-You'll need OSGi dependencies in your pom: 
-<file xml pom.xml> 
-<dependency> 
-   <groupId>org.osgi</groupId> 
-   <artifactId>core</artifactId> 
-   <version>4.3.0</version> 
-</dependency> 
-</file> 
- 
-Then create a java class for your bundle activator: 
-<file java MySensorPublisherActivator.java> 
-package it.cnr.isti.sample; 
- 
-import it.cnr.isti.sensorweaver.middleware.api.Middleware; 
- 
-import org.osgi.framework.BundleActivator; 
-import org.osgi.framework.BundleContext; 
-import org.osgi.framework.ServiceReference; 
- 
-public class MySensorPublisherActivator implements BundleActivator { 
- 
- private ServiceReference<Middleware> middlewareReference; 
- private MySensorPublisher publisher; 
- 
- public void start(BundleContext context) throws Exception { 
- middlewareReference = context.getServiceReference(Middleware.class); 
- Middleware middleware = context.getService(middlewareReference); 
-                //Middleware instance can be passed to other components at this point   
- publisher = new MySensorPublisher(middleware); 
- publisher.start(); 
- } 
- 
- public void stop(BundleContext context) throws Exception { 
- publisher.stop(); 
- context.ungetService(middlewareReference); 
- } 
- 
-} 
-</file> 
- 
-Declare your bundle activator in your Manifest by configuring the //maven bundle plugin//: 
-<file xml pom.xml> 
-<plugin> 
-   <groupId>org.apache.felix</groupId> 
-   <artifactId>maven-bundle-plugin</artifactId> 
-   <version>2.3.7</version> 
-   <extensions>true</extensions> 
-   <configuration> 
-      <instructions> 
-         <!-- ... Other manifest headers ... --> 
-         <Bundle-Activator>it.cnr.isti.sample.MySensorPublisherActivator</Bundle-Activator> 
-      </instructions> 
-   </configuration> 
-</plugin> 
-</file> 
  
 === Blueprint === === Blueprint ===
Line 220: Line 170:
 </file> </file>
  
-Assuming that you're following Maven conventions on project structure, create folder under ''src/main/resources'': ''OSGI-INF/blueprint''.+Assuming that you're following Maven conventions on project structure, create the folder ''src/main/resources/OSGI-INF/blueprint''.
  
 Create a ''services.xml'' file inside of this folder with this content: Create a ''services.xml'' file inside of this folder with this content:
Line 230: Line 180:
  xsi:schemaLocation="  xsi:schemaLocation="
  http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd   http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd 
- http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0 http://aries.apache.org/schemas/blueprint-cm/blueprint-cm-1.1.0.xsd+ http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0 http://aries.apache.org/schemas/blueprint-cm/blueprint-cm-1.1.0.xsd">
- default-activation="lazy">+
  
  <reference id="middleware"  <reference id="middleware"
Line 243: Line 192:
 </file> </file>
 This configuration basically tells the blueprint runtime to This configuration basically tells the blueprint runtime to
-  * create an instance of ''MySensorPublisher'' when the bundle starts (activation=eager) by wiring it with a proxy reference of the Middleware +  * create an instance of ''MySensorPublisher'' when the bundle starts (activation=eager) by wiring it with a proxy reference of the Middleware using the constructor 
-  * call the method ''start'' of the instance when it is initialized+  * call the method ''start'' of the instance when the bundle is started and the bean is initialized
   * call the method ''stop'' of the instance when the bundle gets stopped   * call the method ''stop'' of the instance when the bundle gets stopped
  
Line 250: Line 199:
 ==== API and usage ==== ==== API and usage ====
  
-Middleware service methods executes asynchronous tasks when called. Whenever a method is called a ''Future'' object is returned ([[http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html|documentation]]).+Middleware service methods executes asynchronous tasks when called. Whenever a methodis called a ''Future'' object is returned ([[http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html|documentation]]).
 This solution removes the need to implement callbacks for every method call, improving code readability. This solution removes the need to implement callbacks for every method call, improving code readability.
 The client can synchronize with the end of the middleware task by calling the ''get'' method on the ''Future'' instance, retrieving a result of the computation, when expected, or an asynchronous task execution exception. The client can synchronize with the end of the middleware task by calling the ''get'' method on the ''Future'' instance, retrieving a result of the computation, when expected, or an asynchronous task execution exception.
Line 271: Line 220:
  
   * ''announceDataFeed'' allows to announce the availability of a new //data feed// on the Middleware. It returns, asynchronously, a ''DataFeedClient'' instance that is used for sending data feed messages and unregister the datafeed.   * ''announceDataFeed'' allows to announce the availability of a new //data feed// on the Middleware. It returns, asynchronously, a ''DataFeedClient'' instance that is used for sending data feed messages and unregister the datafeed.
-  * ''registerDiscoverer'' allows to register a ''DataFeedDiscoverer'' instance, a callback object that is notified about lifecycle events related to a set //data feeds//+  * ''registerDiscoverer'' allows to register a ''DataFeedDiscoverer'' instance, a callback object that is notified about lifecycle events related to a set of //data feeds//
   * ''registerListener'' allows to register a ''DataFeedListener'' instance, a callback object that is notified each time a message is produced by a ''data feed''   * ''registerListener'' allows to register a ''DataFeedListener'' instance, a callback object that is notified each time a message is produced by a ''data feed''
  
Line 285: Line 234:
 import it.cnr.isti.sensorweaver.middleware.api.datafeed.descriptor.DataFeedDescriptor; import it.cnr.isti.sensorweaver.middleware.api.datafeed.descriptor.DataFeedDescriptor;
 import it.cnr.isti.sensorweaver.middleware.api.datafeed.descriptor.DataFeedBuilder; import it.cnr.isti.sensorweaver.middleware.api.datafeed.descriptor.DataFeedBuilder;
 +import it.cnr.isti.sensorweaver.middleware.api.common.descriptor.Property;
  
 /** ... **/ /** ... **/
Line 293: Line 243:
  builder.property("sensorType", "temperatureSensor");  builder.property("sensorType", "temperatureSensor");
  builder.parameter("temperature", new Property("Unit of Measure","Celsius"));  builder.parameter("temperature", new Property("Unit of Measure","Celsius"));
- builder.parameter("timestamp", new Property("Format","ISO8601")); + return builder.build();
- DataFeedDescriptor descriptor = builder.build()+
- return descriptor;+
 } }
 </code> </code>
Line 321: Line 269:
  MessageBuilder messageBuilder = dataFeedClient.buildMessage();  MessageBuilder messageBuilder = dataFeedClient.buildMessage();
  messageBuilder.entry("temperature", Integer.toString(datasource.getValue()));  messageBuilder.entry("temperature", Integer.toString(datasource.getValue()));
- messageBuilder.entry("timestamp", DateTime.now().toString());+ messageBuilder.timestamp(Calendar.getInstance().getTimeInMillis());
  messageBuilder.send();  messageBuilder.send();
 } }
 </code> </code>
 +
 +In order to publish a message for a given //data feed// you must produce values for all of the message elements defined previously in the //data feed descriptor//.
 +
 +The datafeed client includes a method //timestamp// for setting the timestamp of the message. If not used, the middleware will set the timestamp at the time of the invocation of the send method.
  
 === Unregistering a Data Feed === === Unregistering a Data Feed ===
Line 338: Line 290:
 === Discover Data Feeds === === Discover Data Feeds ===
 In order to discover new //data feeds// you need to define a ''DataFeedDiscoverer'' first, like the following: In order to discover new //data feeds// you need to define a ''DataFeedDiscoverer'' first, like the following:
- 
  
 <code java> <code java>
Line 362: Line 313:
 </code> </code>
 The discoverer provides a filter which tells the Middleware about which data feeds the discoverer has to be notified on data feed lifecycle events. The discoverer provides a filter which tells the Middleware about which data feeds the discoverer has to be notified on data feed lifecycle events.
 +The filter matches with announced data feed descriptors that have the same property values.
  
 To activate a discoverer you must register it on the Middleware; To activate a discoverer you must register it on the Middleware;
Line 376: Line 328:
  
 In order to start listening for a //data feed// the middleware client must provide a ''DataFeedListener'' In order to start listening for a //data feed// the middleware client must provide a ''DataFeedListener''
-Each listener will listen to messages sent by a //data feed//+ 
 +Each listener will listen to messages sent by a specific //data feed//.
  
 <code java> <code java>
 +    RegistrationToken registrationToken;
 +    
 +    /** ... **/
 +    
 private void startListening(DataFeedDescriptor descriptor) throws InterruptedException, ExecutionException { private void startListening(DataFeedDescriptor descriptor) throws InterruptedException, ExecutionException {
- RegistrationToken registrationToken; +    registrationToken = middleware.registerListener(new LoggingListener(descriptor)).get();
- registrationToken = middleware.registerListener(new LoggingListener(descriptor)).get(); +
- listenerTokens.put(descriptor, registrationToken);+
 } }
   
-private void stopListening(DataFeedDescriptor descriptor) throws InterruptedException, ExecutionException { +private void stopListening() throws InterruptedException, ExecutionException { 
-    RegistrationToken registrationToken = listenerTokens.remove(descriptor); +    registrationToken.unregister().get();
-    if (registrationToken != null) registrationToken.unregister().get();+
 } }
 </code> </code>
 +The same unregistration mechanisms of ''DataFeedDiscoverer'' applies to ''DataFeedListener''.
 +
 +==== Testing your app ====
 +
 +Applications can be easily tested in the [[http://karaf.apache.org/|Karaf]] OSGi environment, using provided logging and debugging tools.
  
-==== Integration testing ====+You can download your preferred Apache Karaf release (latest version is strongly recommended) and install the ''middleware'' feature from the latest [[http://ala.isti.cnr.it:8081/nexus/index.html#nexus-search;quick~sensorweaver-features|SensorWeaver karaf feature repository]] to start up your container.
  
-Applications can be directly tested in Karaf OSGi environment using the middleware-dev feature. please refer to the administrator guide in order to setup the test environment.+Deafult feature configuration assumes that you have an MQTT broker online on port 1883 on your local machine.
  
 +Please refer to the [[sensorweaver:admin-guide|Administrator Guide]] in order to setup and configure your OSGI environment.
sensorweaver/developer-guide.1419254067.txt.gz · Last modified: 2014-12-22 13:14 by luigi.fortunati

Donate Powered by PHP Valid HTML5 Valid CSS Run on Debian Driven by DokuWiki