Merge pull request #138 from GPrathap/master

refactored cdmf-devicetype-archetype maven archetype
application-manager-new
sumedharubasinghe 9 years ago
commit 2e85e030c4

@ -19,6 +19,7 @@
<archetype-descriptor name="${deviceType}">
<requiredProperties>
<requiredProperty key="deviceType"></requiredProperty>
<requiredProperty key="nameOfTheSensor"></requiredProperty>
</requiredProperties>
<modules>
<module id="${rootArtifactId}-component" dir="component" name="${rootArtifactId}-component">
@ -87,6 +88,8 @@
<include>**/*.sh</include>
<include>**/*.hbs</include>
<include>**/*.py</include>
<include>**/*-view.js</include>
<include>**/*-graph.js</include>
</includes>
</fileSet>
<fileSet filtered="false" encoding="UTF-8">
@ -99,6 +102,29 @@
</fileSet>
</fileSets>
</module>
<module id="${groupId}.${rootArtifactId}.analytics" dir="analytics"
name="${groupId}.${rootArtifactId}.analytics">
<fileSets>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/assembly</directory>
<includes>
<include>**/*.xml</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/resources/carbonapps</directory>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory></directory>
<includes>
<include>build.xml</include>
</includes>
</fileSet>
</fileSets>
</module>
</modules>
</module>
<module id="${rootArtifactId}-feature" dir="feature" name="${rootArtifactId}-feature">

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/-->
<project name="create-sample-sensor-capps" default="zip" basedir=".">
<property name="project-name" value="${ant.project.name}"/>
<property name="target-dir" value="target/carbonapps"/>
<property name="src-dir" value="src/main/resources/carbonapps"/>
<property name="sensor_dir" value="${nameOfTheSensor}"/>
<target name="clean">
<delete dir="${target-dir}" />
</target>
<target name="zip" depends="clean">
<mkdir dir="${target-dir}"/>
<zip destfile="${target-dir}/${sensor_dir}.car">
<zipfileset dir="${src-dir}/${sensor_dir}"/>
</zip>
</target>
</project>

@ -0,0 +1,86 @@
<!--/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>${groupId}</groupId>
<artifactId>${rootArtifactId}-component</artifactId>
<version>${version}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>${artifactId}</artifactId>
<version>${version}</version>
<packaging>pom</packaging>
<name> ${artifactId} </name>
<url>http://wso2.org</url>
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>${maven-clean-plugin.version}</version>
<executions>
<execution>
<id>auto-clean</id>
<phase>initialize</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>${wso2.maven.compiler.source}</version>
<executions>
<execution>
<phase>process-resources</phase>
<configuration>
<target>
<ant antfile="build.xml" target="zip"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>${maven-assembly-plugin.version}</version>
<configuration>
<finalName>${project.artifactId}-${version}</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/assembly/src.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>create-archive</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,36 @@
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>src</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<baseDirectory>${basedir}/src</baseDirectory>
<fileSets>
<fileSet>
<directory>${basedir}/target/carbonapps</directory>
<outputDirectory>/</outputDirectory>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>
</assembly>

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<eventPublisher name="EventPublisher_${nameOfTheSensor}" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventpublisher">
<from streamName="org.wso2.iot.devices.${nameOfTheSensor}" version="1.0.0"/>
<mapping customMapping="disable" type="wso2event"/>
<to eventAdapterType="iot-ui"/>
</eventPublisher>

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<artifact name="Eventpublisher_${nameOfTheSensor}" version="1.0.0" type="event/publisher" serverRole="DataAnalyticsServer">
<file>EventPublisher_${nameOfTheSensor}.xml</file>
</artifact>

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<eventReceiver name="${nameOfTheSensor}-mqtt" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver">
<from eventAdapterType="oauth-mqtt">
<property name="topic">carbon.super/${deviceType}/+/publisher</property>
<property name="username">admin</property>
<property name="contentValidatorParams">device_id_json_path:event.metaData.deviceId,device_id_topic_hierarchy_index:2</property>
<property name="contentValidator">org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.util.MQTTContentValidator</property>
<property name="contentTransformer">default</property>
<property name="dcrUrl">https://localhost:${carbon.https.port}/dynamic-client-web/register</property>
<property name="url">tcp://${mqtt.broker.host}:${mqtt.broker.port}</property>
<property name="cleanSession">true</property>
</from>
<mapping customMapping="disable" type="json"/>
<to streamName="org.wso2.iot.devices.${nameOfTheSensor}" version="1.0.0"/>
</eventReceiver>

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<artifact name="Eventreceiver_mqtt_${nameOfTheSensor}" version="1.0.0" type="event/receiver" serverRole="DataAnalyticsServer">
<file>EventReceiver_mqtt_${nameOfTheSensor}.xml</file>
</artifact>

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<artifact name="Eventstore_${nameOfTheSensor}" version="1.0.0" type="analytics/eventstore" serverRole="DataAnalyticsServer">
<file>org_wso2_iot_devices_${nameOfTheSensor}.xml</file>
</artifact>

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<EventStoreConfiguration>
<Source>
<StreamId>org.wso2.iot.devices.${nameOfTheSensor}:1.0.0</StreamId>
</Source>
<RecordStoreName>EVENT_STORE</RecordStoreName>
<TableSchema>
<ColumnDefinition>
<Name>meta_owner</Name>
<EnableIndexing>true</EnableIndexing>
<IsPrimaryKey>true</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>STRING</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>meta_deviceType</Name>
<EnableIndexing>true</EnableIndexing>
<IsPrimaryKey>true</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>STRING</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>meta_deviceId</Name>
<EnableIndexing>true</EnableIndexing>
<IsPrimaryKey>true</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>STRING</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>meta_time</Name>
<EnableIndexing>true</EnableIndexing>
<IsPrimaryKey>true</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>LONG</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>${nameOfTheSensor}</Name>
<EnableIndexing>false</EnableIndexing>
<IsPrimaryKey>false</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>FLOAT</Type>
</ColumnDefinition>
</TableSchema>
</EventStoreConfiguration>

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<artifact name="Eventstream_${nameOfTheSensor}" version="1.0.0" type="event/stream" serverRole="DataAnalyticsServer">
<file>org.wso2.iot.devices.${nameOfTheSensor}_1.0.0.json</file>
</artifact>

@ -0,0 +1,20 @@
{
"name": "org.wso2.iot.devices.${nameOfTheSensor}",
"version": "1.0.0",
"nickName": "${nameOfTheSensor}",
"description": "${nameOfTheSensor} data received from the Device",
"metaData": [
{"name":"owner","type":"STRING"},
{"name":"deviceType","type":"STRING"},
{"name":"deviceId","type":"STRING"},
{"name":"time","type":"LONG"}
],
"payloadData": [
{
"name": "${nameOfTheSensor}","type": "FLOAT"
}
]
}

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<Analytics>
<Name>IoTServer_Sensor_Script</Name>
<Script>
CREATE TEMPORARY TABLE Device${nameOfTheSensor}Data USING CarbonAnalytics OPTIONS(tableName "ORG_WSO2_IOT_DEVICES_${nameOfTheSensor}");
CREATE TEMPORARY TABLE Device${nameOfTheSensor}SummaryData USING CarbonAnalytics OPTIONS (tableName "DEVICE_${nameOfTheSensor}_SUMMARY", schema "${nameOfTheSensor} FLOAT, deviceType STRING -i, deviceId STRING -i, owner STRING -i, time LONG -i",primaryKeys "deviceType, deviceId, owner, time");
insert overwrite table Device${nameOfTheSensor}SummaryData select ${nameOfTheSensor}, meta_deviceType as deviceType, meta_deviceId as deviceId, meta_owner as owner, cast(meta_time/1000 as BIGINT)as time from Device${nameOfTheSensor}Data group by ${nameOfTheSensor}, meta_deviceType, meta_deviceId, meta_owner, cast(meta_time/1000 as BIGINT);
</Script>
<CronExpression>0 * * * * ?</CronExpression>
</Analytics>

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<artifact name="Sparkscripts" version="1.0.0" type="analytics/spark" serverRole="DataAnalyticsServer">
<file>${nameOfTheSensor}_Script.xml</file>
</artifact>

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<artifacts>
<artifact name="${nameOfTheSensor}_CAPP" version="1.0.0" type="carbon/application">
<dependency artifact="Eventstream_${nameOfTheSensor}" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
<dependency artifact="Eventstore_${nameOfTheSensor}" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
<dependency artifact="Eventreceiver_mqtt_${nameOfTheSensor}" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
<dependency artifact="Eventpublisher_${nameOfTheSensor}" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
<dependency artifact="Sparkscripts" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
</artifact>
</artifacts>

@ -144,11 +144,6 @@
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.apimgt.webapp.publisher</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics</groupId>
<artifactId>org.wso2.carbon.analytics.api</artifactId>

