forked from community/device-mgt-plugins
Merge branch 'IoTS-1.0.0-M1' of https://github.com/wso2/carbon-device-mgt-plugins into IoTS-1.0.0-M1
commit
e365cd1c35
314
components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/ArduinoService.java → components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/ArduinoService.java
314
components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/ArduinoService.java → components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/ArduinoService.java
0
components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/dto/DeviceJSON.java → components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/dto/DeviceJSON.java
0
components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/dto/DeviceJSON.java → components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/dto/DeviceJSON.java
0
components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/exception/ArduinoException.java → components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/exception/ArduinoException.java
0
components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/exception/ArduinoException.java → components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/exception/ArduinoException.java
0
components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/transport/ArduinoMQTTSubscriber.java → components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/transport/ArduinoMQTTSubscriber.java
0
components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/transport/ArduinoMQTTSubscriber.java → components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/transport/ArduinoMQTTSubscriber.java
0
components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/util/ArduinoServiceUtils.java → components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/util/ArduinoServiceUtils.java
0
components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/util/ArduinoServiceUtils.java → components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/util/ArduinoServiceUtils.java
@ -0,0 +1,171 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
~ 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<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>
|
||||||
|
<artifactId>device-mgt-iot-arduino</artifactId>
|
||||||
|
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
|
||||||
|
<version>1.9.2-SNAPSHOT</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>org.wso2.carbon.device.mgt.iot.arduino.mgt.service.impl</artifactId>
|
||||||
|
<version>1.9.2-SNAPSHOT</version>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
<name>WSO2 Carbon - IoT Server Arduino API</name>
|
||||||
|
<description>WSO2 Carbon - Arduino Service API Implementation</description>
|
||||||
|
<url>http://wso2.org</url>
|
||||||
|
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.wso2.carbon</groupId>
|
||||||
|
<artifactId>org.wso2.carbon.utils</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- CDM -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||||
|
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||||
|
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.apache.axis2.wso2</groupId>
|
||||||
|
<artifactId>axis2-client</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||||
|
<artifactId>org.wso2.carbon.device.mgt.analytics</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.apache.axis2.wso2</groupId>
|
||||||
|
<artifactId>axis2-client</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!--CXF -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cxf</groupId>
|
||||||
|
<artifactId>cxf-rt-frontend-jaxws</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cxf</groupId>
|
||||||
|
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cxf</groupId>
|
||||||
|
<artifactId>cxf-rt-transports-http</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--MQTT -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.paho</groupId>
|
||||||
|
<artifactId>mqtt-client</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--IOT -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpasyncclient</artifactId>
|
||||||
|
<version>4.1</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
|
||||||
|
<artifactId>org.wso2.carbon.device.mgt.iot</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
|
||||||
|
<artifactId>org.wso2.carbon.device.mgt.iot.arduino.plugin.impl</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--JAX-RS -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.codehaus.jackson</groupId>
|
||||||
|
<artifactId>jackson-core-asl</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.codehaus.jackson</groupId>
|
||||||
|
<artifactId>jackson-jaxrs</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax</groupId>
|
||||||
|
<artifactId>javaee-web-api</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.ws.rs</groupId>
|
||||||
|
<artifactId>jsr311-api</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||||
|
<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>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
|
<source>${wso2.maven.compiler.source}</source>
|
||||||
|
<target>${wso2.maven.compiler.target}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<warName>arduino_mgt</warName>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,443 @@
|
|||||||
|
/*
|
||||||
|
* 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 org.wso2.carbon.device.mgt.iot.arduino.service;
|
||||||
|
|
||||||
|
import org.apache.commons.httpclient.HttpStatus;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.wso2.carbon.apimgt.annotations.api.API;
|
||||||
|
import org.wso2.carbon.apimgt.annotations.device.DeviceType;
|
||||||
|
import org.wso2.carbon.apimgt.annotations.device.feature.Feature;
|
||||||
|
import org.wso2.carbon.apimgt.webapp.publisher.KeyGenerationUtil;
|
||||||
|
import org.wso2.carbon.device.mgt.common.Device;
|
||||||
|
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.iot.DeviceManagement;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.DeviceValidator;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.apimgt.AccessTokenInfo;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.apimgt.TokenClient;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.arduino.plugin.constants.ArduinoConstants;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.arduino.service.dto.DeviceJSON;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.arduino.service.transport.ArduinoMQTTSubscriber;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.arduino.service.util.ArduinoServiceUtils;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.exception.AccessTokenException;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.util.ZipArchive;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.util.ZipUtil;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.HeaderParam;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@API( name="arduino", version="1.0.0", context="/arduino")
|
||||||
|
@DeviceType( value = "arduino")
|
||||||
|
public class ArduinoService {
|
||||||
|
|
||||||
|
private static Log log = LogFactory.getLog(ArduinoService.class);
|
||||||
|
|
||||||
|
//TODO; replace this tenant domain
|
||||||
|
private static final String SUPER_TENANT = "carbon.super";
|
||||||
|
|
||||||
|
@Context //injected response proxy supporting multiple thread
|
||||||
|
private HttpServletResponse response;
|
||||||
|
|
||||||
|
public static final String HTTP_PROTOCOL = "HTTP";
|
||||||
|
public static final String MQTT_PROTOCOL = "MQTT";
|
||||||
|
|
||||||
|
private ArduinoMQTTSubscriber arduinoMQTTSubscriber;
|
||||||
|
private static Map<String, LinkedList<String>> replyMsgQueue = new HashMap<>();
|
||||||
|
private static Map<String, LinkedList<String>> internalControlsQueue = new HashMap<>();
|
||||||
|
private ConcurrentHashMap<String, String> deviceToIpMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param arduinoMQTTSubscriber an object of type "ArduinoMQTTSubscriber" specific for this ArduinoService
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public void setArduinoMQTTSubscriber(
|
||||||
|
final ArduinoMQTTSubscriber arduinoMQTTSubscriber) {
|
||||||
|
this.arduinoMQTTSubscriber = arduinoMQTTSubscriber;
|
||||||
|
|
||||||
|
if (MqttConfig.getInstance().isEnabled()) {
|
||||||
|
Runnable xmppStarter = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
arduinoMQTTSubscriber.initConnector();
|
||||||
|
arduinoMQTTSubscriber.connectAndSubscribe();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Thread xmppStarterThread = new Thread(xmppStarter);
|
||||||
|
xmppStarterThread.setDaemon(true);
|
||||||
|
xmppStarterThread.start();
|
||||||
|
} else {
|
||||||
|
log.warn("MQTT disabled in 'devicemgt-config.xml'. Hence, ArduinoMQTTSubscriber not started.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the "ArduinoMQTTSubscriber" object of this ArduinoService instance
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public ArduinoMQTTSubscriber getArduinoMQTTSubscriber() {
|
||||||
|
return arduinoMQTTSubscriber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the queue containing all the MQTT reply messages from all Arduinos communicating to this service
|
||||||
|
*/
|
||||||
|
public static Map<String, LinkedList<String>> getReplyMsgQueue() {
|
||||||
|
return replyMsgQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the queue containing all the MQTT controls received to be sent to any Arduinos connected to this server
|
||||||
|
*/
|
||||||
|
public static Map<String, LinkedList<String>> getInternalControlsQueue() {
|
||||||
|
return internalControlsQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------
|
||||||
|
Device management specific APIs
|
||||||
|
--------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param deviceId
|
||||||
|
* @param name
|
||||||
|
* @param owner
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Path("manager/device/register")
|
||||||
|
@PUT
|
||||||
|
public boolean register(@QueryParam("deviceId") String deviceId,
|
||||||
|
@QueryParam("name") String name, @QueryParam("owner") String owner) {
|
||||||
|
|
||||||
|
DeviceManagement deviceManagement = new DeviceManagement(SUPER_TENANT);
|
||||||
|
|
||||||
|
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
|
||||||
|
deviceIdentifier.setId(deviceId);
|
||||||
|
deviceIdentifier.setType(ArduinoConstants.DEVICE_TYPE);
|
||||||
|
try {
|
||||||
|
if (deviceManagement.getDeviceManagementService().isEnrolled(deviceIdentifier)) {
|
||||||
|
response.setStatus(Response.Status.CONFLICT.getStatusCode());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Device device = new Device();
|
||||||
|
device.setDeviceIdentifier(deviceId);
|
||||||
|
EnrolmentInfo enrolmentInfo = new EnrolmentInfo();
|
||||||
|
enrolmentInfo.setDateOfEnrolment(new Date().getTime());
|
||||||
|
enrolmentInfo.setDateOfLastUpdate(new Date().getTime());
|
||||||
|
enrolmentInfo.setStatus(EnrolmentInfo.Status.ACTIVE);
|
||||||
|
enrolmentInfo.setOwnership(EnrolmentInfo.OwnerShip.BYOD);
|
||||||
|
device.setName(name);
|
||||||
|
device.setType(ArduinoConstants.DEVICE_TYPE);
|
||||||
|
enrolmentInfo.setOwner(owner);
|
||||||
|
device.setEnrolmentInfo(enrolmentInfo);
|
||||||
|
|
||||||
|
boolean added = deviceManagement.getDeviceManagementService().enrollDevice(device);
|
||||||
|
if (added) {
|
||||||
|
response.setStatus(Response.Status.OK.getStatusCode());
|
||||||
|
} else {
|
||||||
|
response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
return added;
|
||||||
|
} catch (DeviceManagementException e) {
|
||||||
|
response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
deviceManagement.endTenantFlow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param deviceId
|
||||||
|
* @param response
|
||||||
|
*/
|
||||||
|
@Path("manager/device/remove/{device_id}")
|
||||||
|
@DELETE
|
||||||
|
public void removeDevice(@PathParam("device_id") String deviceId, @Context HttpServletResponse response) {
|
||||||
|
|
||||||
|
DeviceManagement deviceManagement = new DeviceManagement(SUPER_TENANT);
|
||||||
|
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
|
||||||
|
deviceIdentifier.setId(deviceId);
|
||||||
|
deviceIdentifier.setType(ArduinoConstants.DEVICE_TYPE);
|
||||||
|
try {
|
||||||
|
boolean removed = deviceManagement.getDeviceManagementService().disenrollDevice(
|
||||||
|
deviceIdentifier);
|
||||||
|
if (removed) {
|
||||||
|
response.setStatus(Response.Status.OK.getStatusCode());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode());
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (DeviceManagementException e) {
|
||||||
|
response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
|
||||||
|
} finally {
|
||||||
|
deviceManagement.endTenantFlow();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param deviceId
|
||||||
|
* @param name
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Path("manager/device/update/{device_id}")
|
||||||
|
@POST
|
||||||
|
public boolean updateDevice(@PathParam("device_id") String deviceId,
|
||||||
|
@QueryParam("name") String name,
|
||||||
|
@Context HttpServletResponse response) {
|
||||||
|
|
||||||
|
DeviceManagement deviceManagement = new DeviceManagement(SUPER_TENANT);
|
||||||
|
|
||||||
|
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
|
||||||
|
deviceIdentifier.setId(deviceId);
|
||||||
|
deviceIdentifier.setType(ArduinoConstants.DEVICE_TYPE);
|
||||||
|
try {
|
||||||
|
Device device = deviceManagement.getDeviceManagementService().getDevice(deviceIdentifier);
|
||||||
|
device.setDeviceIdentifier(deviceId);
|
||||||
|
|
||||||
|
// device.setDeviceTypeId(deviceTypeId);
|
||||||
|
device.getEnrolmentInfo().setDateOfLastUpdate(new Date().getTime());
|
||||||
|
|
||||||
|
device.setName(name);
|
||||||
|
device.setType(ArduinoConstants.DEVICE_TYPE);
|
||||||
|
|
||||||
|
boolean updated = deviceManagement.getDeviceManagementService().modifyEnrollment(device);
|
||||||
|
|
||||||
|
if (updated) {
|
||||||
|
response.setStatus(Response.Status.OK.getStatusCode());
|
||||||
|
} else {
|
||||||
|
response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode());
|
||||||
|
|
||||||
|
}
|
||||||
|
return updated;
|
||||||
|
} catch (DeviceManagementException e) {
|
||||||
|
response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
deviceManagement.endTenantFlow();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param deviceId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Path("manager/device/{device_id}")
|
||||||
|
@GET
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public Device getDevice(@PathParam("device_id") String deviceId) {
|
||||||
|
|
||||||
|
DeviceManagement deviceManagement = new DeviceManagement(SUPER_TENANT);
|
||||||
|
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
|
||||||
|
deviceIdentifier.setId(deviceId);
|
||||||
|
deviceIdentifier.setType(ArduinoConstants.DEVICE_TYPE);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return deviceManagement.getDeviceManagementService().getDevice(deviceIdentifier);
|
||||||
|
|
||||||
|
} catch (DeviceManagementException e) {
|
||||||
|
response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
deviceManagement.endTenantFlow();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param username
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Path("manager/devices/{username}")
|
||||||
|
@GET
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public Device[] getArduinoDevices(@PathParam("username") String username) {
|
||||||
|
|
||||||
|
DeviceManagement deviceManagement = new DeviceManagement(SUPER_TENANT);
|
||||||
|
|
||||||
|
try {
|
||||||
|
List<Device> userDevices =
|
||||||
|
deviceManagement.getDeviceManagementService().getDevicesOfUser(username);
|
||||||
|
ArrayList<Device> userDevicesforArduino = new ArrayList<>();
|
||||||
|
for (Device device : userDevices) {
|
||||||
|
if (device.getType().equals(ArduinoConstants.DEVICE_TYPE) &&
|
||||||
|
device.getEnrolmentInfo().getStatus().equals(EnrolmentInfo.Status.ACTIVE)) {
|
||||||
|
userDevicesforArduino.add(device);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return userDevicesforArduino.toArray(new Device[]{});
|
||||||
|
} catch (DeviceManagementException e) {
|
||||||
|
response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
deviceManagement.endTenantFlow();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param owner
|
||||||
|
* @param customDeviceName
|
||||||
|
* @param sketchType
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Path("manager/device/{sketch_type}/download")
|
||||||
|
@GET
|
||||||
|
@Produces("application/octet-stream")
|
||||||
|
public Response downloadSketch(@QueryParam("owner") String owner,
|
||||||
|
@QueryParam("deviceName") String customDeviceName,
|
||||||
|
@PathParam("sketch_type") String sketchType) {
|
||||||
|
//TODO:: null check customDeviceName at UI level
|
||||||
|
try {
|
||||||
|
ZipArchive zipFile = createDownloadFile(owner, customDeviceName, sketchType);
|
||||||
|
Response.ResponseBuilder rb = Response.ok(zipFile.getZipFile());
|
||||||
|
rb.header("Content-Disposition",
|
||||||
|
"attachment; filename=\"" + zipFile.getFileName() + "\"");
|
||||||
|
return rb.build();
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
return Response.status(400).entity(ex.getMessage()).build();//bad request
|
||||||
|
} catch (DeviceManagementException ex) {
|
||||||
|
return Response.status(500).entity(ex.getMessage()).build();
|
||||||
|
} catch (AccessTokenException ex) {
|
||||||
|
return Response.status(500).entity(ex.getMessage()).build();
|
||||||
|
} catch (DeviceControllerException ex) {
|
||||||
|
return Response.status(500).entity(ex.getMessage()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param owner
|
||||||
|
* @param customDeviceName
|
||||||
|
* @param sketchType
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Path("manager/device/{sketch_type}/generate_link")
|
||||||
|
@GET
|
||||||
|
public Response generateSketchLink(@QueryParam("owner") String owner,
|
||||||
|
@QueryParam("deviceName") String customDeviceName,
|
||||||
|
@PathParam("sketch_type") String sketchType) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
ZipArchive zipFile = createDownloadFile(owner, customDeviceName, sketchType);
|
||||||
|
Response.ResponseBuilder rb = Response.ok(zipFile.getDeviceId());
|
||||||
|
return rb.build();
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
return Response.status(400).entity(ex.getMessage()).build();//bad request
|
||||||
|
} catch (DeviceManagementException ex) {
|
||||||
|
return Response.status(500).entity(ex.getMessage()).build();
|
||||||
|
} catch (AccessTokenException ex) {
|
||||||
|
return Response.status(500).entity(ex.getMessage()).build();
|
||||||
|
} catch (DeviceControllerException ex) {
|
||||||
|
return Response.status(500).entity(ex.getMessage()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param owner
|
||||||
|
* @param customDeviceName
|
||||||
|
* @param sketchType
|
||||||
|
* @return
|
||||||
|
* @throws DeviceManagementException
|
||||||
|
* @throws AccessTokenException
|
||||||
|
* @throws DeviceControllerException
|
||||||
|
*/
|
||||||
|
private ZipArchive createDownloadFile(String owner, String customDeviceName, String sketchType)
|
||||||
|
throws DeviceManagementException, AccessTokenException, DeviceControllerException {
|
||||||
|
if (owner == null) {
|
||||||
|
throw new IllegalArgumentException("Error on createDownloadFile() Owner is null!");
|
||||||
|
}
|
||||||
|
|
||||||
|
//create new device id
|
||||||
|
String deviceId = shortUUID();
|
||||||
|
|
||||||
|
KeyGenerationUtil.createApplicationKeys("arduino");
|
||||||
|
|
||||||
|
TokenClient accessTokenClient = new TokenClient(ArduinoConstants.DEVICE_TYPE);
|
||||||
|
AccessTokenInfo accessTokenInfo = accessTokenClient.getAccessToken(owner, deviceId);
|
||||||
|
|
||||||
|
//create token
|
||||||
|
String accessToken = accessTokenInfo.getAccess_token();
|
||||||
|
String refreshToken = accessTokenInfo.getRefresh_token();
|
||||||
|
|
||||||
|
//Register the device with CDMF
|
||||||
|
String deviceName = customDeviceName + "_" + deviceId;
|
||||||
|
boolean status = register(deviceId, deviceName, owner);
|
||||||
|
|
||||||
|
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, SUPER_TENANT, sketchType, deviceId, deviceName, accessToken,
|
||||||
|
refreshToken);
|
||||||
|
zipFile.setDeviceId(deviceId);
|
||||||
|
return zipFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static String shortUUID() {
|
||||||
|
UUID uuid = UUID.randomUUID();
|
||||||
|
long l = ByteBuffer.wrap(uuid.toString().getBytes(StandardCharsets.UTF_8)).getLong();
|
||||||
|
return Long.toString(l, Character.MAX_RADIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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 org.wso2.carbon.device.mgt.iot.arduino.service.dto;
|
||||||
|
|
||||||
|
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
@XmlRootElement
|
||||||
|
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public class DeviceJSON {
|
||||||
|
@XmlElement(required = true) public String owner;
|
||||||
|
@XmlElement(required = true) public String deviceId;
|
||||||
|
@XmlElement(required = true) public String reply;
|
||||||
|
@XmlElement public Long time;
|
||||||
|
@XmlElement public String key;
|
||||||
|
@XmlElement public float value;
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* 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 org.wso2.carbon.device.mgt.iot.arduino.service.exception;
|
||||||
|
|
||||||
|
public class ArduinoException extends Exception {
|
||||||
|
private static final long serialVersionUID = 118512086957330189L;
|
||||||
|
|
||||||
|
public ArduinoException(String errorMessage) {
|
||||||
|
super(errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArduinoException(String errorMessage, Throwable throwable) {
|
||||||
|
super(errorMessage, throwable);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* 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 org.wso2.carbon.device.mgt.iot.arduino.service.transport;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||||
|
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.arduino.plugin.constants.ArduinoConstants;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.arduino.service.ArduinoService;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.config.server.DeviceManagementConfigurationManager;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttSubscriber;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ArduinoMQTTSubscriber extends MqttSubscriber {
|
||||||
|
private static Log log = LogFactory.getLog(ArduinoMQTTSubscriber.class);
|
||||||
|
|
||||||
|
private static final String serverName =
|
||||||
|
DeviceManagementConfigurationManager.getInstance().getDeviceManagementServerInfo().getName();
|
||||||
|
private static final String subscribeTopic =
|
||||||
|
serverName + File.separator + "+" + File.separator + ArduinoConstants.DEVICE_TYPE + File.separator + "#";
|
||||||
|
|
||||||
|
|
||||||
|
private static final String iotServerSubscriber = UUID.randomUUID().toString().substring(0, 5);
|
||||||
|
private static String mqttEndpoint;
|
||||||
|
|
||||||
|
private ArduinoMQTTSubscriber() {
|
||||||
|
super(iotServerSubscriber, ArduinoConstants.DEVICE_TYPE,
|
||||||
|
MqttConfig.getInstance().getMqttQueueEndpoint(), subscribeTopic);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initConnector() {
|
||||||
|
mqttEndpoint = MqttConfig.getInstance().getMqttQueueEndpoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void connectAndSubscribe() {
|
||||||
|
try {
|
||||||
|
super.connectAndSubscribe();
|
||||||
|
} catch (DeviceManagementException e) {
|
||||||
|
log.error("Subscription to MQTT Broker at: " + mqttEndpoint + " failed");
|
||||||
|
retryMQTTSubscription();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void postMessageArrived(String topic, MqttMessage message) {
|
||||||
|
int lastIndex = topic.lastIndexOf("/");
|
||||||
|
String deviceId = topic.substring(lastIndex + 1);
|
||||||
|
|
||||||
|
lastIndex = message.toString().lastIndexOf(":");
|
||||||
|
String msgContext = message.toString().substring(lastIndex + 1);
|
||||||
|
|
||||||
|
LinkedList<String> deviceControlList = null;
|
||||||
|
LinkedList<String> replyMessageList = null;
|
||||||
|
|
||||||
|
if (msgContext.equals("IN") || msgContext.equals(ArduinoConstants.STATE_ON) || msgContext.equals(
|
||||||
|
ArduinoConstants.STATE_OFF)) {
|
||||||
|
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Received a control message: ");
|
||||||
|
log.debug("Control message topic: " + topic);
|
||||||
|
log.debug("Control message: " + message.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (ArduinoService.getInternalControlsQueue()) {
|
||||||
|
deviceControlList = ArduinoService.getInternalControlsQueue().get(deviceId);
|
||||||
|
if (deviceControlList == null) {
|
||||||
|
ArduinoService.getInternalControlsQueue()
|
||||||
|
.put(deviceId, deviceControlList = new LinkedList<String>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deviceControlList.add(message.toString());
|
||||||
|
|
||||||
|
} else if (msgContext.equals("OUT")) {
|
||||||
|
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Recieved reply from a device: ");
|
||||||
|
log.debug("Reply message topic: " + topic);
|
||||||
|
log.debug("Reply message: " + message.toString().substring(0, lastIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (ArduinoService.getReplyMsgQueue()) {
|
||||||
|
replyMessageList = ArduinoService.getReplyMsgQueue().get(deviceId);
|
||||||
|
if (replyMessageList == null) {
|
||||||
|
ArduinoService.getReplyMsgQueue()
|
||||||
|
.put(deviceId, replyMessageList = new LinkedList<String>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
replyMessageList.add(message.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void retryMQTTSubscription() {
|
||||||
|
Thread retryToSubscribe = new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (true) {
|
||||||
|
if (!isConnected()) {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Subscriber re-trying to reach MQTT queue....");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
ArduinoMQTTSubscriber.super.connectAndSubscribe();
|
||||||
|
} catch (DeviceManagementException e1) {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Attempt to re-connect to MQTT-Queue failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(5000);
|
||||||
|
} catch (InterruptedException e1) {
|
||||||
|
log.error("MQTT: Thread S;eep Interrupt Exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
retryToSubscribe.setDaemon(true);
|
||||||
|
retryToSubscribe.start();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,234 @@
|
|||||||
|
/*
|
||||||
|
* 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 org.wso2.carbon.device.mgt.iot.arduino.service.util;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.concurrent.FutureCallback;
|
||||||
|
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
|
||||||
|
import org.apache.http.impl.nio.client.HttpAsyncClients;
|
||||||
|
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||||
|
import org.wso2.carbon.device.mgt.analytics.exception.DataPublisherConfigurationException;
|
||||||
|
import org.wso2.carbon.device.mgt.analytics.service.DeviceAnalyticsService;
|
||||||
|
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.DeviceController;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.arduino.plugin.constants.ArduinoConstants;
|
||||||
|
import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
|
||||||
|
|
||||||
|
import javax.ws.rs.HttpMethod;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.ProtocolException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
public class ArduinoServiceUtils {
|
||||||
|
private static final Log log = LogFactory.getLog(ArduinoServiceUtils.class);
|
||||||
|
|
||||||
|
//TODO; replace this tenant domain
|
||||||
|
private static final String SUPER_TENANT = "carbon.super";
|
||||||
|
private static final String TEMPERATURE_STREAM_DEFINITION = "org.wso2.iot.devices.temperature";
|
||||||
|
|
||||||
|
public static String sendCommandViaHTTP(final String deviceHTTPEndpoint, String urlContext,
|
||||||
|
boolean fireAndForgot) throws DeviceManagementException {
|
||||||
|
|
||||||
|
String responseMsg = "";
|
||||||
|
String urlString = ArduinoConstants.URL_PREFIX + deviceHTTPEndpoint + urlContext;
|
||||||
|
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug(urlString);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fireAndForgot) {
|
||||||
|
HttpURLConnection httpConnection = getHttpConnection(urlString);
|
||||||
|
|
||||||
|
try {
|
||||||
|
httpConnection.setRequestMethod(HttpMethod.GET);
|
||||||
|
} catch (ProtocolException e) {
|
||||||
|
String errorMsg =
|
||||||
|
"Protocol specific error occurred when trying to set method to GET" +
|
||||||
|
" for:" + urlString;
|
||||||
|
log.error(errorMsg);
|
||||||
|
throw new DeviceManagementException(errorMsg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
responseMsg = readResponseFromGetRequest(httpConnection);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
CloseableHttpAsyncClient httpclient = null;
|
||||||
|
try {
|
||||||
|
|
||||||
|
httpclient = HttpAsyncClients.createDefault();
|
||||||
|
httpclient.start();
|
||||||
|
HttpGet request = new HttpGet(urlString);
|
||||||
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
Future<HttpResponse> future = httpclient.execute(
|
||||||
|
request, new FutureCallback<HttpResponse>() {
|
||||||
|
@Override
|
||||||
|
public void completed(HttpResponse httpResponse) {
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void failed(Exception e) {
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelled() {
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
latch.await();
|
||||||
|
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Sync Interrupted");
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (httpclient != null) {
|
||||||
|
httpclient.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Failed on close");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return responseMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean sendCommandViaMQTT(String deviceOwner, String deviceId, String resource,
|
||||||
|
String state) throws DeviceManagementException {
|
||||||
|
|
||||||
|
boolean result;
|
||||||
|
DeviceController deviceController = new DeviceController();
|
||||||
|
|
||||||
|
try {
|
||||||
|
result = deviceController.publishMqttControl(deviceOwner, ArduinoConstants.DEVICE_TYPE, deviceId, resource, state);
|
||||||
|
} catch (DeviceControllerException e) {
|
||||||
|
String errorMsg = "Error whilst trying to publish to MQTT Queue";
|
||||||
|
log.error(errorMsg);
|
||||||
|
throw new DeviceManagementException(errorMsg, e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------
|
||||||
|
Utility methods relevant to creating and sending http requests
|
||||||
|
--------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* This methods creates and returns a http connection object */
|
||||||
|
|
||||||
|
public static HttpURLConnection getHttpConnection(String urlString) throws
|
||||||
|
DeviceManagementException {
|
||||||
|
|
||||||
|
URL connectionUrl = null;
|
||||||
|
HttpURLConnection httpConnection;
|
||||||
|
|
||||||
|
try {
|
||||||
|
connectionUrl = new URL(urlString);
|
||||||
|
httpConnection = (HttpURLConnection) connectionUrl.openConnection();
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
String errorMsg =
|
||||||
|
"Error occured whilst trying to form HTTP-URL from string: " + urlString;
|
||||||
|
log.error(errorMsg);
|
||||||
|
throw new DeviceManagementException(errorMsg, e);
|
||||||
|
} catch (IOException e) {
|
||||||
|
String errorMsg = "Error occured whilst trying to open a connection to: " +
|
||||||
|
connectionUrl.toString();
|
||||||
|
log.error(errorMsg);
|
||||||
|
throw new DeviceManagementException(errorMsg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This methods reads and returns the response from the connection */
|
||||||
|
|
||||||
|
public static String readResponseFromGetRequest(HttpURLConnection httpConnection)
|
||||||
|
throws DeviceManagementException {
|
||||||
|
BufferedReader bufferedReader;
|
||||||
|
try {
|
||||||
|
bufferedReader = new BufferedReader(new InputStreamReader(
|
||||||
|
httpConnection.getInputStream()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
String errorMsg =
|
||||||
|
"There is an issue with connecting the reader to the input stream at: " +
|
||||||
|
httpConnection.getURL();
|
||||||
|
log.error(errorMsg);
|
||||||
|
throw new DeviceManagementException(errorMsg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
String responseLine;
|
||||||
|
StringBuilder completeResponse = new StringBuilder();
|
||||||
|
|
||||||
|
try {
|
||||||
|
while ((responseLine = bufferedReader.readLine()) != null) {
|
||||||
|
completeResponse.append(responseLine);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
String errorMsg =
|
||||||
|
"Error occured whilst trying read from the connection stream at: " +
|
||||||
|
httpConnection.getURL();
|
||||||
|
log.error(errorMsg);
|
||||||
|
throw new DeviceManagementException(errorMsg, e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
bufferedReader.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(
|
||||||
|
"Could not succesfully close the bufferedReader to the connection at: " +
|
||||||
|
httpConnection.getURL());
|
||||||
|
}
|
||||||
|
|
||||||
|
return completeResponse.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean publishToDAS(String owner, String deviceId, float temperature) {
|
||||||
|
PrivilegedCarbonContext.startTenantFlow();
|
||||||
|
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
||||||
|
ctx.setTenantDomain(SUPER_TENANT, true);
|
||||||
|
DeviceAnalyticsService deviceAnalyticsService = (DeviceAnalyticsService) ctx.getOSGiService(
|
||||||
|
DeviceAnalyticsService.class, null);
|
||||||
|
Object metdaData[] = {owner, ArduinoConstants.DEVICE_TYPE, deviceId, System.currentTimeMillis()};
|
||||||
|
Object payloadData[] = {temperature};
|
||||||
|
|
||||||
|
try {
|
||||||
|
deviceAnalyticsService.publishEvent(TEMPERATURE_STREAM_DEFINITION, "1.0.0", metdaData, new Object[0], payloadData);
|
||||||
|
} catch (DataPublisherConfigurationException e) {
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
PrivilegedCarbonContext.endTenantFlow();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
~ Copyright 2005-2013 WSO2, Inc. (http://wso2.com)
|
||||||
|
~
|
||||||
|
~ Licensed 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This file defines class loading policy of the whole container. But this behaviour can be overridden by individual webapps by putting this file into the META-INF/ directory.
|
||||||
|
-->
|
||||||
|
<Classloading xmlns="http://wso2.org/projects/as/classloading">
|
||||||
|
|
||||||
|
<!-- Parent-first or child-first. Default behaviour is child-first.-->
|
||||||
|
<ParentFirst>false</ParentFirst>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Default environments that contains provides to all the webapps. This can be overridden by individual webapps by specifing required environments
|
||||||
|
Tomcat environment is the default and every webapps gets it even if they didn't specify it.
|
||||||
|
e.g. If a webapps requires CXF, they will get both Tomcat and CXF.
|
||||||
|
-->
|
||||||
|
<Environments>CXF,Carbon</Environments>
|
||||||
|
</Classloading>
|
@ -0,0 +1,48 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
~ 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
|
||||||
|
xsi:schemaLocation="
|
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||||
|
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">
|
||||||
|
|
||||||
|
|
||||||
|
<jaxrs:server id="Arduino" address="/">
|
||||||
|
<jaxrs:serviceBeans>
|
||||||
|
<bean id="ArduinoService"
|
||||||
|
class="org.wso2.carbon.device.mgt.iot.arduino.service.ArduinoService">
|
||||||
|
<property name="arduinoMQTTSubscriber" ref="arduinoMQTTSubscriber"/>
|
||||||
|
</bean>
|
||||||
|
</jaxrs:serviceBeans>
|
||||||
|
<jaxrs:providers>
|
||||||
|
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
|
||||||
|
</jaxrs:providers>
|
||||||
|
</jaxrs:server>
|
||||||
|
|
||||||
|
|
||||||
|
<bean id="arduinoMQTTSubscriber"
|
||||||
|
class="org.wso2.carbon.device.mgt.iot.arduino.service.transport.ArduinoMQTTSubscriber">
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
</beans>
|
||||||
|
|
@ -0,0 +1,55 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<web-app version="2.5"
|
||||||
|
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
||||||
|
metadata-complete="true">
|
||||||
|
<display-name>Arduino</display-name>
|
||||||
|
<description>Arduino</description>
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>CXFServlet</servlet-name>
|
||||||
|
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
|
||||||
|
<load-on-startup>1</load-on-startup>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
|
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>CXFServlet</servlet-name>
|
||||||
|
<url-pattern>/*</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<context-param>
|
||||||
|
<param-name>isAdminService</param-name>
|
||||||
|
<param-value>false</param-value>
|
||||||
|
</context-param>
|
||||||
|
<context-param>
|
||||||
|
<param-name>doAuthentication</param-name>
|
||||||
|
<param-value>false</param-value>
|
||||||
|
</context-param>
|
||||||
|
|
||||||
|
<!--publish to apim-->
|
||||||
|
<context-param>
|
||||||
|
<param-name>managed-api-enabled</param-name>
|
||||||
|
<param-value>true</param-value>
|
||||||
|
</context-param>
|
||||||
|
<context-param>
|
||||||
|
<param-name>managed-api-owner</param-name>
|
||||||
|
<param-value>admin</param-value>
|
||||||
|
</context-param>
|
||||||
|
<context-param>
|
||||||
|
<param-name>managed-api-context-template</param-name>
|
||||||
|
<param-value>/arduino/{version}</param-value>
|
||||||
|
</context-param>
|
||||||
|
<context-param>
|
||||||
|
<param-name>managed-api-application</param-name>
|
||||||
|
<param-value>arduino</param-value>
|
||||||
|
</context-param>
|
||||||
|
<context-param>
|
||||||
|
<param-name>managed-api-isSecured</param-name>
|
||||||
|
<param-value>true</param-value>
|
||||||
|
</context-param>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</web-app>
|
@ -1,15 +0,0 @@
|
|||||||
package org.wso2.carbon.device.mgt.iot.digitaldisplay.api.transport;
|
|
||||||
|
|
||||||
public interface CommunicationHandler<T> {
|
|
||||||
int DEFAULT_TIMEOUT_INTERVAL = 5000; // millis ~ 10 sec
|
|
||||||
|
|
||||||
void connect();
|
|
||||||
|
|
||||||
boolean isConnected();
|
|
||||||
|
|
||||||
void processIncomingMessage(T message, String... messageParams);
|
|
||||||
|
|
||||||
void processIncomingMessage();
|
|
||||||
|
|
||||||
void disconnect();
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
package org.wso2.carbon.device.mgt.iot.digitaldisplay.api.transport;
|
|
||||||
|
|
||||||
public class CommunicationHandlerException extends Exception {
|
|
||||||
private static final long serialVersionUID = 2736466230451105440L;
|
|
||||||
|
|
||||||
private String errorMessage;
|
|
||||||
|
|
||||||
public String getErrorMessage() {
|
|
||||||
return errorMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setErrorMessage(String errorMessage) {
|
|
||||||
this.errorMessage = errorMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommunicationHandlerException(String msg, Exception nestedEx) {
|
|
||||||
super(msg, nestedEx);
|
|
||||||
setErrorMessage(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommunicationHandlerException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
setErrorMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommunicationHandlerException(String msg) {
|
|
||||||
super(msg);
|
|
||||||
setErrorMessage(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommunicationHandlerException() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommunicationHandlerException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,345 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 org.wso2.carbon.device.mgt.iot.digitaldisplay.api.transport;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.eclipse.paho.client.mqttv3.*;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class contains the IoT-Server specific implementation for all the MQTT functionality.
|
|
||||||
* This includes connecting to a MQTT Broker & subscribing to the appropriate MQTT-topic, action
|
|
||||||
* plan upon losing connection or successfully delivering a message to the broker and processing
|
|
||||||
* incoming messages. Makes use of the 'Paho-MQTT' library provided by Eclipse Org.
|
|
||||||
* <p/>
|
|
||||||
* It is an abstract class that implements the common interface "CommunicationHandler" and the
|
|
||||||
* "MqttCallback". Whilst providing some methods which handle key MQTT relevant tasks, this class
|
|
||||||
* implements only the most generic methods of the "CommunicationHandler" interface. The rest of
|
|
||||||
* the methods are left for any extended concrete-class to implement as per its need.
|
|
||||||
*/
|
|
||||||
public abstract class MQTTCommunicationHandler
|
|
||||||
implements MqttCallback, CommunicationHandler<MqttMessage> {
|
|
||||||
private static final Log log = LogFactory.getLog(MQTTCommunicationHandler.class);
|
|
||||||
|
|
||||||
public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0;
|
|
||||||
|
|
||||||
private MqttClient client;
|
|
||||||
private String clientId;
|
|
||||||
private MqttConnectOptions options;
|
|
||||||
private String clientWillTopic;
|
|
||||||
|
|
||||||
protected String mqttBrokerEndPoint;
|
|
||||||
protected int timeoutInterval;
|
|
||||||
protected String subscribeTopic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor for the MQTTCommunicationHandler which takes in the owner, type of the device
|
|
||||||
* and the MQTT Broker URL and the topic to subscribe.
|
|
||||||
*
|
|
||||||
* @param deviceOwner the owner of the device.
|
|
||||||
* @param deviceType the CDMF Device-Type of the device.
|
|
||||||
* @param mqttBrokerEndPoint the IP/URL of the MQTT broker endpoint.
|
|
||||||
* @param subscribeTopic the MQTT topic to which the client is to be subscribed
|
|
||||||
*/
|
|
||||||
protected MQTTCommunicationHandler(String deviceOwner, String deviceType,
|
|
||||||
String mqttBrokerEndPoint,
|
|
||||||
String subscribeTopic) {
|
|
||||||
this.clientId = deviceOwner + ":" + deviceType;
|
|
||||||
this.subscribeTopic = subscribeTopic;
|
|
||||||
this.clientWillTopic = deviceType + File.separator + "disconnection";
|
|
||||||
this.mqttBrokerEndPoint = mqttBrokerEndPoint;
|
|
||||||
this.timeoutInterval = DEFAULT_TIMEOUT_INTERVAL;
|
|
||||||
this.initSubscriber();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor for the MQTTCommunicationHandler which takes in the owner, type of the device
|
|
||||||
* and the MQTT Broker URL and the topic to subscribe. Additionally this constructor takes in
|
|
||||||
* the reconnection-time interval between successive attempts to connect to the broker.
|
|
||||||
*
|
|
||||||
* @param deviceOwner the owner of the device.
|
|
||||||
* @param deviceType the CDMF Device-Type of the device.
|
|
||||||
* @param mqttBrokerEndPoint the IP/URL of the MQTT broker endpoint.
|
|
||||||
* @param subscribeTopic the MQTT topic to which the client is to be subscribed
|
|
||||||
* @param intervalInMillis the time interval in MILLI-SECONDS between successive
|
|
||||||
* attempts to connect to the broker.
|
|
||||||
*/
|
|
||||||
protected MQTTCommunicationHandler(String deviceOwner, String deviceType,
|
|
||||||
String mqttBrokerEndPoint, String subscribeTopic,
|
|
||||||
int intervalInMillis) {
|
|
||||||
this.clientId = deviceOwner + ":" + deviceType;
|
|
||||||
this.subscribeTopic = subscribeTopic;
|
|
||||||
this.clientWillTopic = deviceType + File.separator + "disconnection";
|
|
||||||
this.mqttBrokerEndPoint = mqttBrokerEndPoint;
|
|
||||||
this.timeoutInterval = intervalInMillis;
|
|
||||||
this.initSubscriber();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTimeoutInterval(int timeoutInterval) {
|
|
||||||
this.timeoutInterval = timeoutInterval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the MQTT-Client. Creates a client using the given MQTT-broker endpoint and the
|
|
||||||
* clientId (which is constructed by a concatenation of [deviceOwner]:[deviceType]). Also sets
|
|
||||||
* the client's options parameter with the clientWillTopic (in-case of connection failure) and
|
|
||||||
* other info. Also sets the call-back this current class.
|
|
||||||
*/
|
|
||||||
private void initSubscriber() {
|
|
||||||
try {
|
|
||||||
|
|
||||||
client = new MqttClient(this.mqttBrokerEndPoint, clientId, null);
|
|
||||||
log.info("MQTT subscriber was created with ClientID : " + clientId);
|
|
||||||
} catch (MqttException ex) {
|
|
||||||
String errorMsg = "MQTT Client Error\n" + "\tReason: " + ex.getReasonCode() +
|
|
||||||
"\n\tMessage: " + ex.getMessage() + "\n\tLocalMsg: " +
|
|
||||||
ex.getLocalizedMessage() + "\n\tCause: " + ex.getCause() +
|
|
||||||
"\n\tException: " + ex;
|
|
||||||
log.error(errorMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
options = new MqttConnectOptions();
|
|
||||||
options.setCleanSession(false);
|
|
||||||
options.setWill(clientWillTopic, "Connection-Lost".getBytes(StandardCharsets.UTF_8), 2,
|
|
||||||
true);
|
|
||||||
client.setCallback(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the connection to the MQTT-Broker persists.
|
|
||||||
*
|
|
||||||
* @return true if the client is connected to the MQTT-Broker, else false.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean isConnected() {
|
|
||||||
return client.isConnected();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Connects to the MQTT-Broker and if successfully established connection.
|
|
||||||
*
|
|
||||||
* @throws CommunicationHandlerException in the event of 'Connecting to' the MQTT broker fails.
|
|
||||||
*/
|
|
||||||
protected void connectToQueue() throws CommunicationHandlerException {
|
|
||||||
try {
|
|
||||||
client.connect(options);
|
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug("Subscriber connected to queue at: " + this.mqttBrokerEndPoint);
|
|
||||||
}
|
|
||||||
} catch (MqttSecurityException ex) {
|
|
||||||
String errorMsg = "MQTT Security Exception when connecting to queue\n" + "\tReason: " +
|
|
||||||
" " +
|
|
||||||
ex.getReasonCode() + "\n\tMessage: " + ex.getMessage() +
|
|
||||||
"\n\tLocalMsg: " + ex.getLocalizedMessage() + "\n\tCause: " +
|
|
||||||
ex.getCause() + "\n\tException: " + ex;
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug(errorMsg);
|
|
||||||
}
|
|
||||||
throw new CommunicationHandlerException(errorMsg, ex);
|
|
||||||
|
|
||||||
} catch (MqttException ex) {
|
|
||||||
String errorMsg = "MQTT Exception when connecting to queue\n" + "\tReason: " +
|
|
||||||
ex.getReasonCode() + "\n\tMessage: " + ex.getMessage() +
|
|
||||||
"\n\tLocalMsg: " + ex.getLocalizedMessage() + "\n\tCause: " +
|
|
||||||
ex.getCause() + "\n\tException: " + ex;
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug(errorMsg);
|
|
||||||
}
|
|
||||||
throw new CommunicationHandlerException(errorMsg, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subscribes to the MQTT-Topic specific to this MQTT Client. (The MQTT-Topic specific to the
|
|
||||||
* device is taken in as a constructor parameter of this class) .
|
|
||||||
*
|
|
||||||
* @throws CommunicationHandlerException in the event of 'Subscribing to' the MQTT broker
|
|
||||||
* fails.
|
|
||||||
*/
|
|
||||||
protected void subscribeToQueue() throws CommunicationHandlerException {
|
|
||||||
try {
|
|
||||||
client.subscribe(subscribeTopic, 0);
|
|
||||||
log.info("Subscriber '" + clientId + "' subscribed to topic: " + subscribeTopic);
|
|
||||||
} catch (MqttException ex) {
|
|
||||||
String errorMsg = "MQTT Exception when trying to subscribe to topic: " +
|
|
||||||
subscribeTopic + "\n\tReason: " + ex.getReasonCode() +
|
|
||||||
"\n\tMessage: " + ex.getMessage() + "\n\tLocalMsg: " +
|
|
||||||
ex.getLocalizedMessage() + "\n\tCause: " + ex.getCause() +
|
|
||||||
"\n\tException: " + ex;
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug(errorMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new CommunicationHandlerException(errorMsg, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is used to publish reply-messages for the control signals received.
|
|
||||||
* Invocation of this method calls its overloaded-method with a QoS equal to that of the
|
|
||||||
* default value.
|
|
||||||
*
|
|
||||||
* @param topic the topic to which the reply message is to be published.
|
|
||||||
* @param payLoad the reply-message (payload) of the MQTT publish action.
|
|
||||||
*/
|
|
||||||
protected void publishToQueue(String topic, String payLoad)
|
|
||||||
throws CommunicationHandlerException {
|
|
||||||
publishToQueue(topic, payLoad, DEFAULT_MQTT_QUALITY_OF_SERVICE, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is an overloaded method that publishes MQTT reply-messages for control signals
|
|
||||||
* received form the IoT-Server.
|
|
||||||
*
|
|
||||||
* @param topic the topic to which the reply message is to be published
|
|
||||||
* @param payLoad the reply-message (payload) of the MQTT publish action.
|
|
||||||
* @param qos the Quality-of-Service of the current publish action.
|
|
||||||
* Could be 0(At-most once), 1(At-least once) or 2(Exactly once)
|
|
||||||
*/
|
|
||||||
protected void publishToQueue(String topic, String payLoad, int qos, boolean retained)
|
|
||||||
throws CommunicationHandlerException {
|
|
||||||
try {
|
|
||||||
client.publish(topic, payLoad.getBytes(StandardCharsets.UTF_8), qos, retained);
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug("Message: " + payLoad + " to MQTT topic [" + topic +
|
|
||||||
"] published successfully");
|
|
||||||
}
|
|
||||||
} catch (MqttException ex) {
|
|
||||||
String errorMsg =
|
|
||||||
"MQTT Client Error" + "\n\tReason: " + ex.getReasonCode() + "\n\tMessage: " +
|
|
||||||
ex.getMessage() + "\n\tLocalMsg: " + ex.getLocalizedMessage() +
|
|
||||||
"\n\tCause: " + ex.getCause() + "\n\tException: " + ex;
|
|
||||||
log.info(ex);
|
|
||||||
throw new CommunicationHandlerException(errorMsg, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected void publishToQueue(String topic, MqttMessage message)
|
|
||||||
throws CommunicationHandlerException {
|
|
||||||
try {
|
|
||||||
client.publish(topic, message);
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug("Message: " + message.toString() + " to MQTT topic [" + topic +
|
|
||||||
"] published successfully");
|
|
||||||
}
|
|
||||||
} catch (MqttException ex) {
|
|
||||||
String errorMsg =
|
|
||||||
"MQTT Client Error" + "\n\tReason: " + ex.getReasonCode() + "\n\tMessage: " +
|
|
||||||
ex.getMessage() + "\n\tLocalMsg: " + ex.getLocalizedMessage() +
|
|
||||||
"\n\tCause: " + ex.getCause() + "\n\tException: " + ex;
|
|
||||||
log.info(errorMsg);
|
|
||||||
throw new CommunicationHandlerException(errorMsg, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback method which is triggered once the MQTT client losers its connection to the broker.
|
|
||||||
* Spawns a new thread that executes necessary actions to try and reconnect to the endpoint.
|
|
||||||
*
|
|
||||||
* @param throwable a Throwable Object containing the details as to why the failure occurred.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void connectionLost(Throwable throwable) {
|
|
||||||
log.warn("Lost Connection for client: " + this.clientId +
|
|
||||||
" to " + this.mqttBrokerEndPoint + ".\nThis was due to - " +
|
|
||||||
throwable.getMessage());
|
|
||||||
|
|
||||||
|
|
||||||
Thread reconnectThread = new Thread() {
|
|
||||||
public void run() {
|
|
||||||
connect();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
reconnectThread.setDaemon(true);
|
|
||||||
reconnectThread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback method which is triggered upon receiving a MQTT Message from the broker. Spawns a
|
|
||||||
* new thread that executes any actions to be taken with the received message.
|
|
||||||
*
|
|
||||||
* @param topic the MQTT-Topic to which the received message was published to and the
|
|
||||||
* client was subscribed to.
|
|
||||||
* @param mqttMessage the actual MQTT-Message that was received from the broker.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void messageArrived(final String topic, final MqttMessage mqttMessage) {
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.info("Got an MQTT message '" + mqttMessage.toString() + "' for topic '" + topic +
|
|
||||||
"'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread messageProcessorThread = new Thread() {
|
|
||||||
public void run() {
|
|
||||||
processIncomingMessage(mqttMessage, topic);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
messageProcessorThread.setDaemon(true);
|
|
||||||
messageProcessorThread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback method which gets triggered upon successful completion of a message delivery to
|
|
||||||
* the broker.
|
|
||||||
*
|
|
||||||
* @param iMqttDeliveryToken the MQTT-DeliveryToken which includes the details about the
|
|
||||||
* specific message delivery.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
|
|
||||||
String message = "";
|
|
||||||
try {
|
|
||||||
if (iMqttDeliveryToken.isComplete()) {
|
|
||||||
if (iMqttDeliveryToken.getMessage() != null){
|
|
||||||
message = iMqttDeliveryToken.getMessage().toString();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.error("MQTT Message not delivered");
|
|
||||||
}
|
|
||||||
} catch (MqttException e) {
|
|
||||||
log.error(
|
|
||||||
"Error occurred whilst trying to read the message from the MQTT delivery token.");
|
|
||||||
}
|
|
||||||
String topic = iMqttDeliveryToken.getTopics()[0];
|
|
||||||
String client = iMqttDeliveryToken.getClient().getClientId();
|
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug("Message - '" + message + "' of client [" + client + "] for the topic (" +
|
|
||||||
topic + ") was delivered successfully.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Closes the connection to the MQTT Broker.
|
|
||||||
*/
|
|
||||||
public void closeConnection() throws MqttException {
|
|
||||||
if (client != null && isConnected()) {
|
|
||||||
client.disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue