diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..f125e627 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.project +*.classpath +*.settings +*.MF +*/target/* +*.log +IoTBroker-runner/work/ diff --git a/IoTBroker-runner/configuration/config.ini b/IoTBroker-runner/configuration/config.ini new file mode 100644 index 00000000..2008c494 --- /dev/null +++ b/IoTBroker-runner/configuration/config.ini @@ -0,0 +1,112 @@ +############################## +# Equinox settings +############################## +eclipse.ignoreApp=true +osgi.clean=true +osgi.noShutdown=true +osgi.bundles.defaultStartLevel=4 +osgi.java.profile=java6-server.profile +osgi.java.profile.bootdelegation=override +# PaxLogging configuration folder +bundles.configuration.location=..//fiwareRelease//iotbrokerconfig//bundleConfigurations +# IoT Broker Server port +tomcat.init.port=80 +# Internal Database folder +hsqldb.directory=..//SQL_database//database//linkDB +# Internal Database port +hsqldb.port=9001 +# Enable the Database Logs +hsqldb.silent=false +# Absolute path to the config folder +dir.config=//root//Aeron//fiwareRelease +ngsiclient.layer=connector +java.awt.headless=true +file.encoding=UTF-8 +-server -Xms2048m -Xmx2048m +-XX:NewSize=1024m -XX:MaxNewSize=1024m -XX:PermSize=1024m +-XX:MaxPermSize=1024m -XX:+DisableExplicitGC +############################## +# Client bundles to install +############################## +osgi.bundles= ../targetPlatform/equinox/org.eclipse.core.contenttype-3.4.100.v20100505-1235.jar@start, \ +../targetPlatform/equinox/org.eclipse.equinox.common-3.6.0.v20110506.jar@2:start, \ +../targetPlatform/equinox/org.eclipse.core.jobs-3.5.0.v20100515.jar@start, \ +../targetPlatform/equinox/org.eclipse.equinox.app-1.3.0.v20100512.jar@start, \ +../targetPlatform/equinox/org.eclipse.equinox.preferences-3.3.0.v20100503.jar@start, \ +../targetPlatform/equinox/org.eclipse.equinox.registry-3.5.0.v20100503.jar@start, \ +../targetPlatform/equinox/org.eclipse.osgi.services-3.2.100.v20100503.jar@start, \ +../targetPlatform/equinox/org.eclipse.equinox.cm_3.2.0.v20070116.jar@1:start, \ +../targetPlatform/pax/pax-confman-propsloader-0.2.2.jar@2:start, \ +../targetPlatform/pax/pax-logging-api-1.7.0-20120710.130402-38.jar@2:start, \ +../targetPlatform/pax/pax-logging-service-1.7.0-20120710.130445-38.jar@2:start, \ +../targetPlatform/bundles/com.springsource.javax.activation-1.1.1.jar@start, \ +../targetPlatform/bundles/javax.persistence-2.0.0.jar@start, \ +../targetPlatform/bundles/httpclient-4.2.0-osgi.jar@start, \ +../targetPlatform/bundles/httpcore-4.2.0-osgi.jar@start, \ +../targetPlatform/bundles/com.springsource.org.apache.commons.io-1.4.0.jar, \ +../targetPlatform/bundles/com.springsource.org.apache.commons.codec-1.6.0.jar@start, \ +../targetPlatform/bundles/com.springsource.javax.annotation-1.0.0.jar@start, \ +../targetPlatform/bundles/com.springsource.javax.ejb-3.0.0.jar@start, \ +../targetPlatform/bundles/com.springsource.javax.el-1.0.0.jar@start, \ +../targetPlatform/bundles/com.springsource.javax.mail-1.4.0.jar@start, \ +../targetPlatform/bundles/com.springsource.javax.persistence-1.0.0.jar@start, \ +../targetPlatform/bundles/com.springsource.javax.servlet.jsp.jstl-1.1.2.jar@start, \ +../targetPlatform/bundles/com.springsource.javax.servlet.jsp-2.1.0.jar@start, \ +../targetPlatform/bundles/com.springsource.javax.servlet-2.5.0.jar@start, \ +../targetPlatform/bundles/com.springsource.javax.xml.bind-2.0.0.jar@start, \ +../targetPlatform/bundles/com.springsource.javax.xml.stream-1.0.1.jar@start, \ +../targetPlatform/bundles/com.springsource.javax.xml.rpc-1.1.0.jar@start, \ +../targetPlatform/bundles/com.springsource.javax.xml.soap-1.3.0.jar@start, \ +../targetPlatform/bundles/com.springsource.javax.xml.ws-2.1.1.jar@start, \ +../targetPlatform/bundles/com.springsource.org.aopalliance-1.0.0.jar@start, \ +../targetPlatform/bundles/com.springsource.org.apache.catalina-6.0.18.jar@start, \ +../targetPlatform/bundles/com.springsource.org.apache.coyote-6.0.18.jar, \ +../targetPlatform/bundles/com.springsource.org.apache.el-6.0.18.jar@start, \ +../targetPlatform/bundles/com.springsource.org.apache.juli.extras-6.0.18.jar@start, \ +../targetPlatform/bundles/com.springsource.org.apache.taglibs.standard-1.1.2.jar@start, \ +../targetPlatform/bundles/catalina.start.osgi-1.0.0.jar@start, \ +../targetPlatform/bundles/jasper.osgi-5.5.23-SNAPSHOT.jar@start, \ +../targetPlatform/bundles/catalina-config-3.5.1.jar, \ +../targetPlatform/jaxb/jaxb-impl-2.1.5_1.0.0.jar@start, \ +../targetPlatform/db/hsqldb_1.0.0.jar@start, \ +../targetPlatform/json/org.json_1.0.0.jar@start, \ +../targetPlatform/json/gson-2.2.2.jar@start, \ +../targetPlatform/json/jackson-core-asl-1.9.2.jar@start, \ +../targetPlatform/json/jackson-mapper-asl-1.9.2.jar@start, \ +../targetPlatform/spring 3.2.3/org.springframework.aop-3.2.3.RELEASE.jar@start, \ +../targetPlatform/spring 3.2.3/org.springframework.aspects-3.2.3.RELEASE.jar@start, \ +../targetPlatform/spring 3.2.3/org.springframework.beans-3.2.3.RELEASE.jar@start, \ +../targetPlatform/spring 3.2.3/org.springframework.context.support-3.2.3.RELEASE.jar@start, \ +../targetPlatform/spring 3.2.3/org.springframework.context-3.2.3.RELEASE.jar@start, \ +../targetPlatform/spring 3.2.3/org.springframework.core-3.2.3.RELEASE.jar@start, \ +../targetPlatform/spring 3.2.3/org.springframework.expression-3.2.3.RELEASE.jar@start, \ +../targetPlatform/spring 3.2.3/org.springframework.jdbc-3.2.3.RELEASE.jar@start, \ +../targetPlatform/spring 3.2.3/org.springframework.orm-3.2.3.RELEASE.jar@start, \ +../targetPlatform/spring 3.2.3/org.springframework.oxm-3.2.3.RELEASE.jar@start, \ +../targetPlatform/spring 3.2.3/org.springframework.transaction-3.2.3.RELEASE.jar@start, \ +../targetPlatform/spring 3.2.3/org.springframework.web.servlet-3.2.3.RELEASE.jar@start, \ +../targetPlatform/spring 3.2.3/org.springframework.web-3.2.3.RELEASE.jar@start, \ +../targetPlatform/spring 3.2.3/org.springframework.security.config-3.1.4.RELEASE.jar@start, \ +../targetPlatform/spring 3.2.3/org.springframework.security.core-3.1.4.RELEASE.jar@start, \ +../targetPlatform/spring 3.2.3/org.springframework.security.web-3.1.4.RELEASE.jar@start, \ +../targetPlatform/spring DM/spring-osgi-annotation-2.0.0.M1.jar@start, \ +../targetPlatform/spring DM/spring-osgi-core-2.0.0.M1.jar@start, \ +../targetPlatform/spring DM/spring-osgi-extender-2.0.0.M1.jar@start, \ +../targetPlatform/spring DM/spring-osgi-io-2.0.0.M1.jar@start, \ +../targetPlatform/spring DM/spring-osgi-web-2.0.0.M1.jar@start, \ +../targetPlatform/spring DM/spring-osgi-web-extender-2.0.0.M1.jar@start, \ +../targetPlatform/monitor/javamelodybundle_1.0.0.jar@start, \ +../targetPlatform/monitor/jrobin_1.5.9.1.jar@start, \ +../targetPlatform/bundles/guava-18.0.jar@start, \ +../eu.neclab.iotplatform.iotbroker.builder/target/iotbroker.builder-4.4.3-assembly/bundle/iotbroker.commons-4.4.3.jar@start, \ +../eu.neclab.iotplatform.iotbroker.builder/target/iotbroker.builder-4.4.3-assembly/bundle/iotbroker.storage-4.4.3.jar@start, \ +../eu.neclab.iotplatform.iotbroker.builder/target/iotbroker.builder-4.4.3-assembly/bundle/iotbroker.client-4.4.3.jar@start, \ +../eu.neclab.iotplatform.iotbroker.builder/target/iotbroker.builder-4.4.3-assembly/bundle/iotbroker.core-4.4.3.jar@start, \ +../eu.neclab.iotplatform.iotbroker.builder/target/iotbroker.builder-4.4.3-assembly/bundle/iotbroker.restcontroller-4.4.3.jar@start, \ +../eu.neclab.iotplatform.iotbroker.builder/target/iotbroker.builder-4.4.3-assembly/bundle/ngsi.api-4.4.3.jar@start, \ +../eu.neclab.iotplatform.iotbroker.builder/target/iotbroker.builder-4.4.3-assembly/bundle/iotbroker.ext.resultfilter-4.4.3.jar@start, \ +../eu.neclab.iotplatform.iotbroker.builder/target/iotbroker.builder-4.4.3-assembly/bundle/tomcat-configuration-fragment-4.4.3.jar, \ +#../eu.neclab.iotplatform.iotbroker.builder/target/iotbroker.builder-4.4.3-assembly/bundle/iotbroker.couchdb-4.4.3.jar@start,\ +../eu.neclab.iotplatform.iotbroker.builder/target/iotbroker.builder-4.4.3-assembly/bundle/entitycomposer-4.4.3.jar@start + + diff --git a/IoTBroker-runner/org.eclipse.osgi.jar b/IoTBroker-runner/org.eclipse.osgi.jar new file mode 100644 index 00000000..efc0763c Binary files /dev/null and b/IoTBroker-runner/org.eclipse.osgi.jar differ diff --git a/IoTBroker-runner/org.eclipse.update.configurator_3.3.100.v20100512.jar b/IoTBroker-runner/org.eclipse.update.configurator_3.3.100.v20100512.jar new file mode 100644 index 00000000..c798ccfd Binary files /dev/null and b/IoTBroker-runner/org.eclipse.update.configurator_3.3.100.v20100512.jar differ diff --git a/IoTBroker-runner/unix64_start-IoTBroker.sh b/IoTBroker-runner/unix64_start-IoTBroker.sh new file mode 100644 index 00000000..2124bd52 --- /dev/null +++ b/IoTBroker-runner/unix64_start-IoTBroker.sh @@ -0,0 +1,2 @@ +#!/bin/bash +java -jar org.eclipse.osgi.jar -console diff --git a/IoTBroker-runner/unix64_start-IoTBroker_as_Demon.sh b/IoTBroker-runner/unix64_start-IoTBroker_as_Demon.sh new file mode 100644 index 00000000..0bc65034 --- /dev/null +++ b/IoTBroker-runner/unix64_start-IoTBroker_as_Demon.sh @@ -0,0 +1,2 @@ +#/bin/bash +nohup java -jar org.eclipse.osgi.jar & diff --git a/IoTBroker-runner/unix64_stop-IoTBroker.sh b/IoTBroker-runner/unix64_stop-IoTBroker.sh new file mode 100644 index 00000000..36fe6fee --- /dev/null +++ b/IoTBroker-runner/unix64_stop-IoTBroker.sh @@ -0,0 +1,2 @@ +#!/bin/bash +pkill -f 'java -jar org.eclipse.osgi.jar' diff --git a/IoTBroker-runner/winx64_start-IoTBroker.bat b/IoTBroker-runner/winx64_start-IoTBroker.bat new file mode 100644 index 00000000..a142f991 --- /dev/null +++ b/IoTBroker-runner/winx64_start-IoTBroker.bat @@ -0,0 +1 @@ +java -jar org.eclipse.osgi.jar -console diff --git a/IoTbrokerParent/pom.xml b/IoTbrokerParent/pom.xml index 03bb9e53..544964a5 100644 --- a/IoTbrokerParent/pom.xml +++ b/IoTbrokerParent/pom.xml @@ -1,22 +1,14 @@ - - 4.0.0 eu.neclab.iotplatform IoTbrokerParent pom - - 4.4.1 UTF-8 - + 4.4.3 3.2.3.RELEASE 2.0.0.M1 3.7.0.v20110221 @@ -244,6 +236,9 @@ 2.5.0 + org.apache.commons com.springsource.org.apache.commons.codec @@ -376,7 +371,6 @@ - @@ -438,15 +431,6 @@ https://oss.sonatype.org/content/repositories/springsource-milestones - - @@ -487,5 +471,6 @@ ${project.version} - + + 4.4.3 \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md index f404312f..bf27826c 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -Copyright (c) 2015, NEC Europe Ltd. +Copyright (c) 2014, NEC Europe Ltd. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/README.md b/README.md index 24b2ae5a..aeeac079 100644 --- a/README.md +++ b/README.md @@ -8,19 +8,23 @@ The IoT Broker is an Internet-of-Things middleware based on the FIWARE NGSI stan IoT Broker Documentation --- -| Document | Reference | -| --------------------------- | ---------------------------------------------------------------------------------------------------------------- | -| FIWARE wiki | https://forge.fi-ware.org/plugins/mediawiki/wiki/fiware/index.php/Main_Page | -| IoT Broker GE specification | https://forge.fi-ware.org/plugins/mediawiki/wiki/fiware/index.php/FIWARE.OpenSpecification.IoT.Backend.IoTBroker | -| FIWARE NGSI API specification | https://forge.fi-ware.org/plugins/mediawiki/wiki/fiware/index.php/FI-WARE_NGSI_Open_RESTful_API_Specification | -| IoT Broker in FIWARE catalogue | http://catalogue.fiware.org/enablers/iot-broker | +| Document | Reference | Contents | +| --------------------------- | ---------------------------------------------------- | -------------------------------------------| +| This file | README.md | How to compile and run the IoT Broker. | +| FIWARE wiki | https://forge.fi-ware.org/plugins/mediawiki/wiki/fiware/index.php/Main_Page | Generic wiki about the FIWARE project and platform. | +| IoT Broker GE specification | https://forge.fi-ware.org/plugins/mediawiki/wiki/fiware/index.php/FIWARE.OpenSpecification.IoT.Backend.IoTBroker | Specification of IoT Broker Generic Enabler, including information about its role in the FIWARE Intenet-of-Things architecture, functionalities, and data flows.| +| IoT Broker API specification | http://aeronbroker.github.io/Aeron/ | Specification of the FIWARE NGSI-10 API exposed by the IoT Broker. | +| FIWARE NGSI API specification | https://forge.fi-ware.org/plugins/mediawiki/wiki/fiware/index.php/FI-WARE_NGSI_Open_RESTful_API_Specification | Specificaton of the FIWARE NGSI API, which is the interface exposed by the IoT Broker and many other FIWARE enablers. | +|IoT Broker Installation and Administration guide| https://forge.fiware.org/plugins/mediawiki/wiki/fiware/index.php/IoT_Broker_-_Installation_and_Administration_Guide | Installation guide (for binary release of IoT Broker) and administration guide. +|IoT Broker User and Programmer Guide| https://forge.fiware.org/plugins/mediawiki/wiki/fiware/index.php/IoT_Broker_-_User_and_Programmers_Guide | Guide showing some toy interactions with the IoT Broker. | +| IoT Broker in FIWARE catalogue | http://catalogue.fiware.org/enablers/iot-broker | Access to IoT Broker binaries and images. | What you get --- IoT Broker is an implementation of the IoT Broker Generic Enabler from FIWARE (http://catalogue.fiware.org/enablers/iot-broker). -It is specified as a lightweight and scalable middleware component that separates IoT applications from the underlying device installations. +It is designed as a lightweight and scalable middleware component that separates IoT applications from the underlying device installations. This implementation satisfies all properties described in the specification of the FIWARE Generic Enabler (https://forge.fi-ware.org/plugins/mediawiki/wiki/fiware/index.php/FIWARE.OpenSpecification.IoT.Backend.IoTBroker). The IoT Broker has unique properties that you will not find in other IoT Platforms: @@ -29,8 +33,8 @@ The IoT Broker has unique properties that you will not find in other IoT Platfor common publish/subscribe paradigm. Instead, the IoT Broker actively communicates simultaneously with multiple IoT gateways and devices in order to obtain exactly the information that is required by the running IoT applications. As a result, information only is generated and exchanged when needed. This is in contrast to the state-of-the-art -middleware components where any piece of information - whether needed or not - is just ''dumped'' inside a central -repository. +middleware components where any piece of information - whether needed or not - is stored inside a central +repository (which is still available as an optional component of the IoT Broker). * The IoT Broker has the ability to automatically translate information to the right abstraction level and therefore closes the gap between information-centric applications and device-centric IoT installations. For example, a simple device can typically only deliver values without being aware of the meaning of these values @@ -59,48 +63,34 @@ The main features of IoT Broker are: Directory Structure ------------------------ -. -├── iotplatform.couchdb Optional bundle for - connection with - couchDB - -├── iotbroker.builder Maven builder - -├── iotbroker.client HTTP client - -├── iotbroker.commons Commons package for - basic functionalities - -├── iotbroker.core Functional core - -├── iotbroker.resultfilter Optional bundle for - filtering results - -├── iotbroker.restcontroller HTTP REST interface - -├── iotbroker.storage Connector to internal - database - -├── ngsi.api Implementation of - FIWARE NGSI API - -├── fiwareRelease Configuration folder - used by IoT Broker - bundles during - runtime - -├── IoTbrokerParent Maven parent project - -├── lib Folder contains OSGI - bundles needed by - IoT Broker to run - -├── SQL_database HSQLDB folder containing - the internal IoT Broker - database files. - -└── tomcat-configuration-fragment Tomcat server configuration +Most of the below sub-directories are containing source code for OSGi bundles the IoT Broker +runs with. Some of these bundles are required for a working installation of IoT Broker; others +are implementing optional features and do not need to be deployed when these features are not +needed. In addition, this repository also contains an OSGi runtime environment and pre-configured +startup script for the IoT Broker, as well as a blackbox test utility for testing a running IoT Broker +instance. + +|Directory | Contents| +|---------------------|---------| +| ├── eu.neclab.iotplatform.couchdb | Optional bundle for connection with a couchDB database for storing and retrieving context information.| +| ├── eu.neclab.iotplatform.entitycomposer | Optional bundle for connection with a couchDB database for storing and retrieving context information. | +|├── eu.neclab.iotplatform.iotbroker.builder | Maven builder project compiling all required and optional IoT Broker OSGi bundles.| +|├── eu.neclab.iotplatform.iotbroker.client | Required bundle for the HTTP client used by IoT Broker. | +|├── eu.neclab.iotplatform.iotbroker.commons | Required bundle for basic IoT Broker functionalities. | +|├── eu.neclab.iotplatform.iotbroker.core | Required bundle containing the functional core of the IoT Broker. | +|├── eu.neclab.iotplatform.iotbroker.ext.resultfilter |Optional bundle for filtering results. Deploying this bundle will effectuate that faulty query responses from IoT data sources are not forwarded to IoT applications.| +|├── eu.neclab.iotplatform.iotbroker.restcontroller | Required bundle implementing the HTTP REST interface of the IoT Broker.| +|├── eu.neclab.iotplatform.iotbroker.storage | Required bundle to setup and connect to an internal database. Note that this database only used to store state information on data subscriptions and does not store any context data. For storing context data, please use the optional bundle eu.neclab.iotplatform.couchdb.| +|├── eu.neclab.iotplatform.ngsi.api | Required bundle containing the libraries implementing the FIWARE NGSI data model.| +|├── fiwareRelease | Configuration folder used by IoT Broker bundles at runtime. This folder is referenced by the runtime environment in the "IoTBroker-runner" folder.| +| ├── IoTbrokerParent |Maven parent project.| +|├── IoTBroker-runner | Pre-configured runtime environment for IoT Broker, based on the Equinox OSGi implementation.| +|├── iotplatform.iotbroker.blackboxtest | Maven project for a blackbox test based on JUNIT. This can be used to test a running instance of IoT Broker. The tests require the running instance to include some optional bundles included by this release.| +|├── lib |Folder contains some OSGI bundles needed by IoT Broker to run.| +|├── SQL_database | HSQLDB folder containing internal IoT Broker database files.| +|├── targetPlatform| Contains the OSGi bundles needed for the IoT Broker at runtime. These bundles are pre-configured to be loaded by the runtime environment in the "IoTBroker-runner" folder.| +|└── tomcat-configuration-fragment | Required bundle for tomcat server configuration.| Building IoT Broker Source Code @@ -114,168 +104,80 @@ for being built: The basic procedure for compiling the IoT Broker is the following: -Navigate into the IoTBrokerParent folder and compile the pom file as follows: +**Build the parent:** Navigate into the IoTBrokerParent folder and compile the pom file as follows: ``` mvn install ``` -* The next step is to build the IoT Broker. Navigate into the eu.neclab.iotplatform.iotbroker.builder folder and use Maven for compiling the pom file: +**Build the IoT broker bundles:** Navigate into the eu.neclab.iotplatform.iotbroker.builder folder and use Maven for compiling the pom file: ``` mvn install ``` - This command will generate 9 OSGI bundles inside the eu.neclab.iotplatform.iotbroker.builder\target folder: + This command will generate 10 OSGI bundles inside the *eu.neclab.iotplatform.iotbroker.builder\target* folder: (Note that the version numbers might differ from what is written in this document.) ``` -iotbroker.client-4.3.3.jar -iotbroker.commons-4.3.3.jar -iotbroker.core-4.3.3.jar -iotbroker.couchdb-4.3.3.jar -iotbroker.ext.resultfilter-4.3.3.jar -iotbroker.restcontroller-4.3.3.jar -iotbroker.storage-4.3.3.jar -ngsi.api-4.3.3.jar -tomcat-configuration-fragment-4.3.3.jar +entitycomposer-4.4.3.jar +iotbroker.client-4.4.3.jar +iotbroker.commons-4.4.3.jar +iotbroker.core-4.4.3.jar +iotbroker.couchdb-4.4.3.jar +iotbroker.ext.resultfilter-4.4.3.jar +iotbroker.restcontroller-4.4.3.jar +iotbroker.storage-4.4.3.jar +ngsi.api-4.4.3.jar +tomcat-configuration-fragment-4.4.3.jar ``` -How to Use the IoT Broker Bundles +How to Use the IoT Broker Bundles in general --- The Iot Broker bundles are OSGI based and can be used with arbitrary OSGI frameworks like EQUINOX, FELIX, etc. The IoT Broker OSGI bundles have been tested with the EQUINOX and the FELIX framework. IoT Broker requires several VM arguments for the runtime that need to be specified (e.g. in Equinox modify the config.ini file): -* dir.config=/user/home (parent directory of the fiwareRelease folder) +* dir.config=/user/home (parent directory of the fiwareRelease folder (absolute path needed)) * bundles.configuration.location=.//fiwareRelease//configuration//configadmin (Location of the logger configuration file) * ngsiclient.layer=connector (Needed for binding the right http bundle) * hsqldb.directory=.//SQL_database/database (Location of the HSQLDB database) -* tomcat.init.port=8090 (the port the IoT Broker REST Interface will be listening to) +* tomcat.init.port=80 (the port the IoT Broker REST Interface will be listening to) -In addition to that, the fiwareRelease folder needs to be copied in the user/home directory (or to the folder specified by dir.config). +In addition to that, the fiwareRelease folder needs to be copied e.g. into the user/home directory (or to the folder specified by dir.config). -An example of an OSGI configuration using the EQUINOX framework (e.g. config.ini) is shown below. For a working example configuration please also see the latest binary release to be found in http://catalogue.fiware.org/enablers/iot-broker. +For example of an OSGI configuration using the EQUINOX framework (e.g. config.ini), please refer to the *IoTBroker-runner* folder. -One of the most simple ways to compile and run your custom version of IoT Broker is to (a) do the modifications of the source code as desired (b) compile the IoT Broker OSGi bundles, (c) replace in a recent binary release of IoT Broker (see http://catalogue.fiware.org/enablers/iot-broker) the IoT Broker bundles by your new custom bundles. +Using the runtime environment included by this repository +--- -``` -############################## -# Equinox settings -############################## -eclipse.ignoreApp=true -osgi.clean=true -osgi.noShutdown=true -osgi.bundles.defaultStartLevel=4 -osgi.java.profile=java6-server.profile -osgi.java.profile.bootdelegation=override -# PaxLogging configuration folder (absolute path) -bundles.configuration.location=//root//IoTBroker_4.3.3//fiwareRelease//iotbrokerconfig//bundleConfigurations -# IoT Broker Server port -tomcat.init.port=80 -# Internal Database folder -hsqldb.directory=.//SQL_database//database//linkDB -# Internal Database port -hsqldb.port=9001 -# Enable the Database Logs -hsqldb.silent=false -# Absolute path to the config folder -dir.config=//root//IoTBroker_4.3.3//fiwareRelease// -ngsiclient.layer=connector -java.awt.headless=true -file.encoding=UTF-8 --server -Xms2048m -Xmx2048m --XX:NewSize=1024m -XX:MaxNewSize=1024m -XX:PermSize=1024m --XX:MaxPermSize=1024m -XX:+DisableExplicitGC -############################## -# Client bundles to install -############################## -osgi.bundles= plugins/equinox/org.eclipse.core.contenttype-3.4.100.v20100505-1235.jar@start, \ -plugins/equinox/org.eclipse.equinox.common-3.6.0.v20110506.jar@2:start, \ -plugins/equinox/org.eclipse.core.jobs-3.5.0.v20100515.jar@start, \ -plugins/equinox/org.eclipse.equinox.app-1.3.0.v20100512.jar@start, \ -plugins/equinox/org.eclipse.equinox.preferences-3.3.0.v20100503.jar@start, \ -plugins/equinox/org.eclipse.equinox.registry-3.5.0.v20100503.jar@start, \ -plugins/equinox/org.eclipse.osgi.services-3.2.100.v20100503.jar@start, \ -plugins/equinox/org.eclipse.equinox.cm_3.2.0.v20070116.jar@1:start, \ -plugins/pax/pax-confman-propsloader-0.2.2.jar@2:start, \ -plugins/pax/pax-logging-api-1.7.0-20120710.130402-38.jar@2:start, \ -plugins/pax/pax-logging-service-1.7.0-20120710.130445-38.jar@2:start, \ -plugins/bundles/com.springsource.javax.activation-1.1.1.jar@start, \ -plugins/bundles/javax.persistence-2.0.0.jar@start, \ -plugins/bundles/httpclient-4.2.0-osgi.jar@start, \ -plugins/bundles/httpcore-4.2.0-osgi.jar@start, \ -plugins/bundles/com.springsource.org.apache.commons.io-1.4.0.jar, \ -plugins/bundles/com.springsource.org.apache.commons.codec-1.6.0.jar@start, \ -plugins/bundles/com.springsource.javax.annotation-1.0.0.jar@start, \ -plugins/bundles/com.springsource.javax.ejb-3.0.0.jar@start, \ -plugins/bundles/com.springsource.javax.el-1.0.0.jar@start, \ -plugins/bundles/com.springsource.javax.mail-1.4.0.jar@start, \ -plugins/bundles/com.springsource.javax.persistence-1.0.0.jar@start, \ -plugins/bundles/com.springsource.javax.servlet.jsp.jstl-1.1.2.jar@start, \ -plugins/bundles/com.springsource.javax.servlet.jsp-2.1.0.jar@start, \ -plugins/bundles/com.springsource.javax.servlet-2.5.0.jar@start, \ -plugins/bundles/com.springsource.javax.xml.bind-2.0.0.jar@start, \ -plugins/bundles/com.springsource.javax.xml.stream-1.0.1.jar@start, \ -plugins/bundles/com.springsource.javax.xml.rpc-1.1.0.jar@start, \ -plugins/bundles/com.springsource.javax.xml.soap-1.3.0.jar@start, \ -plugins/bundles/com.springsource.javax.xml.ws-2.1.1.jar@start, \ -plugins/bundles/com.springsource.org.aopalliance-1.0.0.jar@start, \ -plugins/bundles/com.springsource.org.apache.catalina-6.0.18.jar@start, \ -plugins/bundles/com.springsource.org.apache.coyote-6.0.18.jar, \ -plugins/bundles/com.springsource.org.apache.el-6.0.18.jar@start, \ -plugins/bundles/com.springsource.org.apache.juli.extras-6.0.18.jar@start, \ -plugins/bundles/com.springsource.org.apache.taglibs.standard-1.1.2.jar@start, \ -plugins/bundles/catalina.start.osgi-1.0.0.jar@start, \ -plugins/bundles/jasper.osgi-5.5.23-SNAPSHOT.jar@start, \ -plugins/bundles/catalina-config-3.5.1.jar, \ -plugins/jaxb/jaxb-impl-2.1.5_1.0.0.jar@start, \ -plugins/db/hsqldb_1.0.0.jar@start, \ -plugins/json/org.json_1.0.0.jar@start, \ -plugins/json/gson-2.2.2.jar@start, \ -plugins/json/jackson-core-asl-1.9.2.jar@start, \ -plugins/json/jackson-mapper-asl-1.9.2.jar@start, \ -plugins/spring 3.2.3/org.springframework.aop-3.2.3.RELEASE.jar@start, \ -plugins/spring 3.2.3/org.springframework.aspects-3.2.3.RELEASE.jar@start, \ -plugins/spring 3.2.3/org.springframework.beans-3.2.3.RELEASE.jar@start, \ -plugins/spring 3.2.3/org.springframework.context.support-3.2.3.RELEASE.jar@start, \ -plugins/spring 3.2.3/org.springframework.context-3.2.3.RELEASE.jar@start, \ -plugins/spring 3.2.3/org.springframework.core-3.2.3.RELEASE.jar@start, \ -plugins/spring 3.2.3/org.springframework.expression-3.2.3.RELEASE.jar@start, \ -plugins/spring 3.2.3/org.springframework.jdbc-3.2.3.RELEASE.jar@start, \ -plugins/spring 3.2.3/org.springframework.orm-3.2.3.RELEASE.jar@start, \ -plugins/spring 3.2.3/org.springframework.oxm-3.2.3.RELEASE.jar@start, \ -plugins/spring 3.2.3/org.springframework.transaction-3.2.3.RELEASE.jar@start, \ -plugins/spring 3.2.3/org.springframework.web.servlet-3.2.3.RELEASE.jar@start, \ -plugins/spring 3.2.3/org.springframework.web-3.2.3.RELEASE.jar@start, \ -plugins/spring 3.2.3/org.springframework.security.config-3.1.4.RELEASE.jar@start, \ -plugins/spring 3.2.3/org.springframework.security.core-3.1.4.RELEASE.jar@start, \ -plugins/spring 3.2.3/org.springframework.security.web-3.1.4.RELEASE.jar@start, \ -plugins/spring DM/spring-osgi-annotation-2.0.0.M1.jar@start, \ -plugins/spring DM/spring-osgi-core-2.0.0.M1.jar@start, \ -plugins/spring DM/spring-osgi-extender-2.0.0.M1.jar@start, \ -plugins/spring DM/spring-osgi-io-2.0.0.M1.jar@start, \ -plugins/spring DM/spring-osgi-web-2.0.0.M1.jar@start, \ -plugins/spring DM/spring-osgi-web-extender-2.0.0.M1.jar@start, \ -plugins/monitor/javamelodybundle_1.0.0.jar@start, \ -plugins/monitor/jrobin_1.5.9.1.jar@start, \ -plugins/bundles/guava-18.0.jar@start, \ -plugins/broker/iotbroker.commons-4.3.3.jar@start, \ -plugins/broker/iotbroker.storage-4.3.3.jar@start, \ -plugins/broker/iotbroker.client-4.3.3.jar@start, \ -plugins/broker/iotbroker.core-4.3.3.jar@start, \ -plugins/broker/iotbroker.restcontroller-4.3.3.jar@start, \ -plugins/broker/ngsi.api-4.3.3.jar@start, \ -plugins/broker/iotbroker.ext.resultfilter-4.3.3.jar@start, \ -plugins/broker/tomcat-configuration-fragment-4.3.3.jar, \ -plugins/broker/iotbroker.couchdb-4.3.3.jar@start -``` +This repository contains a complete runtime environment for the IoT Broker. In the *IoTBroker-runner* folder you can find the Equinox OSGi environment together with its configuration file. The configuration files contains references the *fiwareRelease* folder, to the bundles in the *targetPlatform* folder, as well as to the IoT Broker bundles that can be found in the *eu.neclab.iotplatform.iotbroker.builder/target* folder after having successfully compiled the bundles. + +To arrive at a running IoT Broker installation, the following steps need to be completed: +1. Compile the IoT Broker bundles as described above +2. Open the file *IoTBroker-runner/configuration/config.ini*. The parameter *dir.config* needs to be changed so that it points inside +the location of the *fiwareRelease* folder. For example, if this project has been cloned to C:\Aeron on a Windows machine, then the +line has to be changed to *dir.config=C://Aeron//fiwareRelease*. +3. Run the IoT Broker by running one of the startup scripts for Windows or Unix in the *IoTBroker-runner* folder. + +Using the Black Box Test +--- +While individual classes of the IoT Broker are already tested during compilation with Maven, the project *iotplatform.iotbroker.blackboxtest* is a dedicated black box test for a running instance of the IoT Broker using server mocks. It is based on the JUNIT-Framework. +These tests assume that the IoT Broker is listening to port 80 and communicates with an IoT Discovery component at port 8002 on localhost. This corresponds to the default configuration. + +To run the tests, navigate to the directory *iotplatform.iotbroker.blackboxtest* and compile the project by the command -Installing and Using the IoT Broker +''' +mvn test +''' + +The IoT Broker instance should be already running at the time of compilation. Please note that a deployment of IoT Broker including at least all bundles loaded by the pre-configured OSGi environment ('IoTBroker-runner' folder) is necessary for the tests to run successfully. + +Minimum System Requirements --- Minimum System Requirements: @@ -285,16 +187,6 @@ Minimum System Requirements: * JAVA : Java 7 * Operating System: 32 or 64-bit version Windows or Linux -The administration and programming manuals for the IoT Broker can be found on the FIWARE Catalogue page, -under the "Documentation" tab. - -User and Programmers Guide: https://forge.fi-ware.org/plugins/mediawiki/wiki/fiware/index.php/IoT_Broker_-_User_and_Programmers_Guide - -Installation and Administration Guide: https://forge.fi-ware.org/plugins/mediawiki/wiki/fiware/index.php/IoT_Broker_-_Installation_and_Administration_Guide - -Pre-compiled and configured binaries: -http://catalogue.fiware.org/enablers/iot-broker - Bugs & Questions --- diff --git a/doc/apiary-doc.apib b/doc/apiary-doc.apib deleted file mode 100644 index 8086bd65..00000000 --- a/doc/apiary-doc.apib +++ /dev/null @@ -1,1123 +0,0 @@ -FORMAT: 1A -HOST: http://polls.apiblueprint.org/ - -# IoT Broker NGSI data Interface - -The information exchange between the IoT Broker and other components is -based on the FIWARE NGSI standards. Therefore, for readers familiar with -FIWARE NGSI, this manual does not contain a lot of new information. - -For the formal specification documents, please refer to -this archive. - -## NGSI Context Management Information Model - -### Entities -The central aspect of the FIWARE NGSI information model is the concept -of 'entities'. Entities are the virtual representation of all kinds -of physical objects in the real world. Examples for physical entities -are tables, rooms, or persons. Virtual entities have an identifier -and a type. For example, a virtual entity representing a person -named “John” could have the identifier “John” and the type “person”. - -### Attributes -Any information about physical entities is expressed in the -form of 'attributes' of virtual entities. Attributes have a name -and a type as well. For example, the body temperature of John would -be represented as an attribute having the name “body_temperature” and -the type “temperature”. Values of such attributes are contained by -value containers. This kind of container does not only consist of -the actual attribute value, but also contains a set of metadata. -Metadata is data about data; in in our body temperature example this -metadata could represent the time of measurement, the measurement unit, -and other information about the attribute value. - -### Attribute Domains -There also is a concept of 'attribute domains' in version 1.0 of -FIWARE NGSI. An attribute domain logically groups together a set of -attributes. For example, the attribute domain "health_status" -could comprise of the attributes "body_temperature" and -"blood_pressure". - -Please note that the attribute domains features is likely to become -deprecated in future versions of FIWARE NGSI. - -### Context Elements - -The data structure used for exchanging information about entities is -'context element'. A context element contains information about multiple -attributes of one entity. The domain of these attributes can also be -specified inside the context element; in this case all provided -attribute values have to belong to that domain. - -Formally, a context element contains the following information: -* an entity id and type -* a list of triplets holding information about attributes of the entity -* (optionally) the name of an attribute domain -* (optionally) a list of triplets that apply to all attribute values of the given domain - - -### NGSI Context Management Interfaces - -FIWARE NGSI defines two interfaces for exchanging information based -on the information model. The NGSI-10 is the 'data interface', -used for exchanging information about entities and their attribute, -i.e., attribute values and metadata. The NGSI-9 is the 'availability -interface'; used for -'availability' information about entities and their attributes. -Here, instead of exchanging attribute values, information about -which provider can provide which context information is exchanged. - -Please note that NGSI-9 and NGSI-10 represent different functionalities -and are not different versions of the same interface. To avoid -confusion, it is likely that in the future the names 'NGSI-10' and 'NGSI-10' -will be replaced by more meaningful names. - -### About this guide - -The IoT Broker GE, being a data broker, mainly uses NGSI 10. This -interface is used both for exchanging data between data consumers -and the IoT Broker, and for exchanging data between the IoT Broker and -data providers. - -The IoT Broker additionally uses NGSI 9 for -communicating with an instance of the IoT Discovery GE in order to -get information about the addresses of data providers matching the -requests of the data consumers. The NGSI-9 interface used in this -communication is mainly specified in the documentation of the IoT -Discovery GE (http://docs.ngsi9.apiary.io/#). - -While this guide describes the message formats and service endpoints, -please refer to the IoT Broker Open Specification -(https://forge.fiware.org/plugins/mediawiki/wiki/fiware/index.php/FIWARE.OpenSpecification.IoT.Backend.IoTBroker) -for details about the IoT Broker data flows. - -# Data exchange via FIWARE NGSI-10 standard operations and convenience operation. - -FIWARE NGSI-10 supports a direct XML-representation of the NGSI-10 -operations that were defined in the OMA specification of NGSI-10. These operations -can be invoked by issuing a POST request on HTTP resources that -correspond to the respective operation.Any possible interaction with the IoT Broker can be done using these -six standard operations. - -In addition, FIWARE NGSI defines also a set of -operations for simplified interaction with data providers. These operations -are called 'convenience operations'. They are redundant in the sense -that the same results could be achieved as well by using only standard -operations instead, so they only exist for the sake of convenience. For -example, all information about a specific context entity can be -retrieved by a HTTP GET on a convenience resource representing -that context entity, while with standard operations the user would -have to fomulate a request message in the right format and -submit it to the generic query resource using HTTP POST. - -Below the standard operations defined by NGSI 10 are described, followed -by the convenience operations. - -## Standard Context Query [/ngsi10/queryContext] - -Generic queries for context information. The expected request body -is an instance of queryContextRequest; the response body is an -instance of queryContextResponse. - -### Issue a context query [POST] - -+ Request (application/xml) - - - - - - ConferenceRoom - - - - temperature - - - -+ Response 400 (application/xml) - - - - - - 404 - CONTEXT ELEMENT NOT FOUND - - - -+ Response 200 (application/xml) - - - - - - - - ConferenceRoom - - - - indoorTemperature - Room - 6 - - - ID - string - 1110 - - - - - - - 200 - Ok - - - - - -## Standard Context Subscription [/ngsi10/subscribeContext] - -Generic subscriptions for context information. The expected -request body is an instance of subscribeContextRequest; the -response body is an instance of subscribeContextResponse. - -### Issue a context subscription [POST] - -+ Request (application/xml) - - - - - - ConferenceRoom - - - - temperature - - 127.0.0.1 - P5M - - someXPATH - - - someScopeType - someScopeValue - - - - - - ONCHANGE - - P5M - - -+ Response 400 (application/xml) - - - - - - - 500 - Subscription Error -
Internal Error
-
-
-
- -+ Response 200 (application/xml) - - - - - 12345 - P5Y - P5Y - - - -## Standard Context Subscription Update [/ngsi10/updateContextSubscription] - -Generic update of context subscriptions. The expected request body -is an instance of updateContexSubscriptiontRequest; the response body -is an instance of updateContextSubscriptionResponse. - -### Issue a context subscription update [POST] - -+ Request (application/xml) - - - - P5Y - - - - - myScopeType - myScopeValue - - - -+ Response 400 (application/xml) - - - - - 12345 - - 404 - Subscription ID not found -
Internal Error
-
-
-
- -+ Response 200 (application/xml) - - - - - 12345 - P5Y - P1D - - - -## Standard Context Subscription Cancellation [/ngsi10/unsubscribeContext] - -Generic unsubscribe operations. The expected request body is an -instance of unsubscribeContextRequest; the response body is an -instance of unsubscribeContextResponse. - -### Unsubscribe [POST] - -+ Request (application/xml) - - - - 1245 - - -+ Response 200 (application/xml) - - - - 12345 - - 200 - OK - - - - -+ Response 400 (application/xml) - - - - 12345 - - 404 - Subscription ID not found -
Internal Error
-
-
- -## Standard Context Notification [/ngsi10/notifyContext] - -Notification operation to send context data matching a previous -subscription. The expected request body is an instance of -notifyContextRequest; the response body is an instance of -notifyContextResponse. - -### Notify [POST] - -+ Request (application/xml) - - - - 12345 - http://localhost/test - - - - - ConferenceRoom - - - - temperature - Room - 10 - - - ID - string - 1110 - - - - - - - 200 - Ok - - - - - -+ Response 200 (application/xml) - - - - - 200 - Ok - - - -## Standard Context Data Push [/ngsi10/updateContext] - -Generic context updates. The expected request body is an instance of -updateContextRequest; the response body is an instance of -updateContextResponse. - -### Update context data [POST] - -+ Request (application/xml) - - - - - - - ConferenceRoom - - - - temperature - degree - 20 - - - ID - long - 1 - - - - - - - - UPDATE - - -+ Response 200 (application/xml) - - - - - - - - ConferenceRoom - - - - temperature - - - - - 200 - Ok - - - - - - -## Convenience Interaction with Individual Context Entity [/ngsi10/contextEntities/ConferenceRoom/] - -### Retrieve all entity information [GET] - -+ Response 200 (application/xml) - - - - - - ConferenceRoom - - - - indoorTemperature - Room - 6 - - - ID - string - 1110 - - - - - - - 200 - Ok -
a
-
-
- - -### Replace a number of attribute values [PUT] - -+ Request (application/xml) - - - - - - temperature - degree - 10 - - - ID - string - 1110 - - - - - humidity - percentage - 70 - - - ID - string - 2312 - - - - - - -+ Response 200 (application/xml) - - - - - - - temperature - degree - - - humidity - percentage - - - - 200 - Ok - - - - -+ Response 400 (application/xml) - - - - - 404 - Context Element not Found -
No Attribute with given value IDs found
-
-
- -### Append context attribute values [POST] - -+ Request (application/xml) - - - - - - temperature - degree - 10 - - - ID - string - 1110 - - - - - humidity - percentage - 70 - - - ID - string - 2312 - - - - - - -+ Response 200 (application/xml) - - - - - - - temperature - degree - 10 - - - ID - string - 1110 - - - - - humidity - percentage - 70 - - - ID - string - 2312 - - - - - - 200 - Ok - - - - -+ Response 400 (application/xml) - - - - - 500 - Internal Error - - - -### Delete all entity information [DELETE] - -+ Response 200 (application/xml) - - - - 200 - Ok - - -+ Response 400 (application/xml) - - - - 404 - Context Element not found - - -## Convenience Interaction with an Individual Attribute of an Individual Entity [/ngsi10/contextEntities/ConferenceRoom/attributes/temperature] - -### Retrieve attribute values [GET] - -+ Response 200 (application/xml) - - - - - - temperature - degree - 10 - - - ID - string - 1110 - - - - - temperature - degree - 12 - - - ID - string - 4837 - - - - - - 200 - OK - - - -### Append context attribute value [POST] - -+ Request (application/xml) - - - - degree - 10 - - - ID - string - 1110 - - - - -+ Response 200 (application/xml) - - - - 200 - Ok - - - -### Delete all values of attribute [DELETE] - -+ Response 200 (application/xml) - - - - 200 - Ok - - -## Convenience Interaction with an Individual Attribute Value Instance of an Individual Entity [/ngsi10/contextEntities/ConferenceRoom/attributes/temperature/id77] - -### Retrieve attribute value and associated metadata [GET] - -+ Response 200 (application/xml) - - - - - - temperature - degree - - - - 200 - OK - - - -+ Response 400 (application/xml) - - - - - - temperature - - - - 404 - Not Found -
Value ID id77 not found.
-
-
- -### Replace context attribute value [PUT] - -+ Request (application/xml) - - - - degree - 10 - - -+ Response 200 (application/xml) - - - - 200 - Ok - - -### Delete all value attribute [DELETE] - -+ Response 200 (application/xml) - - - - 200 - Ok - - -## Convenience Interaction with Attribute Domain of Individual Entity [/ngsi10/contextEntities/ConferenceRoom/attributeDomain/roomInfo] - -### Retrieve all attribute information belonging to attribute domain [GET] - -+ Response 200 (application/xml) - - - - - - temperature - degree - 10 - - - ID - string - 1110 - - - - - humidity - percentage - 70 - - - ID - string - 2312 - - - - - - 200 - Ok - - - -## Convenience Interaction with Entity Type [/ngsi10/contextEntityTypes/Room] - -### Retrieve all context information about entities of specified type [GET] - -+ Response 200 (application/xml) - - - - - - - - ConferenceRoom - - - - indoorTemperature - degree - 6 - - - ID - string - 1110 - - - - - - - 200 - Ok - - - - - - Office - - - - humidity - percentage - 70 - - - - - 200 - Ok - - - - - - -## Convenience Interaction with Attribute of Entity Type [/ngsi10/contextEntityTypes/Room/attributes/indoorTemperature] - -### Retrieve all values of specified attribute of the context entities of the specific type [GET] - -+ Response 200 (application/xml) - - - - - - - - ConferenceRoom - - - - indoorTemperature - degree - 6 - - - ID - string - 1110 - - - - - - - 200 - Ok - - - - - - Office - - - - indoorTemperature - degree - 13 - - - - - 200 - Ok - - - - - - -## Convenience Interaction with Attribute Domain of Entity Type [/ngsi10/contextEntityTypes/Room/attributeDomains/roomInfo] - -### For all context entities of the specific type, retrieve the values of all attributes belonging to the attribute domain [GET] - -+ Response 200 (application/xml) - - - - - - - - ConferenceRoom - - - - indoorTemperature - degree - 6 - - - ID - string - 1110 - - - - - humidity - percentage - 70 - - - - - 200 - Ok - - - - - - Office - - - - indoorTemperature - degree - 13 - - - - - 200 - Ok - - - - - -## Convenience Subscription Container [/ngsi10/contextSubscriptions] - -### Create a new subscription [POST] - -+ Request (application/xml) - - - - - - ConferenceRoom - - - - temperature - - 127.0.0.1 - P5Y - - someXPATH - - - someScopeType - someScopeValue - - - - - - ONCHANGE - - P5Y - - -+ Response 400 (application/xml) - - - - - - - 400 - Subscription Error -
Internal Error
-
-
-
- -+ Response 200 (application/xml) - - - - - 123 - P5Y - P5Y - - - -## Convenience Interaction with individual subscription [/ngsi10/contextSubscriptions/12345] - -### Update subscription [PUT] - -+ Request (application/xml) - - - - P5Y - - -+ Response 400 (application/xml) - - - - - 12345 - - 404 - Subscription ID not found - - - - -+ Response 200 (application/xml) - - - - - 12345 - P5Y - P1D - - - -### Cancel subscription [DELETE] - -+ Response 200 (application/xml) - - - - 12345 - - 200 - OK - - - - -+ Response 400 (application/xml) - - - - 12345 - - 404 - Subscription ID not found -
Internal Error
-
-
- - - diff --git a/eu.neclab.iotplatform.couchdb/pom.xml b/eu.neclab.iotplatform.couchdb/pom.xml index 10efdd36..5988ed4e 100644 --- a/eu.neclab.iotplatform.couchdb/pom.xml +++ b/eu.neclab.iotplatform.couchdb/pom.xml @@ -4,7 +4,7 @@ IoTbrokerParent eu.neclab.iotplatform - 4.3.3 + 4.4.3 ../IoTbrokerParent diff --git a/eu.neclab.iotplatform.entitycomposer/META-INF/spring/entitycomposer-context.xml b/eu.neclab.iotplatform.entitycomposer/META-INF/spring/entitycomposer-context.xml new file mode 100644 index 00000000..eec27b94 --- /dev/null +++ b/eu.neclab.iotplatform.entitycomposer/META-INF/spring/entitycomposer-context.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + diff --git a/eu.neclab.iotplatform.entitycomposer/META-INF/spring/entitycomposer-osgi.xml b/eu.neclab.iotplatform.entitycomposer/META-INF/spring/entitycomposer-osgi.xml new file mode 100644 index 00000000..add56e29 --- /dev/null +++ b/eu.neclab.iotplatform.entitycomposer/META-INF/spring/entitycomposer-osgi.xml @@ -0,0 +1,16 @@ + + + + + + + + \ No newline at end of file diff --git a/eu.neclab.iotplatform.entitycomposer/pom.xml b/eu.neclab.iotplatform.entitycomposer/pom.xml new file mode 100644 index 00000000..cb14a24f --- /dev/null +++ b/eu.neclab.iotplatform.entitycomposer/pom.xml @@ -0,0 +1,49 @@ + + 4.0.0 + + + IoTbrokerParent + eu.neclab.iotplatform + 4.4.3 + ../IoTbrokerParent + + + entitycomposer + eu.neclab.iotplatform.entitycomposer + bundle + + + + + src/main/resources + + + . + + META-INF/** + + + + + + org.apache.felix + maven-bundle-plugin + true + + META-INF + + + + + + + eu.neclab.iotplatform + ngsi.api + + + eu.neclab.iotplatform + iotbroker.commons + + + diff --git a/eu.neclab.iotplatform.entitycomposer/src/main/java/eu/neclab/iotplatform/entitycomposer/CompositeEntityQueryService.java b/eu.neclab.iotplatform.entitycomposer/src/main/java/eu/neclab/iotplatform/entitycomposer/CompositeEntityQueryService.java new file mode 100644 index 00000000..ddd24210 --- /dev/null +++ b/eu.neclab.iotplatform.entitycomposer/src/main/java/eu/neclab/iotplatform/entitycomposer/CompositeEntityQueryService.java @@ -0,0 +1,245 @@ +package eu.neclab.iotplatform.entitycomposer; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import org.apache.log4j.Logger; + +import eu.neclab.iotplatform.entitycomposer.datamodel.AggregationSourceInformation; +import eu.neclab.iotplatform.entitycomposer.datamodel.EntityAggregationInfo; +import eu.neclab.iotplatform.entitycomposer.datamodel.SourceInfoContextMetadata; +import eu.neclab.iotplatform.iotbroker.commons.interfaces.QueryService; +import eu.neclab.iotplatform.ngsi.api.datamodel.ContextElementResponse; +import eu.neclab.iotplatform.ngsi.api.datamodel.ContextMetadata; +import eu.neclab.iotplatform.ngsi.api.datamodel.ContextRegistration; +import eu.neclab.iotplatform.ngsi.api.datamodel.EntityId; +import eu.neclab.iotplatform.ngsi.api.datamodel.QueryContextRequest; +import eu.neclab.iotplatform.ngsi.api.datamodel.QueryContextResponse; +import eu.neclab.iotplatform.ngsi.api.datamodel.SourceInformation; +import eu.neclab.iotplatform.ngsi.api.ngsi10.Ngsi10Interface; + +/** + * This class is responsible for composing entities from other entities + * by means of aggregation functions. + * + * After resolving the associations it goes back to the IoT Broker core + * to retrieve information on the source entities it needs to compose + * the target entity. + */ +public class CompositeEntityQueryService implements QueryService{ + + private static final String SOURCE_INFORMATION_TYPENAME = "org.fiware.type.metadata.sourceinformation"; + private static final String AGGREGATION_TYPENAME = "org.fiware.type.sourceinformation.aggregation"; + + //pointer to IoT Broker core; expected to be autowired + Ngsi10Interface iotBrokerCore; + + public Ngsi10Interface getIotBrokerCore() { + return iotBrokerCore; + } + + public void setIotBrokerCore(Ngsi10Interface iotBrokerCore) { + this.iotBrokerCore = iotBrokerCore; + } + + Logger logger = Logger.getLogger(this.getClass()); + + /** Executor for asynchronous tasks */ + private final ExecutorService taskExecutor = Executors + .newCachedThreadPool(); + + @Override + public QueryContextResponse queryContext(QueryContextRequest req, List regList) { + + logger.info("started composite entity query service"); + + /* + * Pull the relevant assembly information out of the registration metadata. + */ + if(regList==null) return null; //no registrations -> nothing to assemble + + List entityAggrInfoList = new ArrayList(0); + + for(ContextRegistration reg:regList){ + if(reg.getListContextMetadata() == null) continue; //no metadata --> nothing to assemble + for(ContextMetadata metadata:reg.getListContextMetadata()){ + if(metadata.getType().toString().equals(SOURCE_INFORMATION_TYPENAME)) + { + /* + * metadata is on source information; now we need to figure out whether + * the source information type is org.fiware.org.sourceinformation.aggregation + */ + + SourceInformation sI; + try{ + sI = SourceInfoContextMetadata.getValueAsSourceInfo(metadata); + } catch(Exception e){ + logger.info("problem interpreting metadata " + + "as source information:\n" + metadata.toString()); + logger.info("Message:"+e.getMessage()); + continue; + } + + if(!sI.getSourceType().toString().equals(AGGREGATION_TYPENAME)) + continue; //wrong source information type + + /* + * Yeah, now we found in a piece of metadata source information + * of type aggregation info. We add the aggregation info + * to our list. + */ + + EntityAggregationInfo entAggInfo; + try{ + entAggInfo = AggregationSourceInformation.getValueAsAggrInfo(sI); + } catch (Exception e){ + logger.info("problem interpreting source information " + + "as aggregation info:\n" + sI.toString()); + logger.info("Message:"+e.getMessage()); + continue; + } + + entityAggrInfoList.add(entAggInfo); + } + + } //end of iteration over metadata + + } //end of iteration over registrations + + if(entityAggrInfoList.isEmpty()) return null; //again, nothing there to aggregate means nothing to do. + + /* + * Now that we found some entity aggregation information, we create the + * aggregator objects that do the actual aggregation. + */ + List entAggList = new ArrayList(entityAggrInfoList.size()); + for(EntityAggregationInfo entAggInfo:entityAggrInfoList) + try { + entAggList.add(new EntityAggregator(entAggInfo,req.getEntityIdList(),req.getAttributeList())); + } catch (NotRequestedException e1) { + //Aggregation information seems not relevant for what was queried; + //do nothing. + } + + /* + * And now, having the objects that do the aggregation, we need to retrieve + * the source entity information. + */ + + /* + * Here we collect the tasks that will submit queries + * to the IoT Broker core + */ + List> tasks = new ArrayList>(); + + /* + * And here we collect all the responses AFTER the aggregation process. + */ + final List responseList = new ArrayList(); + + /* + * We define a class for runnable objects that will + * - query the IoT Broker core on behalf of the aggregator object + * - submit the result to the aggregator object + * - fetch the aggregated information from the object and put it + * into the response list. + */ + class aggregationThread implements Runnable{ + + EntityAggregator entAgg; + + public aggregationThread(EntityAggregator entAgg) + { + this.entAgg = entAgg; + } + + @Override + public void run() { + + /* + * Get from the entityAggregator the entities and + * attributes that need to be queried + */ + List queryEntityList = entAgg.getSourceEntities(); + List queryAttribList = entAgg.getSourceAttributes(); + + /* + * Formulate a query context request to submit back to the + * IoT Broker Core + */ + QueryContextRequest queryReq = new QueryContextRequest(queryEntityList, queryAttribList, null); + + /* + * submit the request to the core & get response + */ + logger.info("submitting query for aggregation source to IoT Broker core"); + + QueryContextResponse queryResp = + iotBrokerCore.queryContext(queryReq); + + logger.info("response received from IoT Broker core:\n"+queryResp.toString()); + + if( queryResp == null || + queryResp.getListContextElementResponse() == null) + return; //no useful response --> nothing to aggregate + + logger.info("putting the response into the aggregator"); + /* + * give the response to the aggregator + */ + entAgg.putData(queryResp.getListContextElementResponse()); + + /* + * get the aggregated data form aggregator + */ + ContextElementResponse aggResp = entAgg.getAggregate(); + + logger.info("getting aggregated response:\n"+aggResp.toString()); + + if(aggResp == null) return; //nothing aggregated --> no more to do + + /* + * add the aggregated data to the response list (which is + * shared among all threads) + */ + synchronized(responseList){ + responseList.add(aggResp); + } + + } + + } + + /* + * We create such a thread for each aggregator + */ + for(EntityAggregator entAgg:entAggList){ + tasks.add(Executors.callable(new aggregationThread(entAgg))); + } + + /* + * And then we run them all. + */ + try{ + taskExecutor.invokeAll(tasks); + } + catch(InterruptedException e) + { + logger.info("Task Execution error"); + logger.error(e); + return null; + } + + logger.info("final response list of aggregator:\n"+responseList.toString() ); + + + /* + * After the threads have populated the response list, we return it. + */ + return new QueryContextResponse(responseList,null); + + } +} diff --git a/eu.neclab.iotplatform.entitycomposer/src/main/java/eu/neclab/iotplatform/entitycomposer/EntityAggregator.java b/eu.neclab.iotplatform.entitycomposer/src/main/java/eu/neclab/iotplatform/entitycomposer/EntityAggregator.java new file mode 100644 index 00000000..5f6128c3 --- /dev/null +++ b/eu.neclab.iotplatform.entitycomposer/src/main/java/eu/neclab/iotplatform/entitycomposer/EntityAggregator.java @@ -0,0 +1,465 @@ +package eu.neclab.iotplatform.entitycomposer; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Logger; + +import eu.neclab.iotplatform.entitycomposer.datamodel.AggregationType; +import eu.neclab.iotplatform.entitycomposer.datamodel.EntityAggregationInfo; +import eu.neclab.iotplatform.iotbroker.commons.EntityIDMatcher; +import eu.neclab.iotplatform.ngsi.api.datamodel.AttributeAssociation; +import eu.neclab.iotplatform.ngsi.api.datamodel.ContextAttribute; +import eu.neclab.iotplatform.ngsi.api.datamodel.ContextElement; +import eu.neclab.iotplatform.ngsi.api.datamodel.ContextElementResponse; +import eu.neclab.iotplatform.ngsi.api.datamodel.EntityId; + +/** + * Objects of this class apply aggregation functions. + */ +public class EntityAggregator { + + Logger logger = Logger.getLogger(this.getClass()); + + /** + * This is the data structure for maintaining the known source + * attribute values. The outer map is indexed by the attribute name, + * while the inner hash maps are indexed by the entity IDs. + */ + Map> sourceValues; + + /** + * The entities useful for this aggregator as sources. + */ + List sourceEntityList; + + /** + * This map contains the relevant attribute associations + * for this aggregator, where each attribute association + * is stored with the source as the key and the target + * as the value + */ + Map attributeAssociationMap; + + + /** + * The Id of the target entity + */ + EntityId targetEntityId; + + /** + * The aggregation function used. + */ + AggregationType aggType; + + /** + * Create an entity aggregator object from aggregation info and a list of + * requested entities and attributes. + */ + public EntityAggregator(EntityAggregationInfo entAggInfo, List entityIdList, List attributeList) throws NotRequestedException { + + logger.info("costructing entity aggregator for \n"+entAggInfo.toString()); + + this.targetEntityId = entAggInfo.getTargetEntity(); + + /* + * Run through given entity Id list to see whether the target entity is + * requested + */ + { + boolean isRequested = false; + for(EntityId eId:entityIdList) + if (EntityIDMatcher.matcher(targetEntityId,eId)) + isRequested = true; + + + if(!isRequested) { + logger.info("Target entityId not requested"); + throw new NotRequestedException("EntityId not requested"); + } + + } + + + + this.sourceValues = new HashMap>(); + + /* + * initialize the source entities and aggregation type like given + * in the aggregation info. + */ + this.sourceEntityList = new ArrayList(entAggInfo.getSourceEntityList()); + this.aggType = entAggInfo.getAggregationType(); + + /* + * For determining the attributes for which to apply this aggregator, + * we compute the intersection between the requested attributes and the + * ones mentioned as targets in the aggregation info. + * + * But first we need to address the special cases where attribute lists + * are not given. + */ + + /* + * If neither the request nor the association list + * has attributes specified ... + */ + if( + (attributeList == null || attributeList.isEmpty()) + && + ( + entAggInfo.getAttributeAssociationList() == null || + entAggInfo.getAttributeAssociationList().isEmpty() + ) + ) + { + /* + * ...then attribute lists stays empty, meaning that + * all attributes are relevant. + */ + } + + /* + * If the request specifies attributes but the aggregation + * info does not.... + */ + else if(entAggInfo.getAttributeAssociationList() == null || + entAggInfo.getAttributeAssociationList().isEmpty() + ) + { + /* + * ... we make attribute associations for the needed attributes. + */ + + this.attributeAssociationMap = new HashMap(); + for(String attr:attributeList){ + attributeAssociationMap.put(attr,attr); + } + } + + /* + * If the aggregation info specifies attributes but the request + * does not ... + */ + else if( + attributeList == null || attributeList.isEmpty() + ) + { + /* + * We make exactly the attribute associations described in + * the aggregation info + */ + this.attributeAssociationMap = new HashMap(); + for(AttributeAssociation assoc:entAggInfo.getAttributeAssociationList()){ + attributeAssociationMap.put(assoc.getSourceAttribute(), assoc.getTargetAttribute()); + } + } + + else + { + + /* + * We compute the intersection as described above: + * first create the set of requested attributes for + * fast lookup + */ + Set reqAttribSet = new HashSet(attributeList); + + this.attributeAssociationMap = new HashMap(); + + /* + * Now run through the attribute associations and pick the + * relevant ones (= the ones whose target is a requested attribute). + */ + for(AttributeAssociation assoc:entAggInfo.getAttributeAssociationList()){ + if(reqAttribSet.contains(assoc.getTargetAttribute())) + attributeAssociationMap.put(assoc.getSourceAttribute(), + assoc.getTargetAttribute()); + } + + } + + + } + + /** + * Returns the list of entities that can be used as sources for + * this aggregation. + */ + public List getSourceEntities() { + + return sourceEntityList; + } + + /** + * Returns the list of attributes that can be used as sources for + * this aggregation + */ + public List getSourceAttributes() { + + /* + * no attributes specified + */ + if(attributeAssociationMap == null) return null; + + /* + * attributes are specified + */ + return new ArrayList(attributeAssociationMap.keySet()); + + } + + + /** + * Submit source data to the aggregator. + */ + public void putData(List ContextElementResponseList) { + + /* + * We check for each attribute value if it is numerical, and if yes, + * we put it into the value map. + * + * Note: for efficiency we do not check whether the attribute value + * is relevant for the aggregation here, because we would have to + * check it against each of the source entity IDs (which are potentially + * patterns, so no hashmap tricks are applicable) + * + */ + + logger.info("starting aggregator put method"); + + if(ContextElementResponseList == null) return; + + for(ContextElementResponse cer:ContextElementResponseList){ + if(cer.getContextElement() == null) + continue; + if(cer.getContextElement().getContextAttributeList() == null) + continue; + + for(ContextAttribute attrib:cer.getContextElement().getContextAttributeList()) + { + + logger.info("now processing attribute:/n"+attrib.toString()); + + Object attrVal = attrib.getcontextValue(); + + + + /* + * we try to cast the attribute value into a Double + */ + double attrValNum = Double.NaN; + try{ + attrValNum = Double.valueOf(attrVal.toString()); + } + catch(ClassCastException E) + { + logger.info("Value of attribute "+ attrib.getName()+ + " of entity "+cer.getContextElement().getEntityId().getId()+ + "not numerical."); + + continue; + } + + + + /* + * Now as we have the attribute value as a numerical value, + * we can add it to the map. + */ + + /* + * check if map for this attribute has been initialized + */ + Map entityValueMap = sourceValues.get(attrib.getName()); + if(entityValueMap == null) + { + entityValueMap = new HashMap(); + sourceValues.put(attrib.getName(), entityValueMap); + } + + /* + * add it to the map + */ + entityValueMap.put(cer.getContextElement().getEntityId(), new Double(attrValNum)); + + logger.info("successfully put value into map:"+attrValNum); + } + + } + + + } + + /** + * Returns the aggregated entity information. + * + */ + public ContextElementResponse getAggregate() { + + logger.info("started aggregator get method"); + + /* + * Create the ContextElementResponse skeleton. + */ + ContextElementResponse cer = new ContextElementResponse(); + + /* + * create the contextElement skeleton + */ + ContextElement ce = new ContextElement(); + ce.setEntityId(targetEntityId); + + /* + * put the contextelement skeletton into the contextelementresponse + * skeleton + */ + cer.setContextElement(ce); + + /* + * create the attributeList + */ + List attributeList = new ArrayList(); + + /* + * put it into the context element skeleton + */ + ce.setContextAttributeList(attributeList); + + logger.info("aggregator's value map:\n"+sourceValues.toString()); + logger.info("attribute Associations:\n"+attributeAssociationMap.toString()); + + /* + * Now we populate the attribute list + */ + for(String srcAttrName:sourceValues.keySet()){ + + logger.info("now processing source attribute: "+srcAttrName); + + Map valueMap = sourceValues.get(srcAttrName); + double aggregatedValue = aggregate(valueMap.values()); + + ContextAttribute ca = new ContextAttribute( + attributeAssociationMap.get(srcAttrName), null, (new Double(aggregatedValue)).toString()); + + logger.info("created context attribute:\n"+ca.toString()); + + attributeList.add(ca); + } + + return cer; + } + + /** + * Aggregates doubles according to the aggregation function specified + * for this object. The behavior in corner cases is as follows: + * + * ALL functions: + * - non-finite input numbers (NaN or +-infinity) will be ignored. + * + * AVG: + * - returns NaN if there are no input values + * MAX, MIN: + * - return NaN if there are no input values + * SUM: + * - return 0.0 if there are no input values + */ + private double aggregate(Collection values) { + + logger.info("starting aggregation of:\n"+values.toString()); + logger.info("aggregation type: "+this.aggType); + + double aggregated = Double.NaN; + + switch(this.aggType){ + + case AVG: + { + double sum = 0.0; + int cnt = 0; + + for(Double db:values) + { + double d = db.doubleValue(); + if(!isFinite(d)) + continue; + + cnt++; + sum+=d; + } + if(cnt>0) + aggregated = sum/(double)cnt; + } + break; + case MAX: + { + double max = Double.NEGATIVE_INFINITY; + + for(Double db:values) + { + double d = db.doubleValue(); + + if(!isFinite(d)) continue; + + if(d>max) max = d; + } + if(max!=Double.NEGATIVE_INFINITY) + aggregated = max; + + } + break; + case MIN: + { + double min = Double.POSITIVE_INFINITY; + + for(Double db:values) + { + double d = db.doubleValue(); + + if(!isFinite(d)) continue; + + if(d sourceEntityList; + + @XmlElementWrapper(name = "attributeAssociationList") + @XmlElement(name = "attributeAssociation") + List attributeAssociationList; + + @XmlElement(name = "aggregationType", required = true) + AggregationType aggregationType; + + public List getSourceEntityList() { + return sourceEntityList; + } + + public void setSourceEntityList(List sourceEntityList) { + this.sourceEntityList = sourceEntityList; + } + + public EntityId getTargetEntity() { + return targetEntity; + } + + public void setTargetEntity(EntityId targetEntity) { + this.targetEntity = targetEntity; + } + + public List getAttributeAssociationList() { + return attributeAssociationList; + } + + public void setAttributeAssociationList(List attributeAssociationList) { + this.attributeAssociationList = attributeAssociationList; + } + + public AggregationType getAggregationType() { + return aggregationType; + } + + public void setAggregationType(AggregationType aggregationType) { + this.aggregationType = aggregationType; + } + + public EntityAggregationInfo(List sourceEntityList, EntityId targetEntity, + List attributeAssociationList, AggregationType aggregationType) { + super(); + this.sourceEntityList = sourceEntityList; + this.targetEntity = targetEntity; + this.attributeAssociationList = attributeAssociationList; + this.aggregationType = aggregationType; + } + + + + public EntityAggregationInfo() { + super(); + } + + public EntityAggregationInfo(Object sourceData) { + // TODO remove this when a proper cast has been implemented + } + +} diff --git a/eu.neclab.iotplatform.entitycomposer/src/main/java/eu/neclab/iotplatform/entitycomposer/datamodel/SourceInfoContextMetadata.java b/eu.neclab.iotplatform.entitycomposer/src/main/java/eu/neclab/iotplatform/entitycomposer/datamodel/SourceInfoContextMetadata.java new file mode 100644 index 00000000..b8fe2a83 --- /dev/null +++ b/eu.neclab.iotplatform.entitycomposer/src/main/java/eu/neclab/iotplatform/entitycomposer/datamodel/SourceInfoContextMetadata.java @@ -0,0 +1,119 @@ +package eu.neclab.iotplatform.entitycomposer.datamodel; + +import java.io.IOException; +import java.io.StringReader; +import java.net.URI; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAnyElement; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.codehaus.jackson.map.annotate.JsonDeserialize; +import org.codehaus.jackson.map.annotate.JsonSerialize; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import eu.neclab.iotplatform.iotbroker.commons.XmlFactory; +import eu.neclab.iotplatform.ngsi.api.datamodel.ContextMetadata; +import eu.neclab.iotplatform.ngsi.api.datamodel.NgsiStructure; +import eu.neclab.iotplatform.ngsi.api.datamodel.SourceInformation; +import eu.neclab.iotplatform.ngsi.api.serialization.json.MetadataObjectValueSerializer; +import eu.neclab.iotplatform.ngsi.api.serialization.json.MetadataValueDeserializer; + +/** + * This is an alternative de-serialization of contextMetadata xml, + * where the value is represented as a EntityAggregationInfo. This is a + * workaround for getting the AggregationInfo from registration metadata. + */ +@XmlRootElement(name = "contextMetadata") +@XmlAccessorType(XmlAccessType.FIELD) +public class SourceInfoContextMetadata extends NgsiStructure { + + public static SourceInformation getValueAsSourceInfo(ContextMetadata cmd){ + + String s = cmd.toString(); + + SourceInfoContextMetadata svcmd = + (SourceInfoContextMetadata) + (new XmlFactory()).convertStringToXml(s, SourceInfoContextMetadata.class); + + return svcmd.getValue(); + + } + + + @XmlElement(name = "name") + private String name = null; + @XmlSchemaType(name = "anyURI") + private URI type = null; + + @XmlElement(name = "value") + //@XmlAnyElement(lax=true) + @JsonSerialize(using = MetadataObjectValueSerializer.class) + @JsonDeserialize(using = MetadataValueDeserializer.class) + private SourceInformation value; + + public SourceInfoContextMetadata() { + + } + + public SourceInfoContextMetadata(String name, URI type, SourceInformation value) { + + this.name = name; + this.type = type; + this.value = value; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public URI getType() { + return type; + } + + public void setType(URI type) { + this.type = type; + } + + public SourceInformation getValue() { + return value; + } + + public void setValue(SourceInformation value) { + this.value = value; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (obj == null || getClass() != obj.getClass()) { + return false; + } + + SourceInfoContextMetadata other = (SourceInfoContextMetadata) obj; + + return name.equals(other.name) && type.equals(other.type) + && value.toString().equals(other.value.toString()); + + } + + + +} diff --git a/eu.neclab.iotplatform.entitycomposer/src/test/java/entitycomposer/AggregationInfoSerializationTest.java b/eu.neclab.iotplatform.entitycomposer/src/test/java/entitycomposer/AggregationInfoSerializationTest.java new file mode 100644 index 00000000..c8efb383 --- /dev/null +++ b/eu.neclab.iotplatform.entitycomposer/src/test/java/entitycomposer/AggregationInfoSerializationTest.java @@ -0,0 +1,57 @@ +package entitycomposer; + +import org.junit.Test; + +import eu.neclab.iotplatform.entitycomposer.datamodel.AggregationSourceInformation; +import eu.neclab.iotplatform.entitycomposer.datamodel.EntityAggregationInfo; +import eu.neclab.iotplatform.entitycomposer.datamodel.SourceInfoContextMetadata; +import eu.neclab.iotplatform.iotbroker.commons.XmlFactory; +import eu.neclab.iotplatform.ngsi.api.datamodel.ContextMetadata; +import eu.neclab.iotplatform.ngsi.api.datamodel.DiscoverContextAvailabilityResponse; +import eu.neclab.iotplatform.ngsi.api.datamodel.SourceInformation; + +public class AggregationInfoSerializationTest { + + @Test + public void test() { + + + /* + * serialize the discovery response from + * the xml file + */ + DiscoverContextAvailabilityResponse discoveryResp = (DiscoverContextAvailabilityResponse) + (new XmlFactory()).convertFileToXML("src/test/resources/aggregationInfoRegistration.xml", DiscoverContextAvailabilityResponse.class); + + System.out.println("Trying to serialize discovery response: \n\n"+ + discoveryResp.toString() + ); + + + /* + * Try to cast the registration metadata value into source information + */ + ContextMetadata md + = discoveryResp.getContextRegistrationResponse().get(0).getContextRegistration().getListContextMetadata().get(0); + + SourceInformation sourceInfo = SourceInfoContextMetadata.getValueAsSourceInfo(md); + + System.out.println("Result of cast: \n\n"+ + sourceInfo.toString()); + + /* + * Try to cast the source value + */ + + System.out.println("Now casting source data into entity aggregation info"); + + EntityAggregationInfo entityAggInfo = + AggregationSourceInformation.getValueAsAggrInfo(sourceInfo); + + System.out.println("Result:\n\n" + entityAggInfo.toString()); + + return; + + } + +} diff --git a/eu.neclab.iotplatform.entitycomposer/src/test/java/entitycomposer/EntityAggregationQueryServiceTest.java b/eu.neclab.iotplatform.entitycomposer/src/test/java/entitycomposer/EntityAggregationQueryServiceTest.java new file mode 100644 index 00000000..9665a08d --- /dev/null +++ b/eu.neclab.iotplatform.entitycomposer/src/test/java/entitycomposer/EntityAggregationQueryServiceTest.java @@ -0,0 +1,121 @@ +package entitycomposer; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; +import org.easymock.EasyMock; +import org.junit.Before; +import org.junit.Test; + +import eu.neclab.iotplatform.entitycomposer.CompositeEntityQueryService; +import eu.neclab.iotplatform.iotbroker.commons.XmlFactory; +import eu.neclab.iotplatform.ngsi.api.datamodel.ContextRegistration; +import eu.neclab.iotplatform.ngsi.api.datamodel.DiscoverContextAvailabilityRequest; +import eu.neclab.iotplatform.ngsi.api.datamodel.DiscoverContextAvailabilityResponse; +import eu.neclab.iotplatform.ngsi.api.datamodel.EntityId; +import eu.neclab.iotplatform.ngsi.api.datamodel.QueryContextRequest; +import eu.neclab.iotplatform.ngsi.api.datamodel.QueryContextResponse; +import eu.neclab.iotplatform.ngsi.api.ngsi10.Ngsi10Interface; +import eu.neclab.iotplatform.ngsi.api.ngsi9.Ngsi9Interface; + +/** + * This tests the query service for entity aggregation info. + * It mocks the IoT Broker core to simulate that some meaningful + * result is returned when it is queried by the query service. + */ +public class EntityAggregationQueryServiceTest { + + /* + * The class tested. + */ + CompositeEntityQueryService queryService = new CompositeEntityQueryService(); + + /* + * The mock of the broker core + */ + Ngsi10Interface coreMock; + + /* + * event logger + */ + private static Logger logger = Logger.getLogger("Unit Tests"); + + @Before + public void before(){ + + //initialize the mock + coreMock = EasyMock.createMock(Ngsi10Interface.class); + + //connect service to mock + queryService.setIotBrokerCore(coreMock); + + } + + + @Test + public void simpleAVGTest() { + + /* + * initialize test requests and responses + */ + + DiscoverContextAvailabilityResponse discResp = + (DiscoverContextAvailabilityResponse) + (new XmlFactory()).convertFileToXML + ("src/test/resources/aggregationInfoRegistration.xml", + DiscoverContextAvailabilityResponse.class); + + List regList = new ArrayList<>(); + regList.add(discResp.getContextRegistrationResponse() + .get(0).getContextRegistration()); + + + QueryContextRequest targetQueryRequest = + (QueryContextRequest) + (new XmlFactory()).convertFileToXML + ("src/test/resources/targetQueryRequest.xml", + QueryContextRequest.class); + + QueryContextResponse expectedResp = + (QueryContextResponse) + (new XmlFactory()).convertFileToXML + ("src/test/resources/targetQueryResponse.xml", + QueryContextResponse.class); + + + QueryContextRequest sourceQueryRequest = + (QueryContextRequest) + (new XmlFactory()).convertFileToXML + ("src/test/resources/sourceQueryRequest.xml", + QueryContextRequest.class); + + QueryContextResponse sourceResponse1 = + (QueryContextResponse) + (new XmlFactory()).convertFileToXML + ("src/test/resources/sourceQueryResponse.xml", + QueryContextResponse.class); + + + + //configure core mock + EasyMock.expect(coreMock.queryContext(sourceQueryRequest)).andReturn(sourceResponse1); + + //arm mock + EasyMock.replay(coreMock); + + //execute the test + QueryContextResponse testResp = queryService.queryContext(targetQueryRequest, regList); + + /* + * verify results + */ + EasyMock.verify(coreMock); + + assertEquals(expectedResp,testResp); + + } + +} diff --git a/eu.neclab.iotplatform.entitycomposer/src/test/resources/aggregationInfoRegistration.xml b/eu.neclab.iotplatform.entitycomposer/src/test/resources/aggregationInfoRegistration.xml new file mode 100644 index 00000000..9eb15a47 --- /dev/null +++ b/eu.neclab.iotplatform.entitycomposer/src/test/resources/aggregationInfoRegistration.xml @@ -0,0 +1,57 @@ + + + + + + + + + ConferenceRoom + + + + + temperature + false + + + + + + aggregationInfo + org.fiware.type.metadata.sourceinformation + + org.fiware.type.sourceinformation.aggregation + + + ConferenceRoom + + + + Sensor_A + + + Sensor_B + + + + + sensorValue + temperature + + + + AVG + + + + + + + + + \ No newline at end of file diff --git a/eu.neclab.iotplatform.entitycomposer/src/test/resources/sourceQueryRequest.xml b/eu.neclab.iotplatform.entitycomposer/src/test/resources/sourceQueryRequest.xml new file mode 100644 index 00000000..c7f80647 --- /dev/null +++ b/eu.neclab.iotplatform.entitycomposer/src/test/resources/sourceQueryRequest.xml @@ -0,0 +1,14 @@ + + + + + Sensor_A + + + Sensor_B + + + + sensorValue + + \ No newline at end of file diff --git a/eu.neclab.iotplatform.entitycomposer/src/test/resources/sourceQueryResponse.xml b/eu.neclab.iotplatform.entitycomposer/src/test/resources/sourceQueryResponse.xml new file mode 100644 index 00000000..776c4f8b --- /dev/null +++ b/eu.neclab.iotplatform.entitycomposer/src/test/resources/sourceQueryResponse.xml @@ -0,0 +1,39 @@ + + + + + + + Sensor_A + + + + sensorValue + 10 + + + + + 200 + Ok + + + + + + Sensor_B + + + + sensorValue + 20 + + + + + 200 + Ok + + + + \ No newline at end of file diff --git a/eu.neclab.iotplatform.entitycomposer/src/test/resources/targetQueryRequest.xml b/eu.neclab.iotplatform.entitycomposer/src/test/resources/targetQueryRequest.xml new file mode 100644 index 00000000..f89ae52e --- /dev/null +++ b/eu.neclab.iotplatform.entitycomposer/src/test/resources/targetQueryRequest.xml @@ -0,0 +1,11 @@ + + + + + ConferenceRoom + + + + temperature + + \ No newline at end of file diff --git a/eu.neclab.iotplatform.entitycomposer/src/test/resources/targetQueryResponse.xml b/eu.neclab.iotplatform.entitycomposer/src/test/resources/targetQueryResponse.xml new file mode 100644 index 00000000..dfc5b61c --- /dev/null +++ b/eu.neclab.iotplatform.entitycomposer/src/test/resources/targetQueryResponse.xml @@ -0,0 +1,18 @@ + + + + + + + ConferenceRoom + + + + temperature + 15.0 + + + + + + \ No newline at end of file diff --git a/eu.neclab.iotplatform.iotbroker.builder/LICENSE.txt b/eu.neclab.iotplatform.iotbroker.builder/LICENSE.txt new file mode 100644 index 00000000..f1790246 --- /dev/null +++ b/eu.neclab.iotplatform.iotbroker.builder/LICENSE.txt @@ -0,0 +1,25 @@ + Copyright (c) 2014, NEC Europe Ltd. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: + This product includes software developed by NEC Europe Ltd. + 4. Neither the name of the NEC nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY NEC ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL NEC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/eu.neclab.iotplatform.iotbroker.builder/README.txt b/eu.neclab.iotplatform.iotbroker.builder/README.txt new file mode 100644 index 00000000..d382822a --- /dev/null +++ b/eu.neclab.iotplatform.iotbroker.builder/README.txt @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2014, NEC Europe Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by NEC Europe Ltd. + * 4. Neither the name of the NEC nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NEC ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NEC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *******************************************************************************/ + +-----IoT Broker Relase 3.2.1----- + +-----System Requirements----------- + + 1 GHz 32-bit (x86) or 64-bit (x64) processor + 1 GB of system memory + 20 GB hard drive with at least 15 GB of available space + Java 7 installed + Maven 3 installed for compiling + Internet connection for compiling with Maven (only the first time) + OSGi Enviroment (Equinox and Felix tested). An example OSGi Enviroment can be found in the IoT Broker binary release. +--------------------------------------- + + +-----Installation Guide----------- + +The IoT Broker software in implemented in Java with Spring and Maven support. Before compiling the source code, please install two additional libraries inside your maven local repository. +For installing these libraries, use the command prompt and navigate to the "lib" folder inside the IoT Broker source folder. Then use the following commands to install the libraries: + +mvn install:install-file -DgroupId=org.apache.httpcomponents -DartifactId=httpclient -Dversion=4.2.0-osgi -Dfile=httpclient-4.2.0-osgi.jar -Dpackaging=jar -DgeneratePom=true + +mvn install:install-file -DgroupId=org.apache.httpcomponents -DartifactId=httpcore -Dversion=4.2.0-osgi -Dfile=httpclient-4.2.0-osgi.jar -Dpackaging=jar -DgeneratePom=true + +After that, you should be able to compile the IoT Broker source code without any problems. For compiling the full IoT Broker, navigate to the builder project "eu.neclab.iotbroker.builder" and use the mvn command "mvn clean package" + +This command will generate a target folder with all the dependencies and the IoT Broker Osgi bundles that are needed for running the IoT Broker using an OSGi framework (like Equinox or Felix). + +---------------------------------- +Contacts: +Tobias Jacobs: tobias.jacob@neclab.eu +Raihan Ul-islam: raihan.ul-islam@neclab.eu +Salvatore Longo: salvatore.longo@neclab.eu \ No newline at end of file diff --git a/eu.neclab.iotplatform.iotbroker.builder/paxrunner-assembly.xml b/eu.neclab.iotplatform.iotbroker.builder/paxrunner-assembly.xml new file mode 100644 index 00000000..05da8c92 --- /dev/null +++ b/eu.neclab.iotplatform.iotbroker.builder/paxrunner-assembly.xml @@ -0,0 +1,75 @@ + + + distribution + + + dir + zip + + + false + + + + README.txt + / + + + LICENSE.txt + / + + + + + + ${basedir} + required-bundles + + lib/*.jar + + + + + + + + false + true + runner + + + + + + + + + provided + + org.ops4j.pax.runner:pax-runner + + ${artifact.artifactId}.${artifact.extension} + + + + \ No newline at end of file diff --git a/eu.neclab.iotplatform.iotbroker.builder/pom.xml b/eu.neclab.iotplatform.iotbroker.builder/pom.xml index b46c6081..52edb73a 100644 --- a/eu.neclab.iotplatform.iotbroker.builder/pom.xml +++ b/eu.neclab.iotplatform.iotbroker.builder/pom.xml @@ -5,7 +5,7 @@ eu.neclab.iotplatform IoTbrokerParent - 4.3.3-SNAPSHOT + 4.4.3 ../IoTbrokerParent @@ -50,6 +50,7 @@ + ../tomcat-configuration-fragment ../eu.neclab.iotplatform.iotbroker.commons ../eu.neclab.iotplatform.iotbroker.storage @@ -58,7 +59,8 @@ ../eu.neclab.iotplatform.iotbroker.restcontroller ../eu.neclab.iotplatform.ngsi.api ../eu.neclab.iotplatform.iotbroker.ext.resultfilter - ../eu.neclab.iotplatform.couchdb + ../eu.neclab.iotplatform.entitycomposer + ../eu.neclab.iotplatform.couchdb diff --git a/eu.neclab.iotplatform.iotbroker.client/pom.xml b/eu.neclab.iotplatform.iotbroker.client/pom.xml index 74808084..759fceb6 100644 --- a/eu.neclab.iotplatform.iotbroker.client/pom.xml +++ b/eu.neclab.iotplatform.iotbroker.client/pom.xml @@ -4,7 +4,7 @@ eu.neclab.iotplatform IoTbrokerParent - 4.3.3-SNAPSHOT + 4.4.3 ../IoTbrokerParent 4.0.0 diff --git a/eu.neclab.iotplatform.iotbroker.commons/pom.xml b/eu.neclab.iotplatform.iotbroker.commons/pom.xml index cce0fa89..de45cb23 100644 --- a/eu.neclab.iotplatform.iotbroker.commons/pom.xml +++ b/eu.neclab.iotplatform.iotbroker.commons/pom.xml @@ -4,7 +4,7 @@ IoTbrokerParent eu.neclab.iotplatform - 4.3.3-SNAPSHOT + 4.4.3 ../IoTbrokerParent diff --git a/eu.neclab.iotplatform.iotbroker.commons/src/main/java/eu/neclab/iotplatform/iotbroker/commons/interfaces/QueryService.java b/eu.neclab.iotplatform.iotbroker.commons/src/main/java/eu/neclab/iotplatform/iotbroker/commons/interfaces/QueryService.java new file mode 100644 index 00000000..40fe2870 --- /dev/null +++ b/eu.neclab.iotplatform.iotbroker.commons/src/main/java/eu/neclab/iotplatform/iotbroker/commons/interfaces/QueryService.java @@ -0,0 +1,17 @@ +package eu.neclab.iotplatform.iotbroker.commons.interfaces; + +import java.util.List; + +import eu.neclab.iotplatform.ngsi.api.datamodel.ContextRegistration; +import eu.neclab.iotplatform.ngsi.api.datamodel.QueryContextRequest; +import eu.neclab.iotplatform.ngsi.api.datamodel.QueryContextResponse; + +/** + * Interface for services that can return NGSI data when called with a + * query context request and a list of context registrations. + */ +public interface QueryService { + + public QueryContextResponse queryContext(QueryContextRequest req, List regList); + +} diff --git a/eu.neclab.iotplatform.iotbroker.core/META-INF/spring/brokercore-context.xml b/eu.neclab.iotplatform.iotbroker.core/META-INF/spring/brokercore-context.xml index 7e71f2aa..a6e2bbb9 100644 --- a/eu.neclab.iotplatform.iotbroker.core/META-INF/spring/brokercore-context.xml +++ b/eu.neclab.iotplatform.iotbroker.core/META-INF/spring/brokercore-context.xml @@ -26,6 +26,10 @@ + + + + + interface="eu.neclab.iotplatform.iotbroker.commons.interfaces.BigDataRepository" + cardinality="0..1" + timeout="0" + > - + + diff --git a/eu.neclab.iotplatform.iotbroker.core/pom.xml b/eu.neclab.iotplatform.iotbroker.core/pom.xml index c210a0fe..2c04f5d3 100644 --- a/eu.neclab.iotplatform.iotbroker.core/pom.xml +++ b/eu.neclab.iotplatform.iotbroker.core/pom.xml @@ -4,7 +4,7 @@ eu.neclab.iotplatform IoTbrokerParent - 4.3.3-SNAPSHOT + 4.4.3 ../IoTbrokerParent 4.0.0 @@ -32,13 +32,13 @@ META-INF eu.neclab.iotplatform.iotbroker.core.* - eu.neclab.iotplatform.iotbroker.commons;version="${pom.version}", - eu.neclab.iotplatform.iotbroker.commons.interfaces;version="${pom.version}", - eu.neclab.iotplatform.iotbroker.storage;version="${pom.version}", - eu.neclab.iotplatform.ngsi.api.datamodel;version="${pom.version}", - eu.neclab.iotplatform.ngsi.api.ngsi10;version="${pom.version}", - eu.neclab.iotplatform.ngsi.api.ngsi9;version="${pom.version}", - eu.neclab.iotplatform.ngsi.association.datamodel;version="${pom.version}", + eu.neclab.iotplatform.iotbroker.commons;version="${project.version}", + eu.neclab.iotplatform.iotbroker.commons.interfaces;version="${project.version}", + eu.neclab.iotplatform.iotbroker.storage;version="${project.version}", + eu.neclab.iotplatform.ngsi.api.datamodel;version="${project.version}", + eu.neclab.iotplatform.ngsi.api.ngsi10;version="${project.version}", + eu.neclab.iotplatform.ngsi.api.ngsi9;version="${project.version}", + eu.neclab.iotplatform.ngsi.association.datamodel;version="${project.version}", com.google.common.base;version="17.0.0", javax.xml.bind, javax.xml.bind.annotation, @@ -82,6 +82,10 @@ eu.neclab.iotplatform iotbroker.storage + + eu.neclab.iotplatform + iotbroker.commons + diff --git a/eu.neclab.iotplatform.iotbroker.core/src/main/java/eu/neclab/iotplatform/iotbroker/core/IotBrokerCore.java b/eu.neclab.iotplatform.iotbroker.core/src/main/java/eu/neclab/iotplatform/iotbroker/core/IotBrokerCore.java index 52eb1477..6703287e 100644 --- a/eu.neclab.iotplatform.iotbroker.core/src/main/java/eu/neclab/iotplatform/iotbroker/core/IotBrokerCore.java +++ b/eu.neclab.iotplatform.iotbroker.core/src/main/java/eu/neclab/iotplatform/iotbroker/core/IotBrokerCore.java @@ -48,9 +48,9 @@ import java.util.LinkedList; import java.util.List; import java.util.concurrent.Callable; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; @@ -70,6 +70,7 @@ import eu.neclab.iotplatform.iotbroker.commons.XmlFactory; import eu.neclab.iotplatform.iotbroker.commons.interfaces.BigDataRepository; import eu.neclab.iotplatform.iotbroker.commons.interfaces.NgsiHierarchyInterface; +import eu.neclab.iotplatform.iotbroker.commons.interfaces.QueryService; import eu.neclab.iotplatform.iotbroker.commons.interfaces.ResultFilterInterface; import eu.neclab.iotplatform.iotbroker.core.subscription.AgentWrapper; import eu.neclab.iotplatform.iotbroker.core.subscription.AssociationsUtil; @@ -88,6 +89,7 @@ import eu.neclab.iotplatform.ngsi.api.datamodel.ContextElementResponse; import eu.neclab.iotplatform.ngsi.api.datamodel.ContextMetadata; import eu.neclab.iotplatform.ngsi.api.datamodel.ContextMetadataAssociation; +import eu.neclab.iotplatform.ngsi.api.datamodel.ContextRegistration; import eu.neclab.iotplatform.ngsi.api.datamodel.ContextRegistrationResponse; import eu.neclab.iotplatform.ngsi.api.datamodel.DiscoverContextAvailabilityRequest; import eu.neclab.iotplatform.ngsi.api.datamodel.DiscoverContextAvailabilityResponse; @@ -131,6 +133,19 @@ */ public class IotBrokerCore implements Ngsi10Interface, Ngsi9Interface { + /** + * List of query services to pass queries to + */ + private List queryServiceList; + + public List getQueryServiceList() { + return queryServiceList; + } + + public void setQueryServiceList(List queryServiceList) { + this.queryServiceList = queryServiceList; + } + /** The URL of the pub/sub broker */ @Value("${dumbInBigDataRepo:false}") private boolean dumbInBigDataRepo; @@ -194,8 +209,7 @@ public class IotBrokerCore implements Ngsi10Interface, Ngsi9Interface { private ResultFilterInterface resultFilter; /** - * A pointer to a Big Data repository. (This functionality is currently - * disabled.) + * A pointer to a Big Data repository. */ private BigDataRepository bigDataRepository; @@ -581,7 +595,30 @@ public QueryContextResponse queryContext(QueryContextRequest request) { .filterOutSelfSubordination(discoveryResponse); } /* till here */ + + /* + * Now as we have done the discovery of data sources, we go and + * exploit these data sources for answering the query. + */ + + /* + * We first initialize the merger for merging the query results later + */ + QueryResponseMerger merger = new QueryResponseMerger(request); + /* + * Then we initialize a task list that will contain the data retrieval + * tasks. + * The reason we use such a task list is that we want to execute + * the data retrieval tasks all in parallel. + */ + List> tasks = new ArrayList>(); + + + /* + * Now check if the discovery response is useful; if yes, then we + * populate the query task list with query tasks accordingly. + */ if ((discoveryResponse.getErrorCode() == null || discoveryResponse .getErrorCode().getCode() == 200) && discoveryResponse.getContextRegistrationResponse() != null) { @@ -610,17 +647,7 @@ public QueryContextResponse queryContext(QueryContextRequest request) { + additionalRequestList); List> queryList = createQueryRequestList( - discoveryResponse, request); - - logger.debug("Query List Size: " + queryList.size()); - - QueryResponseMerger merger = new QueryResponseMerger(request); - - // List of Task - List> tasks = new ArrayList>(); - - // Countdown of Task - CountDownLatch count = new CountDownLatch(queryList.size()); + discoveryResponse, request); for (int i = 0; i < queryList.size(); i++) { logger.debug("Starting Thread number: " + i); @@ -633,126 +660,254 @@ public QueryContextResponse queryContext(QueryContextRequest request) { .get(i).getContextRegistration() .getProvidingApplication()); - tasks.add(Executors.callable(new RequestThread(resultFilter, + tasks.add(Executors.callable(new RequestThread( ngsi10Requester, queryList.get(i).getLeft(), queryList - .get(i).getRight(), merger, count, + .get(i).getRight(), merger, transitiveList))); } - - try { - - long t0 = System.currentTimeMillis(); - taskExecutor.invokeAll(tasks); - long t1 = System.currentTimeMillis(); - logger.debug("Finished all tasks in " + (t1 - t0) + " ms"); - - } catch (InterruptedException e) { - logger.debug("Thread Error", e); + + } + + /* + * In addition to the regular tasks of trying to get information + * from NGSI10 providers, we create for each 'query service' a task + * to obtain information from it. + * + * Query services are additional service, obtained from OSGi bundles, + * that can make queries for entities. Examples are: retrieving data + * from a database, resolving association, etc. + */ + + //this has only to be executed once... + if(queryServiceList == null) queryServiceList = new ArrayList(); + + logger.info(queryServiceList.size() + " query Services found"); + + /* + * Definition of Thread calling the query services and + * adding the query result to the merger. Implementation + * should be straightforward to understand. + */ + class queryServiceCaller implements Runnable{ + + QueryService qS; + QueryContextRequest qCR; + List regList; + QueryResponseMerger merger; + + queryServiceCaller( + QueryService qS, + QueryContextRequest qCR, + List regList, + QueryResponseMerger merger){ + this.qS=qS;this.qCR=qCR;this.regList=regList; + this.merger=merger; } + + @Override + public void run() { + //query the query service + QueryContextResponse qCResp = qS.queryContext(qCR, regList); + + //add result to the merger + synchronized(merger) + { + merger.put(qCResp); + } + } + + } + + /* + * We extract the list of context registrations from the + * discovery response + */ + List registrationList = new ArrayList(discoveryResponse.getContextRegistrationResponse().size()); + if(discoveryResponse.getContextRegistrationResponse() != null) + { + for(ContextRegistrationResponse cRR: discoveryResponse.getContextRegistrationResponse()) + { + registrationList.add(cRR.getContextRegistration()); + } + } + + /* + * Initialize the tasks for calling the query service + */ + for(QueryService qS: queryServiceList) + { + tasks.add(Executors.callable( + new queryServiceCaller(qS, request, registrationList, merger))); + } - // Call the Merge Method - QueryContextResponse threadResponse = merger.get(); - - logger.debug("Response after merging: " + threadResponse); - - if (resultFilter != null) { - logger.info("-----------++++++++++++++++++++++Begin Filter"); - List lqcReq = new ArrayList(); - lqcReq.add(request); - List lceRes = threadResponse - .getListContextElementResponse(); - logger.info("-----------++++++++++++++++++++++ QueryContextRequest:" - + lqcReq.toString() - + " ContextElementResponse:" - + lceRes.toString()); - - logger.info(lqcReq.size()); - logger.info(lceRes.size()); - - List lqcRes = resultFilter.filterResult( - lceRes, lqcReq); + + /* + * Now we are finally ready to execute all the data retrieval + * tasks in parallel. Yeah! Let's Do it. + */ + + try { - if (lqcRes.size() == 1) { - threadResponse = lqcRes.get(0); - } + long t0 = System.currentTimeMillis(); + taskExecutor.invokeAll(tasks, 10000, TimeUnit.MILLISECONDS); + long t1 = System.currentTimeMillis(); + logger.debug("Finished all tasks in " + (t1 - t0) + " ms"); - logger.info("-----------++++++++++++++++++++++ After Filter ListContextElementResponse:" - + lqcRes.toString() - + " ContextElementResponse:" - + lqcRes.toString()); - logger.info("-----------++++++++++++++++++++++End Filter"); - } else { + } catch (InterruptedException e) { + logger.error("Thread Error", e); + } + + + /* + * And now that all our tasks have nicely at least tried to + * retrieve their data and have put their data into the + * merger, we use the merger to do what is was designed for: + * to merge. + */ + + QueryContextResponse mergerResponse = merger.get(); - logger.info("Result filter not found!!"); + logger.debug("Response after merging: " + mergerResponse); + /* + * Now we call also the result filter if it is present. The result + * filter will check the merged query result against the original + * request to check whether the response matches what actually + * has been queried. Everything that is not matching is thrown + * out of the result. + * + * (Note that the try-catch is a workaround of the fact + * that this is the only way we see for testing wether + * the OSGi service is available) + */ + try{ + logger.info("trying to apply result filter"); + logger.debug("-----------++++++++++++++++++++++Begin Filter"); + List lqcReq = new ArrayList(); + lqcReq.add(request); + List lceRes = mergerResponse + .getListContextElementResponse(); + logger.debug("-----------++++++++++++++++++++++ QueryContextRequest:" + + lqcReq.toString() + + " ContextElementResponse:" + + lceRes.toString()); + + logger.debug(lqcReq.size()); + logger.debug(lceRes.size()); + + List lqcRes = resultFilter.filterResult( + lceRes, lqcReq); + + if (lqcRes.size() == 1) { + mergerResponse = lqcRes.get(0); } - final QueryContextResponse queryContextRespLIstAfterMerge = threadResponse; - - logger.debug("QueryContextResponse after merger:" + threadResponse); - - /** - * The code snippet below is for dumping the data in a Big Data - * repository in addition. This feature is currently disabled. - */ - if (bigDataRepository != null) { + logger.debug("-----------++++++++++++++++++++++ After Filter ListContextElementResponse:" + + lqcRes.toString() + + " ContextElementResponse:" + + lqcRes.toString()); + logger.debug("-----------++++++++++++++++++++++End Filter"); + logger.info("Result filter found and applied."); + } + catch(Exception E) + { + logger.info("Error executing result filter; possibly bundle not present."); + } - new Thread() { - @Override - public void run() { - List contextElementList = new ArrayList(); + logger.debug("QueryContextResponse after merger and (maybe) result filter:" + mergerResponse); - Iterator iter = queryContextRespLIstAfterMerge - .getListContextElementResponse().iterator(); + /* + * The code snippet below is for dumping the data in a Big Data + * repository in addition. + * + * (And again we a similar workaround as above for the result filter) + */ + + logger.info("Trying to access Big Data repository"); + final QueryContextResponse queryContextRespListAfterMerge = mergerResponse; - while (iter.hasNext()) { + new Thread() { + @Override + public void run() { + + try{ + - ContextElementResponse contextElementResp = iter - .next(); + List contextElementList = new ArrayList(); - contextElementList.add(contextElementResp - .getContextElement()); + Iterator iter = queryContextRespListAfterMerge + .getListContextElementResponse().iterator(); - } + while (iter.hasNext()) { - bigDataRepository.storeData(contextElementList); + ContextElementResponse contextElementResp = iter + .next(); - } - }.start(); - } - - if (request.getRestriction() != null) { + contextElementList.add(contextElementResp + .getContextElement()); + + } - String xpathExpression = request.getRestriction() - .getAttributeExpression(); - applyRestriction(xpathExpression, threadResponse); + bigDataRepository.storeData(contextElementList); + + } catch(Exception E) + { + logger.info("Error accessing Big data repository; possibly plugin not found."); + } } + }.start(); + + - if (threadResponse.getListContextElementResponse() == null - || threadResponse.getListContextElementResponse().isEmpty()) { - - threadResponse.setErrorCode(new StatusCode( - Code.CONTEXTELEMENTNOTFOUND_404.getCode(), - ReasonPhrase.CONTEXTELEMENTNOTFOUND_404.toString(), - null)); - - } + /* + * Now, having the nicely merged (and maybe even filtered) query + * result, it is time to apply the xpath restriction to it. + */ + + if (request.getRestriction() != null) { - return threadResponse; + String xpathExpression = request.getRestriction() + .getAttributeExpression(); + applyRestriction(xpathExpression, mergerResponse); - } else { + } - QueryContextResponse response = new QueryContextResponse(null, - discoveryResponse.getErrorCode()); + /* + * Now the final thing to do is to check if at all there is any- + * thing contained in the response or if all the work was for + * nothing. + * Well, if all was for nothing we at least add an error message... + */ + + if (mergerResponse.getListContextElementResponse() == null + || mergerResponse.getListContextElementResponse().isEmpty()) { - return response; + /* + * The details of the error message are taken from the + * discovery response if present. + */ + String details = null; + if(discoveryResponse != null && discoveryResponse.getErrorCode() != null) + details = "Discovery response: "+discoveryResponse.getErrorCode().getReasonPhrase()+" (details: "+ + discoveryResponse.getErrorCode().getDetails()+")"; + + logger.debug("No query results to return! Discovery response:" + discoveryResponse.toString()); + + mergerResponse.setErrorCode(new StatusCode( + Code.CONTEXTELEMENTNOTFOUND_404.getCode(), + ReasonPhrase.CONTEXTELEMENTNOTFOUND_404.toString(), + details)); } + - } + return mergerResponse; + + } + /** * This method is destructive: it changes the input contextElementResponse. diff --git a/eu.neclab.iotplatform.iotbroker.core/src/main/java/eu/neclab/iotplatform/iotbroker/core/RequestThread.java b/eu.neclab.iotplatform.iotbroker.core/src/main/java/eu/neclab/iotplatform/iotbroker/core/RequestThread.java index 3c6feaa7..dea03f0a 100644 --- a/eu.neclab.iotplatform.iotbroker.core/src/main/java/eu/neclab/iotplatform/iotbroker/core/RequestThread.java +++ b/eu.neclab.iotplatform.iotbroker.core/src/main/java/eu/neclab/iotplatform/iotbroker/core/RequestThread.java @@ -71,7 +71,6 @@ public class RequestThread implements Runnable { private QueryContextRequest request; private URI uri; private QueryResponseMerger merger; - private CountDownLatch count; private Ngsi10Requester requestor; @@ -109,16 +108,15 @@ public RequestThread() { * it will decrement the latch. * @param additionalRequestList */ - public RequestThread(ResultFilterInterface resultFilter, + public RequestThread( Ngsi10Requester requestor, QueryContextRequest request, URI uri, - QueryResponseMerger merger, CountDownLatch count, + QueryResponseMerger merger, List additionalRequestList) { this.requestor = requestor; this.request = request; this.uri = uri; this.merger = merger; - this.count = count; this.additionalRequestList = additionalRequestList; } @@ -243,7 +241,6 @@ public void run() { logger.debug("Start Merger!"); logger.debug("Response to put into merger: " + response); merger.put(response); - count.countDown(); } } diff --git a/eu.neclab.iotplatform.iotbroker.core/src/test/java/eu/neclab/iotplatform/iotbroker/core/junittests/tests/TestFunctionality.java b/eu.neclab.iotplatform.iotbroker.core/src/test/java/eu/neclab/iotplatform/iotbroker/core/junittests/tests/TestFunctionality.java index c2bf4d81..0b0836cb 100644 --- a/eu.neclab.iotplatform.iotbroker.core/src/test/java/eu/neclab/iotplatform/iotbroker/core/junittests/tests/TestFunctionality.java +++ b/eu.neclab.iotplatform.iotbroker.core/src/test/java/eu/neclab/iotplatform/iotbroker/core/junittests/tests/TestFunctionality.java @@ -211,6 +211,9 @@ public void restrictionTest(){ EasyMock.verify(ngsi9InterfaceMock); EasyMock.verify(ngsi10RequesterMock); + //manually remove the details from the broker response + brokerResp.getErrorCode().setDetails(null); + assertEquals(brokerResp,queryResp_notFound); logger.info("Successfully tested FIWARE.Feature.IoT.BackendIoTBroker.Query.Restriction"); diff --git a/eu.neclab.iotplatform.iotbroker.core/src/test/resources/queryReq_attribExpr.xml b/eu.neclab.iotplatform.iotbroker.core/src/test/resources/queryReq_attribExpr.xml new file mode 100644 index 00000000..ecc202e5 --- /dev/null +++ b/eu.neclab.iotplatform.iotbroker.core/src/test/resources/queryReq_attribExpr.xml @@ -0,0 +1,14 @@ + + + + + ConferenceRoom + + + + temperature + + + //id[../../contextAttributeList/contextAttribute/metadata/contextMetadata[name='test' and type='string']/value] + + diff --git a/eu.neclab.iotplatform.iotbroker.ext.resultfilter/pom.xml b/eu.neclab.iotplatform.iotbroker.ext.resultfilter/pom.xml index b6745304..75f77a27 100644 --- a/eu.neclab.iotplatform.iotbroker.ext.resultfilter/pom.xml +++ b/eu.neclab.iotplatform.iotbroker.ext.resultfilter/pom.xml @@ -3,7 +3,7 @@ eu.neclab.iotplatform IoTbrokerParent - 4.3.3-SNAPSHOT + 4.4.3 ../IoTbrokerParent iotbroker.ext.resultfilter diff --git a/eu.neclab.iotplatform.iotbroker.restcontroller/pom.xml b/eu.neclab.iotplatform.iotbroker.restcontroller/pom.xml index 6b9c91c4..364658be 100644 --- a/eu.neclab.iotplatform.iotbroker.restcontroller/pom.xml +++ b/eu.neclab.iotplatform.iotbroker.restcontroller/pom.xml @@ -3,7 +3,7 @@ eu.neclab.iotplatform IoTbrokerParent - 4.3.3-SNAPSHOT + 4.4.3 ../IoTbrokerParent 4.0.0 diff --git a/eu.neclab.iotplatform.iotbroker.storage/pom.xml b/eu.neclab.iotplatform.iotbroker.storage/pom.xml index 619c74cd..c3cd12cd 100644 --- a/eu.neclab.iotplatform.iotbroker.storage/pom.xml +++ b/eu.neclab.iotplatform.iotbroker.storage/pom.xml @@ -4,7 +4,7 @@ IoTbrokerParent eu.neclab.iotplatform - 4.3.3-SNAPSHOT + 4.4.3 ../IoTbrokerParent diff --git a/eu.neclab.iotplatform.ngsi.api/pom.xml b/eu.neclab.iotplatform.ngsi.api/pom.xml index a087ea52..412b6f23 100644 --- a/eu.neclab.iotplatform.ngsi.api/pom.xml +++ b/eu.neclab.iotplatform.ngsi.api/pom.xml @@ -4,7 +4,7 @@ eu.neclab.iotplatform IoTbrokerParent - 4.3.3-SNAPSHOT + 4.4.3 ../IoTbrokerParent diff --git a/eu.neclab.iotplatform.ngsi.api/src/main/java/eu/neclab/iotplatform/ngsi/api/datamodel/ContextRegistration.java b/eu.neclab.iotplatform.ngsi.api/src/main/java/eu/neclab/iotplatform/ngsi/api/datamodel/ContextRegistration.java index 8a70bd02..a0cfd9b0 100644 --- a/eu.neclab.iotplatform.ngsi.api/src/main/java/eu/neclab/iotplatform/ngsi/api/datamodel/ContextRegistration.java +++ b/eu.neclab.iotplatform.ngsi.api/src/main/java/eu/neclab/iotplatform/ngsi/api/datamodel/ContextRegistration.java @@ -72,7 +72,7 @@ public class ContextRegistration extends NgsiStructure { @JsonProperty("attributes") private List contextRegistrationAttribute = null; - @XmlElementWrapper(name = "registrationMetaData") + @XmlElementWrapper(name = "registrationMetadata") @XmlElement(name = "contextMetadata") private List contextMetadata = null; diff --git a/eu.neclab.iotplatform.ngsi.api/src/main/java/eu/neclab/iotplatform/ngsi/api/datamodel/ScopeTypes.java b/eu.neclab.iotplatform.ngsi.api/src/main/java/eu/neclab/iotplatform/ngsi/api/datamodel/ScopeTypes.java new file mode 100644 index 00000000..093ab576 --- /dev/null +++ b/eu.neclab.iotplatform.ngsi.api/src/main/java/eu/neclab/iotplatform/ngsi/api/datamodel/ScopeTypes.java @@ -0,0 +1,17 @@ +package eu.neclab.iotplatform.ngsi.api.datamodel; + +public enum ScopeTypes { + + ISO8601TimeInterval("ISO8601TimeInterval"); + + private String string; + + private ScopeTypes(String string) { + + this.string = string; + } + + public String toString(){ + return string; + } +} diff --git a/eu.neclab.iotplatform.ngsi.api/src/main/java/eu/neclab/iotplatform/ngsi/api/datamodel/SourceInformation.java b/eu.neclab.iotplatform.ngsi.api/src/main/java/eu/neclab/iotplatform/ngsi/api/datamodel/SourceInformation.java new file mode 100644 index 00000000..b5a1aa0e --- /dev/null +++ b/eu.neclab.iotplatform.ngsi.api/src/main/java/eu/neclab/iotplatform/ngsi/api/datamodel/SourceInformation.java @@ -0,0 +1,45 @@ +package eu.neclab.iotplatform.ngsi.api.datamodel; + +import java.net.URI; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlSchemaType; + +/** + * This class represents information about how to + * obtain NGSI Entity information. + */ +@XmlRootElement(name = "sourceInformation") +@XmlAccessorType(XmlAccessType.FIELD) +public class SourceInformation extends NgsiStructure{ + + + @XmlSchemaType(name = "anyURI") + private URI sourceType = null; + + @XmlElement(required=true) + Object sourceData; + + public URI getSourceType() { + return sourceType; + } + + public void setSourceType(URI sourceType) { + this.sourceType = sourceType; + } + + public Object getSourceData() { + return sourceData; + } + + public void setSourceData(String sourceData) { + this.sourceData = sourceData; + } + + + +} diff --git a/fiwareRelease/confmanconfig/bundleConfigurations/services/org.ops4j.pax.logging.properties b/fiwareRelease/confmanconfig/bundleConfigurations/services/org.ops4j.pax.logging.properties deleted file mode 100644 index 207c8ed1..00000000 --- a/fiwareRelease/confmanconfig/bundleConfigurations/services/org.ops4j.pax.logging.properties +++ /dev/null @@ -1,21 +0,0 @@ -log4j.rootLogger=INFO, ReportFileAppender, console - -#Console Appender -log4j.appender.console=org.apache.log4j.ConsoleAppender -log4j.appender.console.layout=org.apache.log4j.PatternLayout -log4j.appender.console.layout.ConversionPattern=%d{ISO8601} | %-5.5p | (%F:%M:%L) | %m%n - -#Solve the digerest Tomcat logger errors -log4j.logger.org.apache.commons=WARN -log4j.logger.org.apache.commons.beanutils=WARN -log4j.logger.org.apache.struts=WARN - -#File Appender -# ReportFileAppender - used to log messages in the report.log file. -log4j.appender.ReportFileAppender=org.apache.log4j.FileAppender -log4j.appender.ReportFileAppender.File=logs/confman.log -log4j.appender.ReportFileAppender.layout=org.apache.log4j.PatternLayout -log4j.appender.ReportFileAppender.layout.ConversionPattern= %-4r [%t] %-5p %c %x - %m%n - - - diff --git a/fiwareRelease/confmanconfig/configurationManager/config/config.properties b/fiwareRelease/confmanconfig/configurationManager/config/config.properties deleted file mode 100644 index 80ec0f24..00000000 --- a/fiwareRelease/confmanconfig/configurationManager/config/config.properties +++ /dev/null @@ -1,6 +0,0 @@ -postgres_user=postgres -postgres_password=confman -postgres_url=//localhost/ -postgres_dbName=confman -couchdb_registerContextDbName=confman_registerContext -couchdb_subscriptionDbName=confman_subscribeContextAvailability diff --git a/fiwareRelease/confmanconfig/configurationManager/config/config.xml b/fiwareRelease/confmanconfig/configurationManager/config/config.xml deleted file mode 100644 index 83a7d731..00000000 --- a/fiwareRelease/confmanconfig/configurationManager/config/config.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - -${dir.config}/schemas/Ngsi9_Operations_v08.xsd -ngsi9 -${dir.config}/schemas/Ngsi9_10_dataStructure_v08.xsd - diff --git a/fiwareRelease/confmanconfig/configurationManager/tableDescription/boxTable b/fiwareRelease/confmanconfig/configurationManager/tableDescription/boxTable deleted file mode 100644 index 4ed6e6dd..00000000 --- a/fiwareRelease/confmanconfig/configurationManager/tableDescription/boxTable +++ /dev/null @@ -1,11 +0,0 @@ -CREATE TABLE public.tablenameplaceholder -( - id serial NOT NULL PRIMARY KEY, - serviceid character varying(500) NOT NULL, - box character varying(100000) NOT NULL, - geoid character varying(500) NOT NULL -) -WITH ( - OIDS = FALSE -) -; \ No newline at end of file diff --git a/fiwareRelease/confmanconfig/configurationManager/tableDescription/circleTable b/fiwareRelease/confmanconfig/configurationManager/tableDescription/circleTable deleted file mode 100644 index 002ce0ec..00000000 --- a/fiwareRelease/confmanconfig/configurationManager/tableDescription/circleTable +++ /dev/null @@ -1,12 +0,0 @@ -CREATE TABLE public.tablenameplaceholder -( - id serial NOT NULL PRIMARY KEY, - serviceid character varying(500) NOT NULL, - center character varying(100000) NOT NULL, - radius double precision NOT NULL, - geoid character varying(500) NOT NULL -) -WITH ( - OIDS = FALSE -) -; \ No newline at end of file diff --git a/fiwareRelease/confmanconfig/configurationManager/tableDescription/ngsihierarchy_registrations b/fiwareRelease/confmanconfig/configurationManager/tableDescription/ngsihierarchy_registrations deleted file mode 100644 index e3e7a200..00000000 --- a/fiwareRelease/confmanconfig/configurationManager/tableDescription/ngsihierarchy_registrations +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE public.ngsihierarchy_registrations -( -department character varying(500) NOT NULL, -registrationid character varying(500) NOT NULL -) -WITH ( - OIDS = FALSE -) -; diff --git a/fiwareRelease/confmanconfig/configurationManager/tableDescription/ngsihierarchy_subscriptions b/fiwareRelease/confmanconfig/configurationManager/tableDescription/ngsihierarchy_subscriptions deleted file mode 100644 index f59ebc5c..00000000 --- a/fiwareRelease/confmanconfig/configurationManager/tableDescription/ngsihierarchy_subscriptions +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE public.ngsihierarchy_subscriptions -( -department character varying(500) NOT NULL, -subscriptionid character varying(500) NOT NULL -) -WITH ( - OIDS = FALSE -) -; diff --git a/fiwareRelease/confmanconfig/configurationManager/tableDescription/notificationsTable b/fiwareRelease/confmanconfig/configurationManager/tableDescription/notificationsTable deleted file mode 100644 index a21d96fe..00000000 --- a/fiwareRelease/confmanconfig/configurationManager/tableDescription/notificationsTable +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE public.notifications -( -subscriptionid character varying(500) NOT NULL REFERENCES subscriptions(subscriptionid) ON DELETE CASCADE, - registrationid character varying(500) NOT NULL, - geohashlist character varying(5000) -) -WITH ( - OIDS = FALSE -) -; diff --git a/fiwareRelease/confmanconfig/configurationManager/tableDescription/subscriptionAttributesTable b/fiwareRelease/confmanconfig/configurationManager/tableDescription/subscriptionAttributesTable deleted file mode 100644 index 74a8e38f..00000000 --- a/fiwareRelease/confmanconfig/configurationManager/tableDescription/subscriptionAttributesTable +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE public.subscriptionattributes -( -subscriptionid character varying(500) NOT NULL REFERENCES subscriptions(subscriptionid) ON DELETE CASCADE, - attribute character varying(500) NOT NULL -) -WITH ( - OIDS = FALSE -) -; - diff --git a/fiwareRelease/confmanconfig/configurationManager/tableDescription/subscriptionEntitiesTable b/fiwareRelease/confmanconfig/configurationManager/tableDescription/subscriptionEntitiesTable deleted file mode 100644 index 0c3b5c3e..00000000 --- a/fiwareRelease/confmanconfig/configurationManager/tableDescription/subscriptionEntitiesTable +++ /dev/null @@ -1,12 +0,0 @@ -CREATE TABLE public.subscriptionentities -( -subscriptionid character varying(500) NOT NULL REFERENCES subscriptions(subscriptionid) ON DELETE CASCADE, - entityid character varying(500) NOT NULL, - type character varying(500), - ispattern boolean NOT NULL -) -WITH ( - OIDS = FALSE -) -; - diff --git a/fiwareRelease/confmanconfig/configurationManager/tableDescription/subscriptionsTable b/fiwareRelease/confmanconfig/configurationManager/tableDescription/subscriptionsTable deleted file mode 100644 index 068338f3..00000000 --- a/fiwareRelease/confmanconfig/configurationManager/tableDescription/subscriptionsTable +++ /dev/null @@ -1,8 +0,0 @@ -CREATE TABLE public.subscriptions -( - subscriptionid character varying(500) NOT NULL PRIMARY KEY, - reference character varying(500) NOT NULL -) -WITH ( - OIDS=FALSE -); diff --git a/fiwareRelease/schemas/Ngsi9_10_dataStructure_v08.xsd b/fiwareRelease/schemas/Ngsi9_10_dataStructure_v08.xsd index c5a000ee..91c9e330 100644 --- a/fiwareRelease/schemas/Ngsi9_10_dataStructure_v08.xsd +++ b/fiwareRelease/schemas/Ngsi9_10_dataStructure_v08.xsd @@ -16,7 +16,7 @@ - + @@ -263,7 +263,7 @@ maxOccurs="1" /> - @@ -284,7 +284,7 @@ minOccurs="0" maxOccurs="1" /> - @@ -292,7 +292,7 @@ - + diff --git a/iotplatform.iotbroker.blackboxtest/pom.xml b/iotplatform.iotbroker.blackboxtest/pom.xml new file mode 100644 index 00000000..30352650 --- /dev/null +++ b/iotplatform.iotbroker.blackboxtest/pom.xml @@ -0,0 +1,54 @@ + + 4.0.0 + + eu.neclab + iotplatform.iotbroker.blackboxtest + 4.4.3 + jar + + iotplatform.iotbroker.blackboxtest + + + UTF-8 + + + + + junit + junit + 4.11 + test + + + org.mock-server + mockserver-netty + RELEASE + + + eu.neclab.iotplatform + ngsi.api + 4.4.3 + + + eu.neclab.iotplatform + iotbroker.commons + 4.4.3 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 5 + 5 + + + + + + diff --git a/iotplatform.iotbroker.blackboxtest/src/test/java/eu/neclab/iotplatform/iotbroker/blackboxtest/BBTest.java b/iotplatform.iotbroker.blackboxtest/src/test/java/eu/neclab/iotplatform/iotbroker/blackboxtest/BBTest.java new file mode 100644 index 00000000..8b1da487 --- /dev/null +++ b/iotplatform.iotbroker.blackboxtest/src/test/java/eu/neclab/iotplatform/iotbroker/blackboxtest/BBTest.java @@ -0,0 +1,425 @@ +package eu.neclab.iotplatform.iotbroker.blackboxtest; + +import org.apache.commons.io.IOUtils; +import org.apache.http.client.HttpClient; + + +import org.mockserver.client.server.MockServerClient; +import org.mockserver.integration.ClientAndServer; +import org.mockserver.matchers.BodyMatcher; +import org.mockserver.model.Body; +import org.mockserver.verify.VerificationTimes; + +import eu.neclab.iotplatform.iotbroker.commons.XmlFactory; +import eu.neclab.iotplatform.ngsi.api.datamodel.DiscoverContextAvailabilityRequest; +import eu.neclab.iotplatform.ngsi.api.datamodel.DiscoverContextAvailabilityResponse; +import eu.neclab.iotplatform.ngsi.api.datamodel.QueryContextRequest; +import eu.neclab.iotplatform.ngsi.api.datamodel.QueryContextResponse; +import io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction; + +import static org.mockserver.integration.ClientAndServer.startClientAndServer; +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; +import static org.mockserver.model.HttpForward.forward; +import static org.mockserver.model.Header.header; +import static org.mockserver.model.HttpResponse.notFoundResponse; +import static org.mockserver.model.HttpResponse.response; +import static org.mockserver.matchers.Times.exactly; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.mockserver.model.HttpForward.Scheme.HTTP; +import static org.mockserver.model.HttpStatusCode.ACCEPTED_202; + +import static org.mockserver.model.StringBody.exact; +import static org.mockserver.model.XPathBody.xpath; + + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import static org.junit.Assert.*; + + + +/** + * A suite of tests using the mockserver framework. These are blackbox tests to be + * run against a deployment of the IoT Broker running at localhost. + * + * Note: As the mockserver framework supports no xml document equivalence check, + * the xml bodies by the IoT Broker are instead tested using XPATH expressions. + */ +public class BBTest { + + final int D_PORT = 8002; //port of discovery mock + final int A1_PORT = 8031; //port of agent 1 mock + final int A2_PORT = 8032; //port of agent 2 mock + final int B_PORT = 80; //port of IoT Broker + + /* + * pointers to the mock servers (initialized in @Before method + * and stopped in @After method) + */ + ClientAndServer discoveryMockServer; + ClientAndServer agent1MockServer; + ClientAndServer agent2MockServer; + + /* + * Clients used to configure the mock servers. Should of course only + * be used in @Test methods, because otherwise the servers will not + * be up. + */ + MockServerClient d_client = new MockServerClient("localhost", D_PORT); + MockServerClient a1_client = new MockServerClient("localhost", A1_PORT); + MockServerClient a2_client = new MockServerClient("localhost", A2_PORT); + + @Before + public void startServerMocks(){ + + discoveryMockServer = startClientAndServer(D_PORT); + agent1MockServer = startClientAndServer(A1_PORT); + agent2MockServer = startClientAndServer(A2_PORT); + + } + + @After + public void stopServerMocks(){ + discoveryMockServer.stop(); + agent1MockServer.stop(); + agent2MockServer.stop(); + } + + /** + * Generic-purpose method to send an http request to localhost. + * Use "" for the path if not present. + * Use null for body in order not to include one in the request. + */ + public static String sendReqToServer(String body, int port, String method, String path) throws Exception{ + + URL url = new URL("http://localhost:"+port+path); + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + + con.setRequestMethod(method); + con.setDoOutput(true); + con.setRequestProperty("Accept", "application/xml"); + con.setRequestProperty("Content-Type", "application/xml"); + + if(body != null){ + DataOutputStream wr = new DataOutputStream(con.getOutputStream()); + wr.writeBytes(body); + wr.flush(); + wr.close(); + } + + BufferedReader in; + if (con.getResponseCode() == 200) { + in = new BufferedReader( + new InputStreamReader(con.getInputStream())); + } else { + /* error from server */ + in = new BufferedReader( + new InputStreamReader(con.getErrorStream())); + } + + String inputLine; + StringBuffer response = new StringBuffer(); + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + + + return response.toString(); + } + + /** + * Only see if and how the server mock framework is working. + */ + @Test + public void servermocktest() throws Exception{ + + + + //tell server what to respond to POST + d_client.when( + request(). + withMethod("POST") + ).respond(response().withStatusCode(200) + .withBody("Hi World!")); + + //send a POST + + String response = sendReqToServer("test!", D_PORT, "POST",""); + System.out.println("req result:" + response); + + + //verify there was a POST with the specific body + d_client + .verify( + request().withMethod("POST").withBody("test!"), + VerificationTimes.exactly(1) + ); + + System.out.println("Reached end of servermocktest"); + + } + + + /** + * A test for the situation where no discovery is + * found. + */ + @Test + public void noDiscoveryFoundTest() throws Exception{ + + //no need to arm a mock server; just send a request to IoT Broker + String response = sendReqToServer(null, B_PORT, "GET", + "/ngsi10/contextEntities/ConferenceRoom/attributes/temperature"); + + /* + * verify that there was a POST on discovery + * with the right path, right method, right body parameters + */ + d_client.verify(request() + .withPath("/ngsi9/discoverContextAvailability") + .withMethod("POST") + .withBody(xpath( + "(/discoverContextAvailabilityRequest/entityIdList/entityId//id=\"ConferenceRoom\")" + + "and" + + "(/discoverContextAvailabilityRequest/attributeList/attribute=\"temperature\")" + )) + , + VerificationTimes.exactly(1) + ); + } + + /** + * This test queries for information and simulates that IoT + * Discovery has entity aggregation information available + * to answer the request. + */ + @Test + public void entityAggregationQueryTest() throws Exception{ + + /* + * The workflow is as follows: + * + * - IoT Broker receives Query + * - IoT Broker asks Discovery and obtains entity aggregation into + * - IoT Broker asks Discovery again for the sources of aggregation info + * and receives info in IoT agents + * - IoT Broker contacts the IoT agents, assembles the target entity + * info from the information received and returns the resulting + * response + * + */ + + + /* + * the request send to start the test + */ + QueryContextRequest b_request = + (QueryContextRequest) + (new XmlFactory()).convertFileToXML + ("src/test/resources/entAggTest_b_req.xml", + QueryContextRequest.class); + + + /* + * the XPATH expression to verify the first request of + * IoT Broker to IoT Discovery + */ + String d_req1_eval = + "(/discoverContextAvailabilityRequest/entityIdList/entityId//id=\"ConferenceRoom\")" + + " and " + + "(/discoverContextAvailabilityRequest/attributeList/attribute=\"humidity\")" + + " and " + + "(/discoverContextAvailabilityRequest/attributeList/attribute=\"temperature\")" + ; + + /* + * The response returned by the IoT Discovery Mock + */ + DiscoverContextAvailabilityResponse d_response_1 = + (DiscoverContextAvailabilityResponse) + (new XmlFactory()).convertFileToXML + ("src/test/resources/entAggTest_d_resp1.xml", + DiscoverContextAvailabilityResponse.class); + + + /* + * The XPATH expression verifying the second + * request of IoT Broker to IoT Discovery + */ + String d_req2_eval = + "(/discoverContextAvailabilityRequest/entityIdList/entityId//id=\"SensorBoard_A\")" + + " and " + + "(/discoverContextAvailabilityRequest/entityIdList/entityId//id=\"TempSensor_B\")" + + " and " + + "(/discoverContextAvailabilityRequest/attributeList/attribute=\"humValue\")" + + " and " + + "(/discoverContextAvailabilityRequest/attributeList/attribute=\"tempValue\")" + ; + + /* + * The response returned this time + */ + DiscoverContextAvailabilityResponse d_response_2 = + (DiscoverContextAvailabilityResponse) + (new XmlFactory()).convertFileToXML + ("src/test/resources/entAggTest_d_resp2.xml", + DiscoverContextAvailabilityResponse.class); + + /* + * XPATH to verify request of IoT Broker to agent 1 + */ + String a1_req_eval = + "(/queryContextRequest/entityIdList/entityId//id=\"SensorBoard_A\")" + + " and " + + "(/queryContextRequest/attributeList/attribute=\"tempValue\")" + + " and " + + "(/queryContextRequest/attributeList/attribute=\"humValue\")" + ; + + /* + * The response sent by agent 1 mock + */ + QueryContextResponse a1_response = + (QueryContextResponse) + (new XmlFactory()).convertFileToXML + ("src/test/resources/entAggTest_a1_resp.xml", + QueryContextResponse.class); + + /* + * XPATH to verify request of IoT Broker to agent 2 + */ + String a2_req_eval = + "(/queryContextRequest/entityIdList/entityId//id=\"TempSensor_B\")" + + " and " + + "(/queryContextRequest/attributeList/attribute=\"tempValue\")" + ; + + /* + * The response sent by agent 2 mock + */ + QueryContextResponse a2_response = + (QueryContextResponse) + (new XmlFactory()).convertFileToXML + ("src/test/resources/entAggTest_a2_resp.xml", + QueryContextResponse.class); + + /* + * The expected final response returned by + * IoT Broker + */ + QueryContextResponse b_response = + (QueryContextResponse) + (new XmlFactory()).convertFileToXML + ("src/test/resources/entAggTest_b_resp.xml", + QueryContextResponse.class); + + + + /* + * arm the discovery mock for both requests + */ + + d_client.when(request() + .withMethod("POST") + .withPath("/ngsi9/discoverContextAvailability") + .withBody(xpath( + d_req1_eval + )) + , + exactly(1) + ).respond(response().withBody( + d_response_1.toString() + ).withStatusCode(200) + ); + + d_client.when(request() + .withMethod("POST") + .withPath("/ngsi9/discoverContextAvailability") + .withBody(xpath( + d_req2_eval + )), + exactly(1) + ).respond(response().withBody( + d_response_2.toString() + ).withStatusCode(200) + ); + + /* + * arm the agent mocks + */ + + a1_client.when(request() + .withMethod("POST") + .withBody(xpath( + a1_req_eval + )) + ).respond(response() + .withStatusCode(200) + .withBody(a1_response.toString()) + ); + + a2_client.when(request() + .withMethod("POST") + .withBody(xpath( + a2_req_eval + )) + ).respond(response() + .withStatusCode(200) + .withBody(a2_response.toString()) + ); + + /* + * trigger the test + */ + String actual_b_response_str = sendReqToServer( + b_request.toString(), + B_PORT, + "POST", + "/ngsi10/queryContext"); + + QueryContextResponse actual_b_response = (QueryContextResponse) + (new XmlFactory()).convertStringToXml( + actual_b_response_str, + QueryContextResponse.class); + + + + + /* + * verify what happened at the mock servers + */ + + d_client.verify(request().withBody(xpath(d_req1_eval))); + d_client.verify(request().withBody(xpath(d_req2_eval))); + a1_client.verify(request().withBody(xpath(a1_req_eval))); + a2_client.verify(request().withBody(xpath(a2_req_eval))); + + /* + * verify the response as well + * + * (commented at the moment as on some machines some problems with + * unpredictable order of attributes persist - need to re-work + * the .equals functions first) + */ + //assertEquals(b_response,actual_b_response); + + + } + + + +} diff --git a/iotplatform.iotbroker.blackboxtest/src/test/resources/cl_request.xml b/iotplatform.iotbroker.blackboxtest/src/test/resources/cl_request.xml new file mode 100644 index 00000000..f89ae52e --- /dev/null +++ b/iotplatform.iotbroker.blackboxtest/src/test/resources/cl_request.xml @@ -0,0 +1,11 @@ + + + + + ConferenceRoom + + + + temperature + + \ No newline at end of file diff --git a/iotplatform.iotbroker.blackboxtest/src/test/resources/cl_response.xml b/iotplatform.iotbroker.blackboxtest/src/test/resources/cl_response.xml new file mode 100644 index 00000000..fa618382 --- /dev/null +++ b/iotplatform.iotbroker.blackboxtest/src/test/resources/cl_response.xml @@ -0,0 +1,8 @@ + + + + + 404 + CONTEXT ELEMENT NOT FOUND + + \ No newline at end of file diff --git a/iotplatform.iotbroker.blackboxtest/src/test/resources/d_request.xml b/iotplatform.iotbroker.blackboxtest/src/test/resources/d_request.xml new file mode 100644 index 00000000..5dff5bd3 --- /dev/null +++ b/iotplatform.iotbroker.blackboxtest/src/test/resources/d_request.xml @@ -0,0 +1,19 @@ + + + + + ConferenceRoom + + + + temperature + + + + + IncludeAssociations + SOURCES + + + + diff --git a/iotplatform.iotbroker.blackboxtest/src/test/resources/d_response.xml b/iotplatform.iotbroker.blackboxtest/src/test/resources/d_response.xml new file mode 100644 index 00000000..daacc248 --- /dev/null +++ b/iotplatform.iotbroker.blackboxtest/src/test/resources/d_response.xml @@ -0,0 +1,7 @@ + + + + 400 + CONTEXT ELEMENT NOT FOUND + + \ No newline at end of file diff --git a/iotplatform.iotbroker.blackboxtest/src/test/resources/entAggTest_a1_resp.xml b/iotplatform.iotbroker.blackboxtest/src/test/resources/entAggTest_a1_resp.xml new file mode 100644 index 00000000..0e266deb --- /dev/null +++ b/iotplatform.iotbroker.blackboxtest/src/test/resources/entAggTest_a1_resp.xml @@ -0,0 +1,26 @@ + + + + + + + SensorBoard_A + + + + tempValue + 10 + + + humValue + 70 + + + + + 200 + Ok + + + + \ No newline at end of file diff --git a/iotplatform.iotbroker.blackboxtest/src/test/resources/entAggTest_a2_resp.xml b/iotplatform.iotbroker.blackboxtest/src/test/resources/entAggTest_a2_resp.xml new file mode 100644 index 00000000..20cdb008 --- /dev/null +++ b/iotplatform.iotbroker.blackboxtest/src/test/resources/entAggTest_a2_resp.xml @@ -0,0 +1,22 @@ + + + + + + + TempSensor_B + + + + tempValue + 13 + + + + + 200 + Ok + + + + \ No newline at end of file diff --git a/iotplatform.iotbroker.blackboxtest/src/test/resources/entAggTest_b_req.xml b/iotplatform.iotbroker.blackboxtest/src/test/resources/entAggTest_b_req.xml new file mode 100644 index 00000000..eee02724 --- /dev/null +++ b/iotplatform.iotbroker.blackboxtest/src/test/resources/entAggTest_b_req.xml @@ -0,0 +1,12 @@ + + + + + ConferenceRoom + + + + temperature + humidity + + \ No newline at end of file diff --git a/iotplatform.iotbroker.blackboxtest/src/test/resources/entAggTest_b_resp.xml b/iotplatform.iotbroker.blackboxtest/src/test/resources/entAggTest_b_resp.xml new file mode 100644 index 00000000..37c4b9f4 --- /dev/null +++ b/iotplatform.iotbroker.blackboxtest/src/test/resources/entAggTest_b_resp.xml @@ -0,0 +1,23 @@ + + + + + + + ConferenceRoom + + + + temperature + 11.5 + + + humidity + 70.0 + + + + + + + \ No newline at end of file diff --git a/iotplatform.iotbroker.blackboxtest/src/test/resources/entAggTest_d_resp1.xml b/iotplatform.iotbroker.blackboxtest/src/test/resources/entAggTest_d_resp1.xml new file mode 100644 index 00000000..7e6b3201 --- /dev/null +++ b/iotplatform.iotbroker.blackboxtest/src/test/resources/entAggTest_d_resp1.xml @@ -0,0 +1,58 @@ + + + + + + + + ConferenceRoom + + + + + temperature + false + + + humidity + false + + + + + + aggregationInfo + org.fiware.type.metadata.sourceinformation + + org.fiware.type.sourceinformation.aggregation + + + ConferenceRoom + + + + SensorBoard_A + + + TempSensor_B + + + + + tempValue + temperature + + + humValue + humidity + + + AVG + + + + + + + + \ No newline at end of file diff --git a/iotplatform.iotbroker.blackboxtest/src/test/resources/entAggTest_d_resp2.xml b/iotplatform.iotbroker.blackboxtest/src/test/resources/entAggTest_d_resp2.xml new file mode 100644 index 00000000..392223f3 --- /dev/null +++ b/iotplatform.iotbroker.blackboxtest/src/test/resources/entAggTest_d_resp2.xml @@ -0,0 +1,41 @@ + + + + + + + + SensorBoard_A + + + + + tempValue + false + + + humValue + false + + + http://localhost:8031 + + + + + + + TempSensor_B + + + + + tempValue + false + + + http://localhost:8032 + + + + \ No newline at end of file diff --git a/lib/command.txt b/lib/command.txt new file mode 100644 index 00000000..0c783377 --- /dev/null +++ b/lib/command.txt @@ -0,0 +1,3 @@ +mvn install:install-file -DgroupId=org.apache.httpcomponents -DartifactId=httpclient -Dversion=4.2.0-osgi -Dfile=httpclient-4.2.0-osgi.jar -Dpackaging=jar -DgeneratePom=true + +mvn install:install-file -DgroupId=org.apache.httpcomponents -DartifactId=httpcore -Dversion=4.2.0-osgi -Dfile=httpclient-4.2.0-osgi.jar -Dpackaging=jar -DgeneratePom=true \ No newline at end of file diff --git a/targetPlatform/bundles/catalina-config-3.5.1.jar b/targetPlatform/bundles/catalina-config-3.5.1.jar new file mode 100644 index 00000000..719f9f6e Binary files /dev/null and b/targetPlatform/bundles/catalina-config-3.5.1.jar differ diff --git a/targetPlatform/bundles/catalina.start.osgi-1.0.0.jar b/targetPlatform/bundles/catalina.start.osgi-1.0.0.jar new file mode 100644 index 00000000..df6473bc Binary files /dev/null and b/targetPlatform/bundles/catalina.start.osgi-1.0.0.jar differ diff --git a/targetPlatform/bundles/com.springsource.javax.activation-1.1.1.jar b/targetPlatform/bundles/com.springsource.javax.activation-1.1.1.jar new file mode 100644 index 00000000..bab12494 Binary files /dev/null and b/targetPlatform/bundles/com.springsource.javax.activation-1.1.1.jar differ diff --git a/targetPlatform/bundles/com.springsource.javax.annotation-1.0.0.jar b/targetPlatform/bundles/com.springsource.javax.annotation-1.0.0.jar new file mode 100644 index 00000000..25cdd929 Binary files /dev/null and b/targetPlatform/bundles/com.springsource.javax.annotation-1.0.0.jar differ diff --git a/targetPlatform/bundles/com.springsource.javax.ejb-3.0.0.jar b/targetPlatform/bundles/com.springsource.javax.ejb-3.0.0.jar new file mode 100644 index 00000000..ae0043f4 Binary files /dev/null and b/targetPlatform/bundles/com.springsource.javax.ejb-3.0.0.jar differ diff --git a/targetPlatform/bundles/com.springsource.javax.el-1.0.0.jar b/targetPlatform/bundles/com.springsource.javax.el-1.0.0.jar new file mode 100644 index 00000000..d562de53 Binary files /dev/null and b/targetPlatform/bundles/com.springsource.javax.el-1.0.0.jar differ diff --git a/targetPlatform/bundles/com.springsource.javax.mail-1.4.0.jar b/targetPlatform/bundles/com.springsource.javax.mail-1.4.0.jar new file mode 100644 index 00000000..188fae28 Binary files /dev/null and b/targetPlatform/bundles/com.springsource.javax.mail-1.4.0.jar differ diff --git a/targetPlatform/bundles/com.springsource.javax.persistence-1.0.0.jar b/targetPlatform/bundles/com.springsource.javax.persistence-1.0.0.jar new file mode 100644 index 00000000..9fcc5ae1 Binary files /dev/null and b/targetPlatform/bundles/com.springsource.javax.persistence-1.0.0.jar differ diff --git a/targetPlatform/bundles/com.springsource.javax.servlet-2.5.0.jar b/targetPlatform/bundles/com.springsource.javax.servlet-2.5.0.jar new file mode 100644 index 00000000..27d67da1 Binary files /dev/null and b/targetPlatform/bundles/com.springsource.javax.servlet-2.5.0.jar differ diff --git a/targetPlatform/bundles/com.springsource.javax.servlet.jsp-2.1.0.jar b/targetPlatform/bundles/com.springsource.javax.servlet.jsp-2.1.0.jar new file mode 100644 index 00000000..7a46bbfb Binary files /dev/null and b/targetPlatform/bundles/com.springsource.javax.servlet.jsp-2.1.0.jar differ diff --git a/targetPlatform/bundles/com.springsource.javax.servlet.jsp.jstl-1.1.2.jar b/targetPlatform/bundles/com.springsource.javax.servlet.jsp.jstl-1.1.2.jar new file mode 100644 index 00000000..aeb37d0b Binary files /dev/null and b/targetPlatform/bundles/com.springsource.javax.servlet.jsp.jstl-1.1.2.jar differ diff --git a/targetPlatform/bundles/com.springsource.javax.transaction-1.1.0.jar b/targetPlatform/bundles/com.springsource.javax.transaction-1.1.0.jar new file mode 100644 index 00000000..56a08933 Binary files /dev/null and b/targetPlatform/bundles/com.springsource.javax.transaction-1.1.0.jar differ diff --git a/targetPlatform/bundles/com.springsource.javax.xml.bind-2.0.0.jar b/targetPlatform/bundles/com.springsource.javax.xml.bind-2.0.0.jar new file mode 100644 index 00000000..74d5c866 Binary files /dev/null and b/targetPlatform/bundles/com.springsource.javax.xml.bind-2.0.0.jar differ diff --git a/targetPlatform/bundles/com.springsource.javax.xml.rpc-1.1.0.jar b/targetPlatform/bundles/com.springsource.javax.xml.rpc-1.1.0.jar new file mode 100644 index 00000000..ec328e14 Binary files /dev/null and b/targetPlatform/bundles/com.springsource.javax.xml.rpc-1.1.0.jar differ diff --git a/targetPlatform/bundles/com.springsource.javax.xml.soap-1.3.0.jar b/targetPlatform/bundles/com.springsource.javax.xml.soap-1.3.0.jar new file mode 100644 index 00000000..3c4e4dfa Binary files /dev/null and b/targetPlatform/bundles/com.springsource.javax.xml.soap-1.3.0.jar differ diff --git a/targetPlatform/bundles/com.springsource.javax.xml.stream-1.0.1.jar b/targetPlatform/bundles/com.springsource.javax.xml.stream-1.0.1.jar new file mode 100644 index 00000000..ce68dd7d Binary files /dev/null and b/targetPlatform/bundles/com.springsource.javax.xml.stream-1.0.1.jar differ diff --git a/targetPlatform/bundles/com.springsource.javax.xml.ws-2.1.1.jar b/targetPlatform/bundles/com.springsource.javax.xml.ws-2.1.1.jar new file mode 100644 index 00000000..34f7d12c Binary files /dev/null and b/targetPlatform/bundles/com.springsource.javax.xml.ws-2.1.1.jar differ diff --git a/targetPlatform/bundles/com.springsource.org.aopalliance-1.0.0.jar b/targetPlatform/bundles/com.springsource.org.aopalliance-1.0.0.jar new file mode 100644 index 00000000..3c5cf8bf Binary files /dev/null and b/targetPlatform/bundles/com.springsource.org.aopalliance-1.0.0.jar differ diff --git a/targetPlatform/bundles/com.springsource.org.apache.catalina-6.0.18.jar b/targetPlatform/bundles/com.springsource.org.apache.catalina-6.0.18.jar new file mode 100644 index 00000000..4f031df6 Binary files /dev/null and b/targetPlatform/bundles/com.springsource.org.apache.catalina-6.0.18.jar differ diff --git a/targetPlatform/bundles/com.springsource.org.apache.commons.codec-1.6.0.jar b/targetPlatform/bundles/com.springsource.org.apache.commons.codec-1.6.0.jar new file mode 100644 index 00000000..0c748b77 Binary files /dev/null and b/targetPlatform/bundles/com.springsource.org.apache.commons.codec-1.6.0.jar differ diff --git a/targetPlatform/bundles/com.springsource.org.apache.commons.io-1.4.0.jar b/targetPlatform/bundles/com.springsource.org.apache.commons.io-1.4.0.jar new file mode 100644 index 00000000..1482fdc3 Binary files /dev/null and b/targetPlatform/bundles/com.springsource.org.apache.commons.io-1.4.0.jar differ diff --git a/targetPlatform/bundles/com.springsource.org.apache.commons.logging-1.1.1.jar b/targetPlatform/bundles/com.springsource.org.apache.commons.logging-1.1.1.jar new file mode 100644 index 00000000..f50c78cc Binary files /dev/null and b/targetPlatform/bundles/com.springsource.org.apache.commons.logging-1.1.1.jar differ diff --git a/targetPlatform/bundles/com.springsource.org.apache.coyote-6.0.18.jar b/targetPlatform/bundles/com.springsource.org.apache.coyote-6.0.18.jar new file mode 100644 index 00000000..2e15b490 Binary files /dev/null and b/targetPlatform/bundles/com.springsource.org.apache.coyote-6.0.18.jar differ diff --git a/targetPlatform/bundles/com.springsource.org.apache.el-6.0.18.jar b/targetPlatform/bundles/com.springsource.org.apache.el-6.0.18.jar new file mode 100644 index 00000000..9726d1c9 Binary files /dev/null and b/targetPlatform/bundles/com.springsource.org.apache.el-6.0.18.jar differ diff --git a/targetPlatform/bundles/com.springsource.org.apache.juli.extras-6.0.18.jar b/targetPlatform/bundles/com.springsource.org.apache.juli.extras-6.0.18.jar new file mode 100644 index 00000000..45cb93da Binary files /dev/null and b/targetPlatform/bundles/com.springsource.org.apache.juli.extras-6.0.18.jar differ diff --git a/targetPlatform/bundles/com.springsource.org.apache.log4j-1.2.15.jar b/targetPlatform/bundles/com.springsource.org.apache.log4j-1.2.15.jar new file mode 100644 index 00000000..5db1ea60 Binary files /dev/null and b/targetPlatform/bundles/com.springsource.org.apache.log4j-1.2.15.jar differ diff --git a/targetPlatform/bundles/com.springsource.org.apache.taglibs.standard-1.1.2.jar b/targetPlatform/bundles/com.springsource.org.apache.taglibs.standard-1.1.2.jar new file mode 100644 index 00000000..7c29d1e6 Binary files /dev/null and b/targetPlatform/bundles/com.springsource.org.apache.taglibs.standard-1.1.2.jar differ diff --git a/targetPlatform/bundles/guava-18.0.jar b/targetPlatform/bundles/guava-18.0.jar new file mode 100644 index 00000000..8f89e490 Binary files /dev/null and b/targetPlatform/bundles/guava-18.0.jar differ diff --git a/targetPlatform/bundles/httpclient-4.2.0-osgi.jar b/targetPlatform/bundles/httpclient-4.2.0-osgi.jar new file mode 100644 index 00000000..f892dfef Binary files /dev/null and b/targetPlatform/bundles/httpclient-4.2.0-osgi.jar differ diff --git a/targetPlatform/bundles/httpcore-4.2.0-osgi.jar b/targetPlatform/bundles/httpcore-4.2.0-osgi.jar new file mode 100644 index 00000000..f56a183d Binary files /dev/null and b/targetPlatform/bundles/httpcore-4.2.0-osgi.jar differ diff --git a/targetPlatform/bundles/jasper.osgi-5.5.23-SNAPSHOT.jar b/targetPlatform/bundles/jasper.osgi-5.5.23-SNAPSHOT.jar new file mode 100644 index 00000000..46d20ada Binary files /dev/null and b/targetPlatform/bundles/jasper.osgi-5.5.23-SNAPSHOT.jar differ diff --git a/targetPlatform/bundles/javax.persistence-2.0.0.jar b/targetPlatform/bundles/javax.persistence-2.0.0.jar new file mode 100644 index 00000000..62ee5c35 Binary files /dev/null and b/targetPlatform/bundles/javax.persistence-2.0.0.jar differ diff --git a/targetPlatform/bundles/log4j-config.jar b/targetPlatform/bundles/log4j-config.jar new file mode 100644 index 00000000..25e493ec Binary files /dev/null and b/targetPlatform/bundles/log4j-config.jar differ diff --git a/targetPlatform/db/hsqldb_1.0.0.jar b/targetPlatform/db/hsqldb_1.0.0.jar new file mode 100644 index 00000000..38d9768b Binary files /dev/null and b/targetPlatform/db/hsqldb_1.0.0.jar differ diff --git a/targetPlatform/equinox/org.eclipse.core.contenttype-3.4.100.v20100505-1235.jar b/targetPlatform/equinox/org.eclipse.core.contenttype-3.4.100.v20100505-1235.jar new file mode 100644 index 00000000..b03a4517 Binary files /dev/null and b/targetPlatform/equinox/org.eclipse.core.contenttype-3.4.100.v20100505-1235.jar differ diff --git a/targetPlatform/equinox/org.eclipse.core.jobs-3.5.0.v20100515.jar b/targetPlatform/equinox/org.eclipse.core.jobs-3.5.0.v20100515.jar new file mode 100644 index 00000000..c1455727 Binary files /dev/null and b/targetPlatform/equinox/org.eclipse.core.jobs-3.5.0.v20100515.jar differ diff --git a/targetPlatform/equinox/org.eclipse.equinox.app-1.3.0.v20100512.jar b/targetPlatform/equinox/org.eclipse.equinox.app-1.3.0.v20100512.jar new file mode 100644 index 00000000..1d0bae1e Binary files /dev/null and b/targetPlatform/equinox/org.eclipse.equinox.app-1.3.0.v20100512.jar differ diff --git a/targetPlatform/equinox/org.eclipse.equinox.cm_3.2.0.v20070116.jar b/targetPlatform/equinox/org.eclipse.equinox.cm_3.2.0.v20070116.jar new file mode 100644 index 00000000..93c9dd4b Binary files /dev/null and b/targetPlatform/equinox/org.eclipse.equinox.cm_3.2.0.v20070116.jar differ diff --git a/targetPlatform/equinox/org.eclipse.equinox.common-3.6.0.v20110506.jar b/targetPlatform/equinox/org.eclipse.equinox.common-3.6.0.v20110506.jar new file mode 100644 index 00000000..bd7ac9b1 Binary files /dev/null and b/targetPlatform/equinox/org.eclipse.equinox.common-3.6.0.v20110506.jar differ diff --git a/targetPlatform/equinox/org.eclipse.equinox.preferences-3.3.0.v20100503.jar b/targetPlatform/equinox/org.eclipse.equinox.preferences-3.3.0.v20100503.jar new file mode 100644 index 00000000..b902bcb9 Binary files /dev/null and b/targetPlatform/equinox/org.eclipse.equinox.preferences-3.3.0.v20100503.jar differ diff --git a/targetPlatform/equinox/org.eclipse.equinox.registry-3.5.0.v20100503.jar b/targetPlatform/equinox/org.eclipse.equinox.registry-3.5.0.v20100503.jar new file mode 100644 index 00000000..935717b9 Binary files /dev/null and b/targetPlatform/equinox/org.eclipse.equinox.registry-3.5.0.v20100503.jar differ diff --git a/targetPlatform/equinox/org.eclipse.osgi.services-3.2.100.v20100503.jar b/targetPlatform/equinox/org.eclipse.osgi.services-3.2.100.v20100503.jar new file mode 100644 index 00000000..e7aeacd9 Binary files /dev/null and b/targetPlatform/equinox/org.eclipse.osgi.services-3.2.100.v20100503.jar differ diff --git a/targetPlatform/jaxb/jaxb-impl-2.1.5_1.0.0.jar b/targetPlatform/jaxb/jaxb-impl-2.1.5_1.0.0.jar new file mode 100644 index 00000000..dd27296a Binary files /dev/null and b/targetPlatform/jaxb/jaxb-impl-2.1.5_1.0.0.jar differ diff --git a/targetPlatform/json/gson-2.2.2.jar b/targetPlatform/json/gson-2.2.2.jar new file mode 100644 index 00000000..f2108e00 Binary files /dev/null and b/targetPlatform/json/gson-2.2.2.jar differ diff --git a/targetPlatform/json/jackson-core-asl-1.9.2.jar b/targetPlatform/json/jackson-core-asl-1.9.2.jar new file mode 100644 index 00000000..c5065672 Binary files /dev/null and b/targetPlatform/json/jackson-core-asl-1.9.2.jar differ diff --git a/targetPlatform/json/jackson-mapper-asl-1.9.2.jar b/targetPlatform/json/jackson-mapper-asl-1.9.2.jar new file mode 100644 index 00000000..6407dc05 Binary files /dev/null and b/targetPlatform/json/jackson-mapper-asl-1.9.2.jar differ diff --git a/targetPlatform/json/org.json_1.0.0.jar b/targetPlatform/json/org.json_1.0.0.jar new file mode 100644 index 00000000..574eb7a9 Binary files /dev/null and b/targetPlatform/json/org.json_1.0.0.jar differ diff --git a/targetPlatform/monitor/javamelodybundle_1.0.0.jar b/targetPlatform/monitor/javamelodybundle_1.0.0.jar new file mode 100644 index 00000000..548237d2 Binary files /dev/null and b/targetPlatform/monitor/javamelodybundle_1.0.0.jar differ diff --git a/targetPlatform/monitor/jrobin_1.5.9.1.jar b/targetPlatform/monitor/jrobin_1.5.9.1.jar new file mode 100644 index 00000000..3e4d1464 Binary files /dev/null and b/targetPlatform/monitor/jrobin_1.5.9.1.jar differ diff --git a/targetPlatform/pax/pax-confman-propsloader-0.2.2.jar b/targetPlatform/pax/pax-confman-propsloader-0.2.2.jar new file mode 100644 index 00000000..54bc8aeb Binary files /dev/null and b/targetPlatform/pax/pax-confman-propsloader-0.2.2.jar differ diff --git a/targetPlatform/pax/pax-logging-api-1.7.0-20120710.130402-38.jar b/targetPlatform/pax/pax-logging-api-1.7.0-20120710.130402-38.jar new file mode 100644 index 00000000..d032827f Binary files /dev/null and b/targetPlatform/pax/pax-logging-api-1.7.0-20120710.130402-38.jar differ diff --git a/targetPlatform/pax/pax-logging-service-1.7.0-20120710.130445-38.jar b/targetPlatform/pax/pax-logging-service-1.7.0-20120710.130445-38.jar new file mode 100644 index 00000000..2da9dbdc Binary files /dev/null and b/targetPlatform/pax/pax-logging-service-1.7.0-20120710.130445-38.jar differ diff --git a/targetPlatform/spring 3.2.3/org.springframework.aop-3.2.3.RELEASE.jar b/targetPlatform/spring 3.2.3/org.springframework.aop-3.2.3.RELEASE.jar new file mode 100644 index 00000000..88d52e2a Binary files /dev/null and b/targetPlatform/spring 3.2.3/org.springframework.aop-3.2.3.RELEASE.jar differ diff --git a/targetPlatform/spring 3.2.3/org.springframework.aspects-3.2.3.RELEASE.jar b/targetPlatform/spring 3.2.3/org.springframework.aspects-3.2.3.RELEASE.jar new file mode 100644 index 00000000..bf4abd66 Binary files /dev/null and b/targetPlatform/spring 3.2.3/org.springframework.aspects-3.2.3.RELEASE.jar differ diff --git a/targetPlatform/spring 3.2.3/org.springframework.beans-3.2.3.RELEASE.jar b/targetPlatform/spring 3.2.3/org.springframework.beans-3.2.3.RELEASE.jar new file mode 100644 index 00000000..664d5a6d Binary files /dev/null and b/targetPlatform/spring 3.2.3/org.springframework.beans-3.2.3.RELEASE.jar differ diff --git a/targetPlatform/spring 3.2.3/org.springframework.context-3.2.3.RELEASE.jar b/targetPlatform/spring 3.2.3/org.springframework.context-3.2.3.RELEASE.jar new file mode 100644 index 00000000..ab057d15 Binary files /dev/null and b/targetPlatform/spring 3.2.3/org.springframework.context-3.2.3.RELEASE.jar differ diff --git a/targetPlatform/spring 3.2.3/org.springframework.context.support-3.2.3.RELEASE.jar b/targetPlatform/spring 3.2.3/org.springframework.context.support-3.2.3.RELEASE.jar new file mode 100644 index 00000000..1f19e298 Binary files /dev/null and b/targetPlatform/spring 3.2.3/org.springframework.context.support-3.2.3.RELEASE.jar differ diff --git a/targetPlatform/spring 3.2.3/org.springframework.core-3.2.3.RELEASE.jar b/targetPlatform/spring 3.2.3/org.springframework.core-3.2.3.RELEASE.jar new file mode 100644 index 00000000..7c6c9226 Binary files /dev/null and b/targetPlatform/spring 3.2.3/org.springframework.core-3.2.3.RELEASE.jar differ diff --git a/targetPlatform/spring 3.2.3/org.springframework.expression-3.2.3.RELEASE.jar b/targetPlatform/spring 3.2.3/org.springframework.expression-3.2.3.RELEASE.jar new file mode 100644 index 00000000..6185112d Binary files /dev/null and b/targetPlatform/spring 3.2.3/org.springframework.expression-3.2.3.RELEASE.jar differ diff --git a/targetPlatform/spring 3.2.3/org.springframework.jdbc-3.2.3.RELEASE.jar b/targetPlatform/spring 3.2.3/org.springframework.jdbc-3.2.3.RELEASE.jar new file mode 100644 index 00000000..00a0308d Binary files /dev/null and b/targetPlatform/spring 3.2.3/org.springframework.jdbc-3.2.3.RELEASE.jar differ diff --git a/targetPlatform/spring 3.2.3/org.springframework.orm-3.2.3.RELEASE.jar b/targetPlatform/spring 3.2.3/org.springframework.orm-3.2.3.RELEASE.jar new file mode 100644 index 00000000..77bf7772 Binary files /dev/null and b/targetPlatform/spring 3.2.3/org.springframework.orm-3.2.3.RELEASE.jar differ diff --git a/targetPlatform/spring 3.2.3/org.springframework.oxm-3.2.3.RELEASE.jar b/targetPlatform/spring 3.2.3/org.springframework.oxm-3.2.3.RELEASE.jar new file mode 100644 index 00000000..23f08d73 Binary files /dev/null and b/targetPlatform/spring 3.2.3/org.springframework.oxm-3.2.3.RELEASE.jar differ diff --git a/targetPlatform/spring 3.2.3/org.springframework.security.config-3.1.4.RELEASE.jar b/targetPlatform/spring 3.2.3/org.springframework.security.config-3.1.4.RELEASE.jar new file mode 100644 index 00000000..761cd1e8 Binary files /dev/null and b/targetPlatform/spring 3.2.3/org.springframework.security.config-3.1.4.RELEASE.jar differ diff --git a/targetPlatform/spring 3.2.3/org.springframework.security.core-3.1.4.RELEASE.jar b/targetPlatform/spring 3.2.3/org.springframework.security.core-3.1.4.RELEASE.jar new file mode 100644 index 00000000..8a6171f7 Binary files /dev/null and b/targetPlatform/spring 3.2.3/org.springframework.security.core-3.1.4.RELEASE.jar differ diff --git a/targetPlatform/spring 3.2.3/org.springframework.security.web-3.1.4.RELEASE.jar b/targetPlatform/spring 3.2.3/org.springframework.security.web-3.1.4.RELEASE.jar new file mode 100644 index 00000000..4f954d47 Binary files /dev/null and b/targetPlatform/spring 3.2.3/org.springframework.security.web-3.1.4.RELEASE.jar differ diff --git a/targetPlatform/spring 3.2.3/org.springframework.transaction-3.2.3.RELEASE.jar b/targetPlatform/spring 3.2.3/org.springframework.transaction-3.2.3.RELEASE.jar new file mode 100644 index 00000000..12311f27 Binary files /dev/null and b/targetPlatform/spring 3.2.3/org.springframework.transaction-3.2.3.RELEASE.jar differ diff --git a/targetPlatform/spring 3.2.3/org.springframework.web-3.2.3.RELEASE.jar b/targetPlatform/spring 3.2.3/org.springframework.web-3.2.3.RELEASE.jar new file mode 100644 index 00000000..828847f5 Binary files /dev/null and b/targetPlatform/spring 3.2.3/org.springframework.web-3.2.3.RELEASE.jar differ diff --git a/targetPlatform/spring 3.2.3/org.springframework.web.servlet-3.2.3.RELEASE.jar b/targetPlatform/spring 3.2.3/org.springframework.web.servlet-3.2.3.RELEASE.jar new file mode 100644 index 00000000..1366068d Binary files /dev/null and b/targetPlatform/spring 3.2.3/org.springframework.web.servlet-3.2.3.RELEASE.jar differ diff --git a/targetPlatform/spring DM/spring-osgi-annotation-2.0.0.M1.jar b/targetPlatform/spring DM/spring-osgi-annotation-2.0.0.M1.jar new file mode 100644 index 00000000..d57dc75f Binary files /dev/null and b/targetPlatform/spring DM/spring-osgi-annotation-2.0.0.M1.jar differ diff --git a/targetPlatform/spring DM/spring-osgi-core-2.0.0.M1.jar b/targetPlatform/spring DM/spring-osgi-core-2.0.0.M1.jar new file mode 100644 index 00000000..dc3df54c Binary files /dev/null and b/targetPlatform/spring DM/spring-osgi-core-2.0.0.M1.jar differ diff --git a/targetPlatform/spring DM/spring-osgi-extender-2.0.0.M1.jar b/targetPlatform/spring DM/spring-osgi-extender-2.0.0.M1.jar new file mode 100644 index 00000000..e48f672a Binary files /dev/null and b/targetPlatform/spring DM/spring-osgi-extender-2.0.0.M1.jar differ diff --git a/targetPlatform/spring DM/spring-osgi-io-2.0.0.M1.jar b/targetPlatform/spring DM/spring-osgi-io-2.0.0.M1.jar new file mode 100644 index 00000000..284886bb Binary files /dev/null and b/targetPlatform/spring DM/spring-osgi-io-2.0.0.M1.jar differ diff --git a/targetPlatform/spring DM/spring-osgi-mock-2.0.0.M1.jar b/targetPlatform/spring DM/spring-osgi-mock-2.0.0.M1.jar new file mode 100644 index 00000000..f558fb80 Binary files /dev/null and b/targetPlatform/spring DM/spring-osgi-mock-2.0.0.M1.jar differ diff --git a/targetPlatform/spring DM/spring-osgi-test-2.0.0.M1.jar b/targetPlatform/spring DM/spring-osgi-test-2.0.0.M1.jar new file mode 100644 index 00000000..807c7697 Binary files /dev/null and b/targetPlatform/spring DM/spring-osgi-test-2.0.0.M1.jar differ diff --git a/targetPlatform/spring DM/spring-osgi-web-2.0.0.M1.jar b/targetPlatform/spring DM/spring-osgi-web-2.0.0.M1.jar new file mode 100644 index 00000000..7d4e590c Binary files /dev/null and b/targetPlatform/spring DM/spring-osgi-web-2.0.0.M1.jar differ diff --git a/targetPlatform/spring DM/spring-osgi-web-extender-2.0.0.M1.jar b/targetPlatform/spring DM/spring-osgi-web-extender-2.0.0.M1.jar new file mode 100644 index 00000000..4c17a4cd Binary files /dev/null and b/targetPlatform/spring DM/spring-osgi-web-extender-2.0.0.M1.jar differ diff --git a/tomcat-configuration-fragment/pom.xml b/tomcat-configuration-fragment/pom.xml index 8a5e7aa6..2fca5c17 100644 --- a/tomcat-configuration-fragment/pom.xml +++ b/tomcat-configuration-fragment/pom.xml @@ -3,7 +3,7 @@ eu.neclab.iotplatform IoTbrokerParent - 4.3.3-SNAPSHOT + 4.4.3 ../IoTbrokerParent 4.0.0