@ -1,201 +0,0 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package ${groupId}.${rootArtifactId}.api;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import ${groupId}.${rootArtifactId}.api.util.APIUtil;
import ${groupId}.${rootArtifactId}.plugin.constants.DeviceTypeConstants;
import ${groupId}.${rootArtifactId}.api.dto.DeviceJSON;
import ${groupId}.${rootArtifactId}.api.transport.MQTTConnector;
import ${groupId}.${rootArtifactId}.api.dto.SensorRecord;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.analytics.dataservice.commons.SortByField;
import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import org.wso2.carbon.analytics.dataservice.commons.SORT;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.DeviceType;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.Feature;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.service.IoTServerStartupListener;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.PathParam;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
* This is the controller API which is used to control agent side functionality
*/
@SuppressWarnings("NonJaxWsWebServices")
@API(name = "${deviceType}", version = "1.0.0", context = "/${deviceType}", tags = "${deviceType}")
@DeviceType(value = "${deviceType}")
public class ControllerServiceImpl implements ControllerService{
private static Log log = LogFactory.getLog(ControllerService.class);
private MQTTConnector mqttConnector;
private ConcurrentHashMap<String, DeviceJSON> deviceToIpMap = new ConcurrentHashMap<>();
private boolean waitForServerStartup() {
while (!IoTServerStartupListener.isServerReady()) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
return true;
}
}
return false;
}
public MQTTConnector getMQTTConnector() {
return mqttConnector;
}
public void setMQTTConnector(final MQTTConnector MQTTConnector) {
Runnable connector = new Runnable() {
public void run() {
if (waitForServerStartup()) {
return;
}
//The delay is added for the server to starts up.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
ControllerServiceImpl.this.mqttConnector = MQTTConnector;
if (MqttConfig.getInstance().isEnabled()) {
mqttConnector.connect();
} else {
log.warn("MQTT disabled in 'devicemgt-config.xml'. Hence, MQTTConnector" +
" not started.");
}
}
};
Thread connectorThread = new Thread(connector);
connectorThread.setDaemon(true);
connectorThread.start();
}
/**
* @param agentInfo device owner,id and sensor value
* @return
*/
@Path("device/register")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response registerDevice(final DeviceJSON agentInfo) {
String deviceId = agentInfo.deviceId;
if ((agentInfo.deviceId != null) && (agentInfo.owner != null)) {
deviceToIpMap.put(deviceId, agentInfo);
return Response.status(Response.Status.OK).build();
}
return Response.status(Response.Status.NOT_ACCEPTABLE).build();
}
/**
* @param deviceId unique identifier for given device type
* @param state change status of sensor: on/off
* @param response
*/
@Path("device/{deviceId}/change-status")
@POST
@Feature(code = "change-status", name = "Change status of sensor: on/off", type = "operation",
description = "Change status of sensor: on/off")
public Response changeStatus(@PathParam("deviceId") String deviceId,
@QueryParam("state") String state,
@Context HttpServletResponse response) {
try {
if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(new DeviceIdentifier(deviceId,
DeviceTypeConstants.DEVICE_TYPE))) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
String sensorState = state.toUpperCase();
if (!sensorState.equals(DeviceTypeConstants.STATE_ON) && !sensorState.equals(
DeviceTypeConstants.STATE_OFF)) {
log.error("The requested state change should be either - 'ON' or 'OFF'");
return Response.status(Response.Status.BAD_REQUEST.getStatusCode()).build();
}
String mqttResource = DeviceTypeConstants.SENSOR_CONTEXT.replace("/", "");
mqttConnector.publishDeviceData(deviceId, mqttResource, sensorState);
return Response.ok().build();
} catch (TransportHandlerException e) {
log.error("Failed to send switch-bulb request to device [" + deviceId + "]");
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (DeviceAccessAuthorizationException e) {
log.error(e.getErrorMessage(), e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
}
/**
* Retrieve Sensor data for the ${deviceType}
*/
@Path("device/stats/{deviceId}")
@GET
@Consumes("application/json")
@Produces("application/json")
public Response getSensorStats(@PathParam("deviceId") String deviceId, @QueryParam("from") long from,
@QueryParam("to") long to){
String fromDate = String.valueOf(from);
String toDate = String.valueOf(to);
String query = "deviceId:" + deviceId + " AND deviceType:" +
DeviceTypeConstants.DEVICE_TYPE + " AND time : [" + fromDate + " TO " + toDate + "]";
String sensorTableName = DeviceTypeConstants.TEMPERATURE_EVENT_TABLE;
try {
if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(new DeviceIdentifier(deviceId,
DeviceTypeConstants.DEVICE_TYPE))) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
if (sensorTableName != null) {
List<SortByField> sortByFields = new ArrayList<>();
SortByField sortByField = new SortByField("time", SORT.ASC, false);
sortByFields.add(sortByField);
List<SensorRecord> sensorRecords = APIUtil.getAllEventsForDevice(sensorTableName, query, sortByFields);
return Response.status(Response.Status.OK.getStatusCode()).entity(sensorRecords).build();
}
} catch (AnalyticsException e) {
String errorMsg = "Error on retrieving stats on table " + sensorTableName + " with query " + query;
log.error(errorMsg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(errorMsg).build();
} catch (DeviceAccessAuthorizationException e) {
log.error(e.getErrorMessage(), e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
return Response.status(Response.Status.BAD_REQUEST).build();
}
}

@ -18,29 +18,23 @@
package ${groupId}.${rootArtifactId}.api;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import ${groupId}.${rootArtifactId}.api.dto.DeviceJSON;
import ${groupId}.${rootArtifactId}.api.transport.MQTTConnector;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.DeviceType;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.Feature;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.service.IoTServerStartupListener;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Path;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.PUT;
import javax.ws.rs.DELETE;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@ -52,7 +46,7 @@ import javax.ws.rs.core.Response;
@SuppressWarnings("NonJaxWsWebServices")
@API(name = "${deviceType}", version = "1.0.0", context = "/${deviceType}", tags = "${deviceType}")
@DeviceType(value = "${deviceType}")
public interface ControllerService {
public interface DeviceTypeService {
/**
* @param agentInfo device owner,id and sensor value
@ -61,6 +55,7 @@ public interface ControllerService {
@Path("device/register")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Permission(scope = "${deviceType}_user", permissions = {"/permission/admin/device-mgt/user/register"})
Response registerDevice(final DeviceJSON agentInfo);
/**
@ -70,11 +65,12 @@ public interface ControllerService {
*/
@Path("device/{deviceId}/change-status")
@POST
@Feature(code = "change-status", name = "Change status of sensor: on/off", type = "operation",
@Feature(code = "change-status", name = "Change status of sensor: on/off",
description = "Change status of sensor: on/off")
@Permission(scope = "${deviceType}_user", permissions = {"/permission/admin/device-mgt/change-status"})
Response changeStatus(@PathParam("deviceId") String deviceId,
@QueryParam("state") String state,
@Context HttpServletResponse response);
@QueryParam("state") String state,
@Context HttpServletResponse response);
/**
* Retrieve Sensor data for the ${deviceType}
@ -83,8 +79,37 @@ public interface ControllerService {
@GET
@Consumes("application/json")
@Produces("application/json")
@Permission(scope = "${deviceType}_user", permissions = {"/permission/admin/device-mgt/stats"})
Response getSensorStats(@PathParam("deviceId") String deviceId, @QueryParam("from") long from,
@QueryParam("to") long to);
@QueryParam("to") long to);
@Path("/device/{device_id}")
@DELETE
@Permission(scope = "${deviceType}_user", permissions = {"/permission/admin/device-mgt/removeDevice"})
Response removeDevice(@PathParam("device_id") String deviceId);
@Path("/device/{device_id}")
@PUT
@Permission(scope = "${deviceType}_user", permissions = {"/permission/admin/device-mgt/updateDevice"})
Response updateDevice(@PathParam("device_id") String deviceId, @QueryParam("name") String name);
@Path("/device/{device_id}")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Permission(scope = "${deviceType}_user", permissions = {"/permission/admin/device-mgt/updateDevice"})
Response getDevice(@PathParam("device_id") String deviceId);
@Path("/devices")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Permission(scope = "${deviceType}_user", permissions = {"/permission/admin/device-mgt/devices"})
Response getAllDevices();
@Path("/device/download")
@GET
@Produces("application/zip")
@Permission(scope = "${deviceType}_user", permissions = {"/permission/admin/device-mgt/download"})
Response downloadSketch(@QueryParam("deviceName") String deviceName, @QueryParam("sketchType") String sketchType);
}

@ -1,29 +1,37 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package ${groupId}.${rootArtifactId}.api;
import ${groupId}.${rootArtifactId}.api.util.ZipUtil;
import ${groupId}.${rootArtifactId}.api.dto.DeviceJSON;
import ${groupId}.${rootArtifactId}.api.dto.SensorRecord;
import ${groupId}.${rootArtifactId}.api.util.APIUtil;
import ${groupId}.${rootArtifactId}.api.util.ZipUtil;
import ${groupId}.${rootArtifactId}.plugin.constants.DeviceTypeConstants;
import ${groupId}.${rootArtifactId}.api.DeviceTypeService;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.analytics.dataservice.commons.SORT;
import org.wso2.carbon.analytics.dataservice.commons.SortByField;
import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey;
import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException;
@ -33,30 +41,52 @@ import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.DeviceType;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.Feature;
import org.wso2.carbon.device.mgt.iot.util.ZipArchive;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.user.api.UserStoreException;
import javax.ws.rs.*;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Path;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Produces;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.PUT;
import javax.ws.rs.DELETE;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
import java.util.Map;
import java.util.List;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@Path("enrollment")
public class ManagerServiceImpl implements ManagerService {
/**
* This is the controller API which is used to control agent side functionality
*/
@SuppressWarnings("NonJaxWsWebServices")
@API(name = "${deviceType}", version = "1.0.0", context = "/${deviceType}", tags = "${deviceType}")
@DeviceType(value = "${deviceType}")
public class DeviceTypeServiceImpl implements DeviceTypeService {
private static final String KEY_TYPE = "PRODUCTION";
private static Log log = LogFactory.getLog(DeviceTypeService.class);
private static ApiApplicationKey apiApplicationKey;
private static Log log = LogFactory.getLog(ManagerServiceImpl.class);
private ConcurrentHashMap<String, DeviceJSON> deviceToIpMap = new ConcurrentHashMap<>();
private static String shortUUID() {
UUID uuid = UUID.randomUUID();
@ -64,7 +94,96 @@ public class ManagerServiceImpl implements ManagerService {
return Long.toString(l, Character.MAX_RADIX);
}
@Path("/devices/{device_id}")
/**
* @param agentInfo device owner,id and sensor value
* @return
*/
@Path("device/register")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response registerDevice(final DeviceJSON agentInfo) {
String deviceId = agentInfo.deviceId;
if ((agentInfo.deviceId != null) && (agentInfo.owner != null)) {
deviceToIpMap.put(deviceId, agentInfo);
return Response.status(Response.Status.OK).build();
}
return Response.status(Response.Status.NOT_ACCEPTABLE).build();
}
/**
* @param deviceId unique identifier for given device type
* @param state change status of sensor: on/off
* @param response
*/
@Path("device/{deviceId}/change-status")
@POST
@Feature(code = "change-status", name = "Change status of sensor: on/off",
description = "Change status of sensor: on/off")
public Response changeStatus(@PathParam("deviceId") String deviceId,
@QueryParam("state") String state,
@Context HttpServletResponse response) {
try {
if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(new DeviceIdentifier(deviceId,
DeviceTypeConstants.DEVICE_TYPE))) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
String sensorState = state.toUpperCase();
if (!sensorState.equals(DeviceTypeConstants.STATE_ON) && !sensorState.equals(
DeviceTypeConstants.STATE_OFF)) {
log.error("The requested state change should be either - 'ON' or 'OFF'");
return Response.status(Response.Status.BAD_REQUEST.getStatusCode()).build();
}
Map<String, String> dynamicProperties = new HashMap<>();
String publishTopic = APIUtil.getAuthenticatedUserTenantDomain()
+ "/" + DeviceTypeConstants.DEVICE_TYPE + "/" + deviceId + "/command";
dynamicProperties.put(DeviceTypeConstants.ADAPTER_TOPIC_PROPERTY, publishTopic);
APIUtil.getOutputEventAdapterService().publish(DeviceTypeConstants.MQTT_ADAPTER_NAME,
dynamicProperties, state);
return Response.ok().build();
} catch (DeviceAccessAuthorizationException e) {
log.error(e.getErrorMessage(), e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
}
/**
* Retrieve Sensor data for the
*/
@Path("device/stats/{deviceId}")
@GET
@Consumes("application/json")
@Produces("application/json")
public Response getSensorStats(@PathParam("deviceId") String deviceId, @QueryParam("from") long from,
@QueryParam("to") long to) {
String fromDate = String.valueOf(from);
String toDate = String.valueOf(to);
String query = "deviceId:" + deviceId + " AND deviceType:" +
DeviceTypeConstants.DEVICE_TYPE + " AND time : [" + fromDate + " TO " + toDate + "]";
String sensorTableName = DeviceTypeConstants.TEMPERATURE_EVENT_TABLE;
try {
if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(new DeviceIdentifier(deviceId,
DeviceTypeConstants.DEVICE_TYPE))) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
if (sensorTableName != null) {
List<SortByField> sortByFields = new ArrayList<>();
SortByField sortByField = new SortByField("time", SORT.ASC, false);
sortByFields.add(sortByField);
List<SensorRecord> sensorRecords = APIUtil.getAllEventsForDevice(sensorTableName, query, sortByFields);
return Response.status(Response.Status.OK.getStatusCode()).entity(sensorRecords).build();
}
} catch (AnalyticsException e) {
String errorMsg = "Error on retrieving stats on table " + sensorTableName + " with query " + query;
log.error(errorMsg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(errorMsg).build();
} catch (DeviceAccessAuthorizationException e) {
log.error(e.getErrorMessage(), e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
return Response.status(Response.Status.BAD_REQUEST).build();
}
@Path("/device/{device_id}")
@DELETE
public Response removeDevice(@PathParam("device_id") String deviceId) {
try {
@ -90,7 +209,7 @@ public class ManagerServiceImpl implements ManagerService {
}
}
@Path("/devices/{device_id}")
@Path("/device/{device_id}")
@PUT
public Response updateDevice(@PathParam("device_id") String deviceId, @QueryParam("name") String name) {
try {
@ -120,7 +239,7 @@ public class ManagerServiceImpl implements ManagerService {
}
}
@Path("/devices/{device_id}")
@Path("/device/{device_id}")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@ -166,7 +285,7 @@ public class ManagerServiceImpl implements ManagerService {
}
}
@Path("/devices/download")
@Path("/device/download")
@GET
@Produces("application/zip")
public Response downloadSketch(@QueryParam("deviceName") String deviceName,
@ -191,9 +310,6 @@ public class ManagerServiceImpl implements ManagerService {
} catch (APIManagerException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (DeviceControllerException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (IOException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
@ -234,13 +350,13 @@ public class ManagerServiceImpl implements ManagerService {
}
private ZipArchive createDownloadFile(String owner, String deviceName, String sketchType)
throws DeviceManagementException, APIManagerException, JWTClientException, DeviceControllerException,
throws DeviceManagementException, JWTClientException, APIManagerException,
UserStoreException {
//create new device id
String deviceId = shortUUID();
if (apiApplicationKey == null) {
String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm().getRealmConfiguration()
.getAdminUserName();
String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
.getRealmConfiguration().getAdminUserName();
APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
String[] tags = {DeviceTypeConstants.DEVICE_TYPE};
apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
@ -250,20 +366,17 @@ public class ManagerServiceImpl implements ManagerService {
String scopes = "device_type_" + DeviceTypeConstants.DEVICE_TYPE + " device_" + deviceId;
AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
apiApplicationKey.getConsumerSecret(), owner, scopes);
//create token
String accessToken = accessTokenInfo.getAccessToken();
String refreshToken = accessTokenInfo.getRefreshToken();
boolean status;
status = register(deviceId, deviceName);
boolean status = register(deviceId, deviceName);
if (!status) {
String msg = "Error occurred while registering the device with " + "id: " + deviceId + " owner:" + owner;
throw new DeviceManagementException(msg);
}
ZipUtil ziputil = new ZipUtil();
ZipArchive zipFile = ziputil.createZipFile(owner, APIUtil.getTenantDomainOftheUser(), sketchType, deviceId,
deviceName, accessToken, refreshToken);
zipFile.setDeviceId(deviceId);
ZipArchive zipFile = ziputil.createZipFile(owner, APIUtil.getTenantDomainOftheUser(), sketchType,
deviceId, deviceName, accessToken, refreshToken);
return zipFile;
}
}

@ -1,56 +0,0 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package ${groupId}.${rootArtifactId}.api;
import org.wso2.carbon.apimgt.annotations.api.API;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@Path("enrollment")
@API(name = "${deviceType}_mgt", version = "1.0.0", context = "/${deviceType}_mgt", tags = "${deviceType}")
public interface ManagerService {
@Path("/devices/{device_id}")
@DELETE
Response removeDevice(@PathParam("device_id") String deviceId);
@Path("/devices/{device_id}")
@PUT
Response updateDevice(@PathParam("device_id") String deviceId, @QueryParam("name") String name);
@Path("/devices/{device_id}")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
Response getDevice(@PathParam("device_id") String deviceId);
@Path("/devices")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
Response getAllDevices();
@Path("/devices/download")
@GET
@Produces("application/zip")
Response downloadSketch(@QueryParam("deviceName") String deviceName, @QueryParam("sketchType") String sketchType);
}

@ -15,6 +15,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package ${groupId}.${rootArtifactId}.api.dto;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
@ -22,12 +23,15 @@ import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
*These information are sent by agent in each request to server
* These information are sent by agent in each request to server
*/
@XmlRootElement
@JsonIgnoreProperties(ignoreUnknown = true)
public class DeviceJSON {
@XmlElement(required = true) public String owner;
@XmlElement(required = true) public String deviceId;
@XmlElement(required = true) public Float sensorValue;
@XmlElement(required = true)
public String owner;
@XmlElement(required = true)
public String deviceId;
@XmlElement(required = true)
public Float sensorValue;
}

@ -1,3 +1,21 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package ${groupId}.${rootArtifactId}.api.dto;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
@ -9,17 +27,19 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@XmlRootElement
/**
* This stores sensor event data for android sense.
*/
@XmlRootElement
@JsonIgnoreProperties(ignoreUnknown = true)
public class SensorRecord {
@XmlElementWrapper(required = true, name = "values")
private Map<String, Object> values;
/** The id. */
/**
* The id.
*/
@XmlElement(required = false, name = "id")
private String id;
@ -39,14 +59,6 @@ public class SensorRecord {
this.values = values;
}
/**
* Sets the id.
* @param id the new id
*/
public void setId(String id) {
this.id = id;
}
/**
* Gets the id.
* @return the id
@ -55,8 +67,16 @@ public class SensorRecord {
return id;
}
/**
* Sets the id.
* @param id the new id
*/
public void setId(String id) {
this.id = id;
}
@Override
public String toString(){
public String toString() {
List<String> valueList = new ArrayList<String>();
for (Map.Entry<String, Object> entry : values.entrySet()) {
valueList.add(entry.getKey() + ":" + entry.getValue());

@ -24,14 +24,6 @@ public class DeviceTypeException extends Exception {
private String errorMessage;
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public DeviceTypeException(String msg, DeviceTypeException nestedEx) {
super(msg, nestedEx);
setErrorMessage(msg);
@ -54,4 +46,12 @@ public class DeviceTypeException extends Exception {
public DeviceTypeException(Throwable cause) {
super(cause);
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
}

@ -1,211 +0,0 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package ${groupId}.${rootArtifactId}.api.transport;
import java.nio.charset.StandardCharsets;
import ${groupId}.${rootArtifactId}.api.util.APIUtil;
import ${groupId}.${rootArtifactId}.plugin.constants.DeviceTypeConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey;
import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
import org.wso2.carbon.device.mgt.iot.transport.mqtt.MQTTTransportHandler;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.user.api.UserStoreException;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
import java.io.File;
import java.util.Calendar;
import java.util.UUID;
/**
* MQTT is used as transport protocol. So this will provide basic functional requirement in order to communicate over
* MQTT
*/
@SuppressWarnings("no JAX-WS annotation")
public class MQTTConnector extends MQTTTransportHandler {
private static final String publisherContext = "publisher";
private static final String subscriberContext = "subscriber";
private static final String subscribeTopic = "wso2/+/"+ DeviceTypeConstants.DEVICE_TYPE + "/+/" + publisherContext;
private static final String KEY_TYPE = "PRODUCTION";
private static final String EMPTY_STRING = "";
private static final String JSON_SERIAL_KEY = "SerialNumber";
private static final String JSON_TENANT_KEY = "Tenant";
private static Log log = LogFactory.getLog(MQTTConnector.class);
private static String iotServerSubscriber = UUID.randomUUID().toString().substring(0, 5);
private MQTTConnector() {
super(iotServerSubscriber, DeviceTypeConstants.DEVICE_TYPE,
MqttConfig.getInstance().getMqttQueueEndpoint(), subscribeTopic);
}
/**
* {@inheritDoc}
* This method will initialize connection with message broker
*/
@Override
public void connect() {
Runnable connector = new Runnable() {
public void run() {
while (!isConnected()) {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
DeviceTypeConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true);
try {
String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
.getRealmConfiguration().getAdminUserName();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(applicationUsername);
APIManagementProviderService apiManagementProviderService = APIUtil
.getAPIManagementProviderService();
String[] tags = {DeviceTypeConstants.DEVICE_TYPE};
ApiApplicationKey apiApplicationKey = apiManagementProviderService
.generateAndRetrieveApplicationKeys(DeviceTypeConstants.DEVICE_TYPE, tags, KEY_TYPE,
applicationUsername, true);
JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
String scopes = "device_type_" + DeviceTypeConstants.DEVICE_TYPE + " device_mqtt_connector";
AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
apiApplicationKey.getConsumerSecret(), applicationUsername, scopes);
//create token
String accessToken = accessTokenInfo.getAccessToken();
setUsernameAndPassword(accessToken, EMPTY_STRING);
connectToQueue();
} catch (TransportHandlerException e) {
log.error("Connection/Subscription to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e);
try {
Thread.sleep(timeoutInterval);
} catch (InterruptedException ex) {
log.error("MQTT-Connector: Thread Sleep Interrupt Exception.", ex);
}
} catch (JWTClientException e) {
log.error("Failed to retrieve token from JWT Client.", e);
return;
} catch (UserStoreException e) {
log.error("Failed to retrieve the user.", e);
return;
} catch (APIManagerException e) {
log.error("Failed to create an application and generate keys.", e);
return;
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
}
};
Thread connectorThread = new Thread(connector);
connectorThread.start();
}
/**
* This callback function will be called by message broker when some messages available to subscribed topic
*
* @param message mqtt message which is comming form agent side
* @param messageParams metadata of mqtt message
*/
@Override
public void processIncomingMessage(MqttMessage message, String... messageParams) throws TransportHandlerException {
}
/**
* connection with message broker can be terminated
*/
@Override
public void disconnect() {
Runnable stopConnection = new Runnable() {
public void run() {
while (isConnected()) {
try {
closeConnection();
} catch (MqttException e) {
if (log.isDebugEnabled()) {
log.warn("Unable to 'STOP' MQTT connection at broker at: " + mqttBrokerEndPoint);
}
try {
Thread.sleep(timeoutInterval);
} catch (InterruptedException e1) {
log.error("MQTT-Terminator: Thread Sleep Interrupt Exception");
}
}
}
}
};
Thread terminatorThread = new Thread(stopConnection);
terminatorThread.setDaemon(true);
terminatorThread.start();
}
@Override
public void publishDeviceData() throws TransportHandlerException {
}
@Override
public void publishDeviceData(MqttMessage publishData) throws TransportHandlerException {
}
@Override
public void publishDeviceData(String... publishData) throws TransportHandlerException {
if (publishData.length != 3) {
String errorMsg = "Incorrect number of arguments received to SEND-MQTT Message. " +
"Need to be [owner, deviceId, resource{SENSOR}, state{ON/OFF or null}]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg);
}
String deviceId = publishData[0];
String resource = publishData[1];
String state = publishData[2];
MqttMessage pushMessage = new MqttMessage();
String publishTopic = "wso2/" + APIUtil.getTenantDomainOftheUser() + "/" + DeviceTypeConstants.DEVICE_TYPE
+ "/" + deviceId;
String actualMessage = resource + ":" + state;
pushMessage.setPayload(actualMessage.getBytes(StandardCharsets.UTF_8));
pushMessage.setQos(DEFAULT_MQTT_QUALITY_OF_SERVICE);
pushMessage.setRetained(false);
publishToQueue(publishTopic, pushMessage);
}
@Override
public void processIncomingMessage() {
}
@Override
public void processIncomingMessage(MqttMessage message) throws TransportHandlerException {
}
}

@ -1,6 +1,8 @@
package ${groupId}.${rootArtifactId}.api.util;
import ${groupId}.${rootArtifactId}.api.dto.SensorRecord;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
import org.wso2.carbon.analytics.api.AnalyticsDataAPI;
import org.wso2.carbon.analytics.dataservice.core.AnalyticsDataServiceUtils;
import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDataResponse;
@ -172,12 +174,6 @@ public class APIUtil {
return ids;
}
/**
* Creates the SensorDatas from records.
*
* @param records the records
* @return the Map of SensorRecord <id, SensorRecord>
*/
public static Map<String, SensorRecord> createSensorData(List<Record> records) {
Map<String, SensorRecord> sensorDatas = new HashMap<>();
for (Record record : records) {
@ -187,12 +183,6 @@ public class APIUtil {
return sensorDatas;
}
/**
* Create a SensorRecord object out of a Record object
*
* @param record the record object
* @return SensorRecord object
*/
public static SensorRecord createSensorData(Record record) {
SensorRecord recordBean = new SensorRecord();
recordBean.setId(record.getId());
@ -211,4 +201,21 @@ public class APIUtil {
}
return analyticsDataAPI;
}
public static String getAuthenticatedUserTenantDomain() {
PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
return threadLocalCarbonContext.getTenantDomain();
}
public static OutputEventAdapterService getOutputEventAdapterService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
OutputEventAdapterService outputEventAdapterService =
(OutputEventAdapterService) ctx.getOSGiService(OutputEventAdapterService.class, null);
if (outputEventAdapterService == null) {
String msg = "Device Authorization service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return outputEventAdapterService;
}
}

@ -25,8 +25,8 @@ import org.wso2.carbon.user.core.Permission;
*/
public class Constants {
public static final String DEFAULT_PERMISSION_RESOURCE = "/permission/admin/device-mgt/${deviceType}/user";
public static final String DEFAULT_ROLE_NAME = "${deviceType}_user";
public static final Permission DEFAULT_PERMISSION[] = new Permission[]{new Permission(Constants.DEFAULT_PERMISSION_RESOURCE,
"ui.execute")};
public static final String DEFAULT_PERMISSION_RESOURCE = "/permission/admin/device-mgt/${deviceType}/user";
public static final String DEFAULT_ROLE_NAME = "${deviceType}_user";
public static final Permission DEFAULT_PERMISSION[]
= new Permission[]{new Permission(Constants.DEFAULT_PERMISSION_RESOURCE, "ui.execute")};
}

@ -19,8 +19,10 @@
package ${groupId}.${rootArtifactId}.api.util;
import ${groupId}.${rootArtifactId}.plugin.constants.DeviceTypeConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException;
import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService;
import org.wso2.carbon.context.PrivilegedCarbonContext;
@ -28,9 +30,11 @@ import org.wso2.carbon.context.PrivilegedCarbonContext;
public class ServiceUtils {
private static final Log log = LogFactory.getLog(ServiceUtils.class);
/**
* Sensor data are published to DAS
* @param deviceId unique identifier of the device
*
* @param deviceId unique identifier of the device
* @param sensorValue current value of sensor which is set at agent side
* @return
*/
@ -42,8 +46,8 @@ public class ServiceUtils {
Object metdaData[] = {owner, DeviceTypeConstants.DEVICE_TYPE, deviceId, System.currentTimeMillis()};
Object payloadData[] = {sensorValue};
try {
deviceAnalyticsService.publishEvent(DeviceTypeConstants.TEMPERATURE_STREAM_DEFINITION,
DeviceTypeConstants.TEMPERATURE_STREAM_DEFINITION_VERSION, metdaData, new Object[0], payloadData);
deviceAnalyticsService.publishEvent(DeviceTypeConstants.SENSOR_STREAM_DEFINITION,
DeviceTypeConstants.SENSOR_STREAM_DEFINITION_VERSION, metdaData, new Object[0], payloadData);
} catch (DataPublisherConfigurationException e) {
return false;
}

@ -18,12 +18,10 @@
package ${groupId}.${rootArtifactId}.api.util;
import ${groupId}.${rootArtifactId}.plugin.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig;
import org.wso2.carbon.device.mgt.iot.exception.IoTException;
import org.wso2.carbon.device.mgt.iot.util.IoTUtil;
import org.wso2.carbon.device.mgt.iot.util.IotDeviceManagementUtil;
import org.wso2.carbon.device.mgt.iot.util.Utils;
import org.wso2.carbon.device.mgt.iot.util.ZipArchive;
import org.wso2.carbon.utils.CarbonUtils;
@ -50,30 +48,24 @@ public class ZipUtil {
String sketchFolder = "repository" + File.separator + "resources" + File.separator + "sketches";
String archivesPath = CarbonUtils.getCarbonHome() + File.separator + sketchFolder + File.separator + "archives" +
File.separator + deviceId;
File.separator + deviceId;
String templateSketchPath = sketchFolder + File.separator + deviceType;
String iotServerIP;
try {
iotServerIP = IoTUtil.getHostName();
iotServerIP = Utils.getServerUrl();
String httpsServerPort = System.getProperty(HTTPS_PORT_PROPERTY);
String httpServerPort = System.getProperty(HTTP_PORT_PROPERTY);
String httpsServerEP = HTTPS_PROTOCOL_APPENDER + iotServerIP + ":" + httpsServerPort;
String httpServerEP = HTTP_PROTOCOL_APPENDER + iotServerIP + ":" + httpServerPort;
String apimEndpoint = httpsServerEP;
String mqttEndpoint = MqttConfig.getInstance().getMqttQueueEndpoint();
String mqttEndpoint = MqttConfig.getInstance().getBrokerEndpoint();
if (mqttEndpoint.contains(LOCALHOST)) {
mqttEndpoint = mqttEndpoint.replace(LOCALHOST, iotServerIP);
}
String xmppEndpoint = XmppConfig.getInstance().getXmppEndpoint();
int indexOfChar = xmppEndpoint.lastIndexOf(":");
if (indexOfChar != -1) {
xmppEndpoint = xmppEndpoint.substring(0, indexOfChar);
}
xmppEndpoint = xmppEndpoint + ":" + XmppConfig.getInstance().getSERVER_CONNECTION_PORT();
Map<String, String> contextParams = new HashMap<>();
contextParams.put("SERVER_NAME", "wso2/" + APIUtil.getTenantDomainOftheUser());
contextParams.put("SERVER_NAME", APIUtil.getTenantDomainOftheUser());
contextParams.put("DEVICE_OWNER", owner);
contextParams.put("DEVICE_ID", deviceId);
contextParams.put("DEVICE_NAME", deviceName);
@ -81,15 +73,12 @@ public class ZipUtil {
contextParams.put("HTTP_EP", httpServerEP);
contextParams.put("APIM_EP", apimEndpoint);
contextParams.put("MQTT_EP", mqttEndpoint);
contextParams.put("XMPP_EP", xmppEndpoint);
contextParams.put("DEVICE_TOKEN", token);
contextParams.put("DEVICE_REFRESH_TOKEN", refreshToken);
ZipArchive zipFile;
zipFile = IotDeviceManagementUtil.getSketchArchive(archivesPath, templateSketchPath, contextParams);
zipFile = Utils.getSketchArchive(archivesPath, templateSketchPath, contextParams, deviceName);
return zipFile;
} catch (IoTException e) {
throw new DeviceManagementException(e.getMessage());
} catch (IOException e) {
throw new DeviceManagementException("Zip File Creation Failed", e);
}

@ -26,40 +26,40 @@
it will result 403 error at the runtime.
-->
<PermissionConfiguration>
<APIVersion></APIVersion>
<!-- Device related APIs -->
<Permission>
<name>Get device</name>
<path>/device-mgt/${deviceType}/user</path>
<url>/enrollment/devices/*</url>
<method>GET</method>
<scope>${deviceType}_user</scope>
</Permission>
<Permission>
<name>Remove device</name>
<path>/device-mgt/${deviceType}/user</path>
<url>/enrollment/devices/*</url>
<method>DELETE</method>
<scope>${deviceType}_user</scope>
</Permission>
<Permission>
<name>Download device</name>
<path>/device-mgt/user</path>
<url>/enrollment/devices/download</url>
<method>GET</method>
<scope>${deviceType}_user</scope>
</Permission>
<Permission>
<name>Update device</name>
<path>/device-mgt/${deviceType}/user</path>
<url>/enrollment/devices/*</url>
<method>POST</method>
<scope>${deviceType}_user</scope>
</Permission>
<APIVersion></APIVersion>
<!-- Device related APIs -->
<Permission>
<name>Get device</name>
<path>/device-mgt/${deviceType}/user</path>
<url>/device/*</url>
<method>GET</method>
<scope>${deviceType}_user</scope>
</Permission>
<Permission>
<name>Remove device</name>
<path>/device-mgt/${deviceType}/user</path>
<url>/device/*</url>
<method>DELETE</method>
<scope>${deviceType}_user</scope>
</Permission>
<Permission>
<name>Download device</name>
<path>/device-mgt/${deviceType}/user</path>
<url>/device/download</url>
<method>GET</method>
<scope>${deviceType}_user</scope>
</Permission>
<Permission>
<name>Update device</name>
<path>/device-mgt/${deviceType}/user</path>
<url>/device/*</url>
<method>POST</method>
<scope>${deviceType}_user</scope>
</Permission>
<Permission>
<name>Get Devices</name>
<path>/device-mgt/${deviceType}/user</path>
<url>/enrollment/devices</url>
<url>/device</url>
<method>GET</method>
<scope>${deviceType}_user</scope>
</Permission>

@ -25,19 +25,12 @@
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">
<jaxrs:server id="${deviceType}" address="/">
<jaxrs:serviceBeans>
<bean id="ControllerService"
class="${groupId}.${rootArtifactId}.api.ControllerServiceImpl">
<property name="MQTTConnector" ref="communicationHandler"/>
</bean>
<bean id="ManagerService"
class="${groupId}.${rootArtifactId}.api.ManagerServiceImpl">
<bean id="DeviceTypeService"
class="${groupId}.${rootArtifactId}.api.DeviceTypeServiceImpl">
</bean>
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
</jaxrs:providers>
</jaxrs:server>
<bean id="communicationHandler"
class="${groupId}.${rootArtifactId}.api.transport.MQTTConnector" >
</bean>
</beans>

@ -26,7 +26,7 @@
</context-param>
<context-param>
<param-name>isSharedWithAllTenants</param-name>
<param-value>true</param-value>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>providerTenantDomain</param-name>

@ -70,7 +70,14 @@
org.wso2.carbon.device.mgt.common,
org.wso2.carbon.device.mgt.iot.*,
org.wso2.carbon.device.mgt.extensions.feature.mgt.*,
org.wso2.carbon.utils.*
org.wso2.carbon.utils.*,
org.wso2.carbon.event.output.adapter.core,
org.wso2.carbon.event.output.adapter.core.exception,
org.wso2.carbon.base,
org.wso2.carbon.core.util,
org.wso2.carbon.context,
org.wso2.carbon.core,
org.apache.commons.codec.binary
</Import-Package>
<Export-Package>
!${project-base-package}.plugin.internal,
@ -82,6 +89,10 @@
</plugins>
</build>
<dependencies>
<dependency>
<groupId>commons-codec.wso2</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi</artifactId>
@ -99,16 +110,24 @@
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.ndatasource.core</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>org.wso2.carbon.device.mgt.iot</artifactId>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.ndatasource.core</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.extensions</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.utils</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.output.adapter.core</artifactId>
</dependency>
</dependencies>
</project>

@ -18,19 +18,49 @@
package ${groupId}.${rootArtifactId}.plugin.constants;
import org.wso2.carbon.utils.CarbonUtils;
import java.io.File;
public class DeviceTypeConstants {
public final static String DEVICE_TYPE = "${deviceType}";
public final static String DEVICE_PLUGIN_DEVICE_NAME = "DEVICE_NAME";
public final static String DEVICE_PLUGIN_DEVICE_ID = "${deviceType}_DEVICE_ID";
public final static String SENSOR_READING = "sensorValue";
public static final String DATA_SOURCE_NAME = "jdbc/${deviceType}DM_DB";
public final static String DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN = "accessToken";
public final static String DEVICE_PLUGIN_PROPERTY_REFRESH_TOKEN = "refreshToken";
public final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super";
public final static String STATE_ON = "ON";
public final static String STATE_OFF = "OFF";
public final static String SENSOR_CONTEXT = "SENSOR";
public final static String TEMPERATURE_EVENT_TABLE = "DEVICE_TEMPERATURE_SUMMARY";
public final static String TEMPERATURE_STREAM_DEFINITION = "org.wso2.iot.devices.temperature";
public final static String TEMPERATURE_STREAM_DEFINITION_VERSION = "1.0.0";
//sensor events summerized table name
public static final String TEMPERATURE_EVENT_TABLE = "ORG_WSO2_IOT_DEVICES_${nameOfTheSensor}";
public static final String DATA_SOURCE_NAME = "jdbc/${deviceType}DM_DB";
public final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super";
//mqtt tranport related constants
public static final String MQTT_ADAPTER_NAME = "${nameOfTheSensor}_mqtt";
public static final String MQTT_ADAPTER_TYPE = "oauth-mqtt";
public static final String ADAPTER_TOPIC_PROPERTY = "topic";
public static final String MQTT_PORT = "\\$\\{mqtt.broker.port\\}";
public static final String MQTT_BROKER_HOST = "\\$\\{mqtt.broker.host\\}";
public static final String CARBON_CONFIG_PORT_OFFSET = "Ports.Offset";
public static final String DEFAULT_CARBON_LOCAL_IP_PROPERTY = "carbon.local.ip";
public static final int CARBON_DEFAULT_PORT_OFFSET = 0;
public static final int DEFAULT_MQTT_PORT = 1883;
public static final String SUBSCRIBED_TOPIC = "carbon.super/${deviceType}/+/publisher";
public static final String CONTENT_TRANSFORMATION = "contentTransformer";
public static final String CONTENT_VALIDATION = "contentValidator";
public static final String RESOURCE = "resource";
public static final String USERNAME_PROPERTY_KEY = "username";
public static final String DCR_PROPERTY_KEY = "dcrUrl";
public static final String BROKER_URL_PROPERTY_KEY = "url";
public static final String SCOPES_PROPERTY_KEY = "scopes";
public static final String QOS_PROPERTY_KEY = "qos";
public static final String CLIENT_ID_PROPERTY_KEY = "qos";
public static final String CLEAR_SESSION_PROPERTY_KEY = "clearSession";
public static final String TOPIC = "topic";
public final static String SENSOR_STREAM_DEFINITION = "org.wso2.iot.devices.${nameOfTheSensor}";
public final static String SENSOR_STREAM_DEFINITION_VERSION = "1.0.0";
public static final String MQTT_CONFIG_LOCATION = CarbonUtils.getEtcCarbonConfigDirPath() + File.separator
+ "mqtt.properties";
}

@ -32,71 +32,37 @@ import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import java.util.List;
public class DeviceTypeManagerService implements DeviceManagementService{
private DeviceManager deviceManager;
public class DeviceTypeManagerService implements DeviceManagementService {
private DeviceManager deviceManager;
@Override
public String getType() {
return DeviceTypeConstants.DEVICE_TYPE;
}
@Override
public void init() throws DeviceManagementException {
this.deviceManager = new DeviceTypeManager();
}
@Override
public DeviceManager getDeviceManager() {
return deviceManager;
}
@Override
public ApplicationManager getApplicationManager() {
return null;
}
@Override
public ProvisioningConfig getProvisioningConfig() {
return new ProvisioningConfig(DeviceTypeConstants.DEVICE_TYPE_PROVIDER_DOMAIN, false);
}
@Override
public PushNotificationConfig getPushNotificationConfig() {
return null;
}
@Override
public String getType() {
return DeviceTypeConstants.DEVICE_TYPE;
}
@Override
public void init() throws DeviceManagementException {
this.deviceManager = new DeviceTypeManager();
}
@Override
public DeviceManager getDeviceManager() {
return deviceManager;
}
@Override
public ApplicationManager getApplicationManager() {
return null;
}
@Override
public ProvisioningConfig getProvisioningConfig() {
return new ProvisioningConfig(DeviceTypeConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true);
}
@Override
public PushNotificationConfig getPushNotificationConfig() {
return null;
}
/*@Override
public Application[] getApplications(String domain, int pageNumber, int size)
throws ApplicationManagementException {
return new Application[0];
}*/
/*@Override
public void updateApplicationStatus(DeviceIdentifier deviceId, Application application,
String status) throws ApplicationManagementException {
}*/
/*@Override
public String getApplicationStatus(DeviceIdentifier deviceId, Application application)
throws ApplicationManagementException {
return null;
}
*/
/*@Override
public void installApplicationForDevices(Operation operation, List<DeviceIdentifier> deviceIdentifiers)
throws ApplicationManagementException {
}
@Override
public void installApplicationForUsers(Operation operation, List<String> userNameList)
throws ApplicationManagementException {
}
@Override
public void installApplicationForUserRoles(Operation operation, List<String> userRoleList)
throws ApplicationManagementException {
}*/
}

@ -20,11 +20,11 @@ package ${groupId}.${rootArtifactId}.plugin.impl.dao;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import ${groupId}.${rootArtifactId}.plugin.constants.DeviceTypeConstants;
import ${groupId}.${rootArtifactId}.plugin.impl.dao.impl.DeviceTypeDAOImpl;
import ${groupId}.${rootArtifactId}.plugin.exception.DeviceMgtPluginException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
@ -32,7 +32,7 @@ import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class DeviceTypeDAO{
public class DeviceTypeDAO {
private static final Log log = LogFactory.getLog(DeviceTypeDAO.class);
static DataSource dataSource; // package local variable
@ -42,17 +42,13 @@ public class DeviceTypeDAO{
initDeviceTypeDAO();
}
public DeviceTypeDAOImpl getDeviceTypeDAO() {
return new DeviceTypeDAOImpl();
}
public static void initDeviceTypeDAO(){
public static void initDeviceTypeDAO() {
try {
Context ctx = new InitialContext();
dataSource = (DataSource) ctx.lookup(DeviceTypeConstants.DATA_SOURCE_NAME);
} catch (NamingException e) {
log.error("Error while looking up the data source: " +
DeviceTypeConstants.DATA_SOURCE_NAME);
DeviceTypeConstants.DATA_SOURCE_NAME);
}
}
@ -98,14 +94,14 @@ public class DeviceTypeDAO{
public static void closeConnection() throws DeviceMgtPluginException {
Connection con = currentConnection.get();
if(con != null){
try {
con.close();
} catch (SQLException e) {
log.error("Error occurred while close the connection");
}
}
Connection con = currentConnection.get();
if (con != null) {
try {
con.close();
} catch (SQLException e) {
log.error("Error occurred while close the connection");
}
}
currentConnection.remove();
}
@ -126,4 +122,8 @@ public class DeviceTypeDAO{
closeConnection();
}
}
public DeviceTypeDAOImpl getDeviceTypeDAO() {
return new DeviceTypeDAOImpl();
}
}

@ -20,10 +20,12 @@ package ${groupId}.${rootArtifactId}.plugin.impl.dao.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import ${groupId}.${rootArtifactId}.plugin.constants.DeviceTypeConstants;
import ${groupId}.${rootArtifactId}.plugin.exception.DeviceMgtPluginException;
import ${groupId}.${rootArtifactId}.plugin.impl.dao.DeviceTypeDAO;
import ${groupId}.${rootArtifactId}.plugin.impl.util.DeviceTypeUtils;
import org.wso2.carbon.device.mgt.common.Device;
import java.sql.Connection;

@ -0,0 +1,43 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package ${groupId}.${rootArtifactId}.plugin.impl.util;
import ${groupId}.${rootArtifactId}.plugin.impl.util.DeviceTypeUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.core.ServerStartupObserver;
import java.io.IOException;
public class DeviceTypeStartupListener implements ServerStartupObserver {
private static final Log log = LogFactory.getLog(${groupId}.${rootArtifactId}.plugin.impl.util.DeviceTypeStartupListener.class);
@Override
public void completingServerStartup() {
}
@Override
public void completedServerStartup() {
try {
DeviceTypeUtils.setupMqttOutputAdapter();
} catch (IOException e) {
log.error("Failed to initialize the ${deviceType} output adapter", e);
}
}
}

@ -18,51 +18,40 @@
package ${groupId}.${rootArtifactId}.plugin.impl.util;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import ${groupId}.${rootArtifactId}.plugin.constants.DeviceTypeConstants;
import ${groupId}.${rootArtifactId}.plugin.exception.DeviceMgtPluginException;
import ${groupId}.${rootArtifactId}.plugin.internal.DeviceTypeManagementDataHolder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.util.Utils;
import org.wso2.carbon.event.output.adapter.core.MessageType;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration;
import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* Contains utility methods used by ${rootArtifactId} plugin.
* Contains utility methods used by ${deviceType} plugin.
*/
public class DeviceTypeUtils {
private static Log log = LogFactory.getLog(DeviceTypeUtils.class);
public static String getDeviceProperty(List<Device.Property> deviceProperties, String propertyKey) {
String deviceProperty = "";
for (Device.Property property : deviceProperties) {
if (propertyKey.equals(property.getName())) {
deviceProperty = property.getValue();
}
}
return deviceProperty;
}
public static Device.Property getProperty(String property, String value) {
if (property != null) {
Device.Property prop = new Device.Property();
prop.setName(property);
prop.setValue(value);
return prop;
}
return null;
}
private static Log log = LogFactory.getLog(${groupId}.${rootArtifactId}.plugin.impl.util.DeviceTypeUtils.class);
public static void cleanupResources(Connection conn, PreparedStatement stmt, ResultSet rs) {
if (rs != null) {
@ -111,4 +100,91 @@ public class DeviceTypeUtils {
}
}
public static String replaceMqttProperty(String urlWithPlaceholders) {
String MQTT_BROKER_HOST = null;
String MQTT_PORT = null;
if(!DeviceTypeConstants.MQTT_BROKER_HOST.startsWith("$")){
MQTT_BROKER_HOST = "\\$".concat(DeviceTypeConstants.MQTT_BROKER_HOST);
}
if(!DeviceTypeConstants.MQTT_PORT.startsWith("$")){
MQTT_PORT = "\\$".concat(DeviceTypeConstants.MQTT_PORT);
}
urlWithPlaceholders = Utils.replaceSystemProperty(urlWithPlaceholders);
urlWithPlaceholders = urlWithPlaceholders.replaceAll(MQTT_PORT, "" +
(DeviceTypeConstants.DEFAULT_MQTT_PORT + getPortOffset()));
urlWithPlaceholders = urlWithPlaceholders.replaceAll(MQTT_BROKER_HOST,
System.getProperty(DeviceTypeConstants.DEFAULT_CARBON_LOCAL_IP_PROPERTY, "localhost"));
return urlWithPlaceholders;
}
private static int getPortOffset() {
ServerConfiguration carbonConfig = ServerConfiguration.getInstance();
String portOffset = System.getProperty("portOffset", carbonConfig.getFirstProperty(
DeviceTypeConstants.CARBON_CONFIG_PORT_OFFSET));
try {
if ((portOffset != null)) {
return Integer.parseInt(portOffset.trim());
} else {
return DeviceTypeConstants.CARBON_DEFAULT_PORT_OFFSET;
}
} catch (NumberFormatException e) {
return DeviceTypeConstants.CARBON_DEFAULT_PORT_OFFSET;
}
}
public static void setupMqttOutputAdapter() throws IOException {
OutputEventAdapterConfiguration outputEventAdapterConfiguration =
createMqttOutputEventAdapterConfiguration(DeviceTypeConstants.MQTT_ADAPTER_NAME,
DeviceTypeConstants.MQTT_ADAPTER_TYPE, MessageType.TEXT);
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
DeviceTypeConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true);
DeviceTypeManagementDataHolder.getInstance().getOutputEventAdapterService()
.create(outputEventAdapterConfiguration);
} catch (OutputEventAdapterException e) {
log.error("Unable to create Output Event Adapter : " + DeviceTypeConstants.MQTT_ADAPTER_NAME, e);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
/**
* Create Output Event Adapter Configuration for given configuration.
*
* @param name Output Event Adapter name
* @param type Output Event Adapter type
* @param msgFormat Output Event Adapter message format
* @return OutputEventAdapterConfiguration instance for given configuration
*/
private static OutputEventAdapterConfiguration createMqttOutputEventAdapterConfiguration(String name, String type,
String msgFormat) throws IOException {
OutputEventAdapterConfiguration outputEventAdapterConfiguration = new OutputEventAdapterConfiguration();
outputEventAdapterConfiguration.setName(name);
outputEventAdapterConfiguration.setType(type);
outputEventAdapterConfiguration.setMessageFormat(msgFormat);
File configFile = new File(DeviceTypeConstants.MQTT_CONFIG_LOCATION);
if (configFile.exists()) {
Map<String, String> mqttAdapterProperties = new HashMap<>();
InputStream propertyStream = configFile.toURI().toURL().openStream();
Properties properties = new Properties();
properties.load(propertyStream);
mqttAdapterProperties.put(DeviceTypeConstants.USERNAME_PROPERTY_KEY, properties.getProperty(
DeviceTypeConstants.USERNAME_PROPERTY_KEY));
mqttAdapterProperties.put(DeviceTypeConstants.DCR_PROPERTY_KEY, Utils.replaceSystemProperty(
properties.getProperty(DeviceTypeConstants.DCR_PROPERTY_KEY)));
mqttAdapterProperties.put(DeviceTypeConstants.BROKER_URL_PROPERTY_KEY, replaceMqttProperty(
properties.getProperty(DeviceTypeConstants.BROKER_URL_PROPERTY_KEY)));
mqttAdapterProperties.put(DeviceTypeConstants.SCOPES_PROPERTY_KEY, properties.getProperty(
DeviceTypeConstants.SCOPES_PROPERTY_KEY));
mqttAdapterProperties.put(DeviceTypeConstants.CLEAR_SESSION_PROPERTY_KEY, properties.getProperty(
DeviceTypeConstants.CLEAR_SESSION_PROPERTY_KEY));
mqttAdapterProperties.put(DeviceTypeConstants.QOS_PROPERTY_KEY, properties.getProperty(
DeviceTypeConstants.QOS_PROPERTY_KEY));
mqttAdapterProperties.put(DeviceTypeConstants.CLIENT_ID_PROPERTY_KEY, "");
mqttAdapterProperties.put(DeviceTypeConstants.RESOURCE, "output-event");
outputEventAdapterConfiguration.setStaticProperties(mqttAdapterProperties);
}
return outputEventAdapterConfiguration;
}
}

@ -0,0 +1,47 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package ${groupId}.${rootArtifactId}.plugin.internal;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
/**
* DataHolder class of fgfgt plugins component.
*/
public class DeviceTypeManagementDataHolder {
private static DeviceTypeManagementDataHolder thisInstance = new DeviceTypeManagementDataHolder();
private OutputEventAdapterService outputEventAdapterService;
private DeviceTypeManagementDataHolder() {
}
public static DeviceTypeManagementDataHolder getInstance() {
return thisInstance;
}
public OutputEventAdapterService getOutputEventAdapterService() {
return outputEventAdapterService;
}
public void setOutputEventAdapterService(
OutputEventAdapterService outputEventAdapterService) {
this.outputEventAdapterService = outputEventAdapterService;
}
}

@ -18,34 +18,47 @@
package ${groupId}.${rootArtifactId}.plugin.internal;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import ${groupId}.${rootArtifactId}.plugin.impl.util.DeviceTypeStartupListener;
import ${groupId}.${rootArtifactId}.plugin.exception.DeviceMgtPluginException;
import ${groupId}.${rootArtifactId}.plugin.impl.util.DeviceTypeUtils;
import ${groupId}.${rootArtifactId}.plugin.impl.DeviceTypeManagerService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext;
import org.wso2.carbon.core.ServerStartupObserver;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
/**
* @scr.component name="${groupId}.${rootArtifactId}.plugin.internal.ServiceComponent"
* immediate="true"
* @scr.reference name="event.output.adapter.service"
* interface="org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService"
* cardinality="1..1"
* policy="dynamic"
* bind="setOutputEventAdapterService"
* unbind="unsetOutputEventAdapterService"
*/
public class ServiceComponent {
private ServiceRegistration serviceRegistration;
private static final Log log = LogFactory.getLog(ServiceComponent.class);
private ServiceRegistration serviceRegistration;
protected void activate(ComponentContext ctx) {
if (log.isDebugEnabled()) {
log.debug("Activating ${rootArtifactId} Management Service Component");
log.debug("Activating b Management Service Component");
}
try {
DeviceTypeManagerService deviceTypeManagerService = new DeviceTypeManagerService();
BundleContext bundleContext = ctx.getBundleContext();
serviceRegistration =
bundleContext.registerService(DeviceManagementService.class.getName(), new
DeviceTypeManagerService(), null);
bundleContext.registerService(DeviceManagementService.class.getName(),
deviceTypeManagerService, null);
bundleContext.registerService(ServerStartupObserver.class.getName(), new DeviceTypeStartupListener(),
null);
String setupOption = System.getProperty("setup");
if (setupOption != null) {
if (log.isDebugEnabled()) {
@ -59,7 +72,7 @@ public class ServiceComponent {
}
}
if (log.isDebugEnabled()) {
log.debug("${rootArtifactId} Management Service Component has been successfully activated");
log.debug("b Management Service Component has been successfully activated");
}
} catch (Throwable e) {
log.error("Error occurred while activating Current Sensor Management Service Component", e);
@ -68,7 +81,7 @@ public class ServiceComponent {
protected void deactivate(ComponentContext ctx) {
if (log.isDebugEnabled()) {
log.debug("De-activating ${rootArtifactId} Management Service Component");
log.debug("De-activating b Management Service Component");
}
try {
if (serviceRegistration != null) {
@ -81,4 +94,20 @@ public class ServiceComponent {
log.error("Error occurred while de-activating Iot Device Management bundle", e);
}
}
/**
* Initialize the Output EventAdapter Service dependency
*
* @param outputEventAdapterService Output EventAdapter Service reference
*/
protected void setOutputEventAdapterService(OutputEventAdapterService outputEventAdapterService) {
DeviceTypeManagementDataHolder.getInstance().setOutputEventAdapterService(outputEventAdapterService);
}
/**
* De-reference the Output EventAdapter Service dependency.
*/
protected void unsetOutputEventAdapterService(OutputEventAdapterService outputEventAdapterService) {
DeviceTypeManagementDataHolder.getInstance().setOutputEventAdapterService(null);
}
}

@ -0,0 +1,60 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package ${groupId}.${rootArtifactId}.plugin.mqtt;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import ${groupId}.${rootArtifactId}.plugin.constants.DeviceTypeConstants;
import ${groupId}.${rootArtifactId}.plugin.impl.util.DeviceTypeUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class MqttConfig {
private static String brokerEndpoint;
private static MqttConfig mqttConfig = new MqttConfig();
private static final Log log = LogFactory.getLog(MqttConfig.class);
private MqttConfig() {
File configFile = new File(DeviceTypeConstants.MQTT_CONFIG_LOCATION);
if (configFile.exists()) {
try {
InputStream propertyStream = configFile.toURI().toURL().openStream();
Properties properties = new Properties();
properties.load(propertyStream);
brokerEndpoint = DeviceTypeUtils.replaceMqttProperty(
properties.getProperty(DeviceTypeConstants.BROKER_URL_PROPERTY_KEY));
} catch (IOException e) {
log.error("Failed to read the mqtt.properties file" + e);
}
}
}
public static MqttConfig getInstance() {
return mqttConfig;
}
public String getBrokerEndpoint() {
return brokerEndpoint;
}
}

@ -5,7 +5,7 @@
data-appcontext="{{@app.context}}"></span>
<div id="div-chart">
<div class="chartWrapper" id="chartWrapper">
<span id="span-title">Temperature</span>
<span id="span-title">${nameOfTheSensor}</span>
<div id="y_axis" class="custom_y_axis"></div>
<div class="legend_container">
<div id="smoother" title="Smoothing"></div>

@ -17,14 +17,23 @@
*/
function onRequest(context) {
var devices = context.unit.params.devices;
var deviceType = context.uriParams.deviceType;
var deviceId = request.getParameter("deviceId");
if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) {
if (devices) {
return {
"devices": stringify(devices),
"backendApiUri": devicemgtProps["httpsURL"] + "/"+deviceType+"/device/stats/"
};
} else if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) {
var deviceModule = require("/app/modules/device.js").deviceModule;
var device = deviceModule.viewDevice(deviceType, deviceId);
if (device && device.status != "error") {
return {"device": device, "backendApiUri" : devicemgtProps["httpsURL"] + "/"+deviceType+"/device/stats/" + deviceId};
return {
"device": device,
"backendApiUri": devicemgtProps["httpsURL"] + "/"+deviceType+"/device/stats/" + deviceId
};
} else {
response.sendError(404, "Device Id " + deviceId + " of type " + deviceType + " cannot be found!");
exit();

@ -18,27 +18,20 @@
var palette = new Rickshaw.Color.Palette({scheme: "classic9"});
function drawGraph(from, to) {
var backendApiUrl = $("#chart").data("backend-api-url") + "?from=" + from + "&to=" + to;
var successCallback = function (data) {
if (data) {
drawLineGraph(JSON.parse(data));
}
};
invokerUtil.get(backendApiUrl, successCallback, function (message) {
console.log(message);
});
}
function drawGraph_${deviceType}(from, to) {
$("#y_axis").html("");
$("#smoother").html("");
$("#legend").html("");
$("#chart").html("");
$("#x_axis").html("");
$("#slider").html("");
var devices = $("#details").data("devices");
var tzOffset = new Date().getTimezoneOffset() * 60;
function drawLineGraph(data) {
var chartWrapperElmId = "#div-chart";
var graphWidth = $(chartWrapperElmId).width() - 50;
if (data.length == 0 || data.length == undefined) {
$("#chart").html("<br/>No data available...");
return;
}
$("#chart").empty();
var chartWrapperElmId = "#div-chart";
var graphWidth = $(chartWrapperElmId).width() - 50;
var graphConfig = {
element: document.getElementById("chart"),
width: graphWidth,
@ -53,47 +46,28 @@ function drawLineGraph(data) {
series: []
};
var tzOffset = new Date().getTimezoneOffset() * 60;
var min = Number.MAX_VALUE;
var max = Number.MIN_VALUE;
var range_min = 99999, range_max = 0;
var max_val = parseInt(data[0].values.temperature);
var min_val = max_val;
var chartData = [];
for (var i = 0; i < data.length; i++) {
var y_val = parseInt(data[i].values.temperature);
if (y_val > max_val) {
max_val = y_val;
} else if (y_val < min_val) {
min_val = y_val;
}
chartData.push(
if (devices) {
for (var i = 0; i < devices.length; i++) {
graphConfig['series'].push(
{
x: parseInt(data[i].values.time) - tzOffset,
y: y_val
}
);
}
if (range_max < max_val) {
range_max = max_val;
}
if (range_min > min_val) {
range_min = min_val;
}
graphConfig['series'].push(
'color': palette.color(),
'data': [{
x: parseInt(new Date().getTime() / 1000),
y: 0
}],
'name': devices[i].name
});
}
} else {
graphConfig['series'].push(
{
'color': palette.color(),
'data': chartData,
'name': $("#details").data("devicename"),
'scale': d3.scale.linear().domain([Math.min(min, min_val), Math.max(max, max_val)])
.nice()
}
);
if (graphConfig['series'].length == 0) {
$(chartWrapperElmId).html("No data available...");
return;
'data': [{
x: parseInt(new Date().getTime() / 1000),
y: 0
}],
'name': $("#details").data("devicename")
});
}
var graph = new Rickshaw.Graph(graphConfig);
@ -106,13 +80,12 @@ function drawLineGraph(data) {
xAxis.render();
var yAxis = new Rickshaw.Graph.Axis.Y.Scaled({
var yAxis = new Rickshaw.Graph.Axis.Y({
graph: graph,
orientation: 'left',
element: document.getElementById("y_axis"),
width: 40,
height: 410,
'scale': d3.scale.linear().domain([Math.min(min, range_min), Math.max(max, range_max)]).nice()
height: 410
});
yAxis.render();
@ -131,9 +104,9 @@ function drawLineGraph(data) {
graph: graph,
formatter: function (series, x, y) {
var date = '<span class="date">' +
moment((x + tzOffset) * 1000).format('Do MMM YYYY h:mm:ss a') + '</span>';
moment.unix((x + tzOffset) * 1000).format('Do MMM YYYY h:mm:ss a') + '</span>';
var swatch = '<span class="detail_swatch" style="background-color: ' +
series.color + '"></span>';
series.color + '"></span>';
return swatch + series.name + ": " + parseInt(y) + '<br>' + date;
}
});
@ -152,4 +125,59 @@ function drawLineGraph(data) {
graph: graph,
legend: legend
});
var deviceIndex = 0;
if (devices) {
getData();
} else {
var backendApiUrl = $("#chart").data("backend-api-url") + "?from=" + from + "&to=" + to;
var successCallback = function (data) {
if (data) {
drawLineGraph(JSON.parse(data));
}
};
invokerUtil.get(backendApiUrl, successCallback, function (message) {
console.log(message);
});
}
function getData() {
if (deviceIndex >= devices.length) {
return;
}
var backendApiUrl = $("#chart").data("backend-api-url") + devices[deviceIndex].deviceIdentifier
+ "?from=" + from + "&to=" + to;
var successCallback = function (data) {
if (data) {
drawLineGraph(JSON.parse(data));
}
deviceIndex++;
getData();
};
invokerUtil.get(backendApiUrl, successCallback, function (message) {
console.log(message);
deviceIndex++;
getData();
});
}
function drawLineGraph(data) {
if (data.length === 0 || data.length === undefined) {
return;
}
var chartData = [];
for (var i = 0; i < data.length; i++) {
chartData.push(
{
x: parseInt(data[i].values.time) - tzOffset,
y: parseInt(data[i].values.${nameOfTheSensor})
}
);
}
graphConfig.series[deviceIndex].data = chartData;
graph.update();
}
}

@ -3,7 +3,7 @@
{{/zone}}
<div id="div-chart" data-websocketurl="{{websocketEndpoint}}">
<div class="chartWrapper" id="chartWrapper">
<div id="y_axis" class="custom_y_axis">Temperature</div>
<div id="y_axis" class="custom_y_axis">${nameOfTheSensor}</div>
<div class="legend_container">
<div id="smoother" title="Smoothing"></div>
<div id="legend"></div>

@ -27,7 +27,7 @@ function onRequest(context) {
if (tokenPair) {
token = tokenPair.accessToken;
}
websocketEndpoint = websocketEndpoint + "/secured-outputui/org.wso2.iot.devices.temperature/1.0.0?" +
websocketEndpoint = websocketEndpoint + "/secured-outputui/org.wso2.iot.devices.${nameOfTheSensor}/1.0.0?" +
"token="+ token +"&deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type;
return {"device": device, "websocketEndpoint" : websocketEndpoint};
}

@ -63,7 +63,7 @@ $(window).load(function () {
new Rickshaw.Graph.HoverDetail({
graph: graph,
formatter: function (series, x, y) {
var date = '<span class="date">' + moment(x * 1000).format('Do MMM YYYY h:mm:ss a') + '</span>';
var date = '<span class="date">' + moment.unix(x*1000).format('Do MMM YYYY h:mm:ss a') + '</span>';
var swatch = '<span class="detail_swatch" style="background-color: ' + series.color + '"></span>';
return swatch + series.name + ": " + parseInt(y) + '<br>' + date;
}

@ -84,6 +84,17 @@
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${groupId}</groupId>
<artifactId>${project-base-package}.analytics</artifactId>
<version>${version}</version>
<type>zip</type>
<overWrite>true</overWrite>
<outputDirectory>
${project.build.directory}/maven-shared-archive-resources/carbonapps
</outputDirectory>
<includes>**/*</includes>
</artifactItem>
<artifactItem>
<groupId>${groupId}</groupId>
<artifactId>${project-base-package}.ui
@ -173,7 +184,7 @@
<adviceFile>
<properties>
<propertyDef>org.wso2.carbon.p2.category.type:server</propertyDef>
<propertyDef>org.eclipse.equinox.p2.type.group:false</propertyDef>
<propertyDef>org.eclipse.equinox.p2.type.group:true</propertyDef>
</properties>
</adviceFile>
<bundles>

@ -44,7 +44,7 @@ CONTROLLER_CONTEXT = configParser.get('Device-Configurations', 'controller-conte
DEVICE_INFO = '{"owner":"' + DEVICE_OWNER + '","deviceId":"' + DEVICE_ID + '",'
HTTPS_EP = configParser.get('Device-Configurations', 'https-ep')
DEVICE_DATA = '"sensorValue":"{sensorValue}"'
SENSOR_STATS = '{{"event":{{"metaData":{{"owner":"' + DEVICE_OWNER + '","type":"'+ DEVICE_TYPE +'","deviceId":"' + DEVICE_ID + '","time":{:.2f}}},"payloadData":{{"temperature":{:.2f}}}}}}}'
SENSOR_STATS = '{{"event":{{"metaData":{{"owner":"' + DEVICE_OWNER + '","deviceType":"'+ DEVICE_TYPE +'","deviceId":"' + DEVICE_ID + '","time":{}}},"payloadData":{{"${nameOfTheSensor}":{:.2f}}}}}}}'
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

@ -71,9 +71,9 @@ def main():
DEV_TYPE =iotUtils.DEVICE_TYPE
TANENT_DOMAIN = iotUtils.SERVER_NAME
global TOPIC_TO_SUBSCRIBE
TOPIC_TO_SUBSCRIBE = TANENT_DOMAIN + "/" + DEV_TYPE + "/" + DEV_ID
TOPIC_TO_SUBSCRIBE = TANENT_DOMAIN + "/" + DEV_TYPE + "/" + DEV_ID + "/command"
global TOPIC_TO_PUBLISH
TOPIC_TO_PUBLISH = TANENT_DOMAIN + "/" + DEV_TYPE + "/" + DEV_ID + "/temperature"
TOPIC_TO_PUBLISH = TANENT_DOMAIN + "/" + DEV_TYPE + "/" + DEV_ID + "/publisher"
print ("MQTT_LISTENER: MQTT_ENDPOINT is " + str(MQTT_ENDPOINT))
print ("MQTT_LISTENER: MQTT_TOPIC is " + TOPIC_TO_SUBSCRIBE)

@ -7,12 +7,12 @@
"analyticStreams": [
{
"name": "Temperature",
"table": "DEVICE_TEMPERATURE_SUMMARY",
"table": "DEVICE_${deviceType}_${nameOfTheSensor}_SUMMARY",
"ui_unit": {
"name": "cdmf.unit.analytics.line-chart",
"data":[
{"column": {"name":"TIME", "label":"time", "ui-mapping":"x-axis"}},
{"column": {"name":"TEMPERATURE", "label":"Temperature", "ui-mapping":"y-axis"}}
{"column": {"name":"${nameOfTheSensor}", "label":"${nameOfTheSensor}", "ui-mapping":"y-axis"}}
]
}
}

@ -12,3 +12,17 @@ org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../depl
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/${groupId}.${rootArtifactId}_${feature.version}/jaggeryapps/,target:${installFolder}/../../deployment/server/jaggeryapps/,overwrite:true);\
org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../database/);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/${groupId}.${rootArtifactId}_${feature.version}/database/,target:${installFolder}/../../database/,overwrite:true);\
org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/carbonapps/);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/${groupId}.${rootArtifactId}_${feature.version}/carbonapps/,target:${installFolder}/../../deployment/server/carbonapps/,overwrite:true);\
instructions.unconfigure = \
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../conf/device-types/${deviceType}.xml);\
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../deployment/server/webapps/${deviceType}.war);\
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../deployment/server/webapps/${deviceType});\
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../../dbscripts/cdm/plugins/${deviceType});\
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../conf/datasources/${deviceType}-datasources.xml);\
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../database/${deviceType}DM_DB.h2.db);\
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../deployment/server/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.${deviceType}.device-view);\
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../deployment/server/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.${deviceType}.type-view);\
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../deployment/server/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.${deviceType}.realtime.analytics-view);\
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../deployment/server/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.${deviceType}.analytics-view);\

@ -78,19 +78,16 @@
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>${cxf.version}</version>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.eclipse.paho</groupId>
@ -118,7 +115,6 @@
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>${javax.ws.rs.version}</version>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
@ -132,11 +128,6 @@
<version>${version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.apimgt.webapp.publisher</artifactId>
<version>${carbon.device.mgt.version}</version>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.ndatasource.core</artifactId>
@ -300,6 +291,21 @@
<artifactId>h2-database-engine</artifactId>
<version>1.2.140.wso2v3</version>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.output.adapter.core</artifactId>
<version>${carbon.analytics.common.version}</version>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.extensions</artifactId>
<version>${carbon.devicemgt.version}</version>
</dependency>
<dependency>
<groupId>commons-codec.wso2</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.wso2.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
@ -409,6 +415,8 @@
<!--Orbit versions-->
<orbit.h2.engine.version>1.2.140.wso2v3</orbit.h2.engine.version>
<commons-json.version.range>(3.0.0, 4.0.0]</commons-json.version.range>
<commons-codec.wso2.version>1.4.0.wso2v1</commons-codec.wso2.version>
<!--XMPP/MQTT Version-->
<smack.wso2.version>3.0.4.wso2v1</smack.wso2.version>
<smackx.wso2.version>3.0.4.wso2v1</smackx.wso2.version>

Loading…
Cancel
Save