diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/pom.xml b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/pom.xml similarity index 97% rename from components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/pom.xml rename to components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/pom.xml index 8034dfefb4..861718e9be 100644 --- a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/pom.xml +++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/pom.xml @@ -29,7 +29,7 @@ 4.0.0 - org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl + org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl 1.9.2-SNAPSHOT war WSO2 Carbon - IoT Server RaspberryPi API diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/RaspberryPiService.java b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/RaspberryPiService.java new file mode 100644 index 0000000000..61e077a6b9 --- /dev/null +++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/RaspberryPiService.java @@ -0,0 +1,355 @@ +/* + * 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.raspberrypi.service; + +import org.apache.commons.io.FileUtils; +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.controlqueue.mqtt.MqttConfig; +import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppAccount; +import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig; +import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppServerClient; +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.raspberrypi.plugin.constants.RaspberrypiConstants; +import org.wso2.carbon.device.mgt.iot.raspberrypi.service.dto.DeviceJSON; +import org.wso2.carbon.device.mgt.iot.raspberrypi.service.transport.RaspberryPiMQTTSubscriber; +import org.wso2.carbon.device.mgt.iot.raspberrypi.service.util.RaspberrypiServiceUtils; +import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager; +import org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord; +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.*; +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.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +@API(name = "raspberrypi", version = "1.0.0", context = "/raspberrypi") +@DeviceType(value = "raspberrypi") +public class RaspberryPiService { + + private static Log log = LogFactory.getLog(RaspberryPiService.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 ConcurrentHashMap deviceToIpMap = new ConcurrentHashMap<>(); + private RaspberryPiMQTTSubscriber raspberryPiMQTTSubscriber; + + /** + * @param raspberryPiMQTTSubscriber + */ + public void setRaspberryPiMQTTSubscriber( + final RaspberryPiMQTTSubscriber raspberryPiMQTTSubscriber) { + this.raspberryPiMQTTSubscriber = raspberryPiMQTTSubscriber; + + if (MqttConfig.getInstance().isEnabled()) { + Runnable xmppStarter = new Runnable() { + @Override + public void run() { + raspberryPiMQTTSubscriber.initConnector(); + raspberryPiMQTTSubscriber.connectAndSubscribe(); + } + }; + + Thread xmppStarterThread = new Thread(xmppStarter); + xmppStarterThread.setDaemon(true); + xmppStarterThread.start(); + } else { + log.warn("MQTT disabled in 'devicemgt-config.xml'. Hence, VirtualFireAlarmMQTTConnector not started."); + } + } + + /** + * @return + */ + public RaspberryPiMQTTSubscriber getRaspberryPiMQTTSubscriber() { + return raspberryPiMQTTSubscriber; + } + + + /* --------------------------------------------------------------------------------------- + Device specific APIs - Control APIs + Data-Publishing APIs + --------------------------------------------------------------------------------------- */ + + @Path("controller/register/{owner}/{deviceId}/{ip}/{port}") + @POST + public String registerDeviceIP(@PathParam("owner") String owner, + @PathParam("deviceId") String deviceId, + @PathParam("ip") String deviceIP, + @PathParam("port") String devicePort, + @Context HttpServletResponse response, + @Context HttpServletRequest request) { + + //TODO:: Need to get IP from the request itself + String result; + + if (log.isDebugEnabled()) { + log.debug("Got register call from IP: " + deviceIP + " for Device ID: " + deviceId + " of owner: " + owner); + } + + String deviceHttpEndpoint = deviceIP + ":" + devicePort; + deviceToIpMap.put(deviceId, deviceHttpEndpoint); + + result = "Device-IP Registered"; + response.setStatus(Response.Status.OK.getStatusCode()); + + if (log.isDebugEnabled()) { + log.debug(result); + } + + return result; + } + + + /** + * @param owner + * @param deviceId + * @param protocol + * @param state + * @param response + */ + @Path("controller/bulb") + @POST + @Feature( code="bulb", name="Bulb On / Off", type="operation", + description="Switch on/off Raspberry Pi agent's bulb. (On / Off)") + public void switchBulb(@HeaderParam("owner") String owner, @HeaderParam("deviceId") String deviceId, + @HeaderParam("protocol") String protocol, @FormParam("state") String state, + @Context HttpServletResponse response) { + + try { + DeviceValidator deviceValidator = new DeviceValidator(); + if (!deviceValidator.isExist(owner, SUPER_TENANT, new DeviceIdentifier(deviceId, + RaspberrypiConstants.DEVICE_TYPE))) { + response.setStatus(Response.Status.UNAUTHORIZED.getStatusCode()); + return; + } + } catch (DeviceManagementException e) { + log.error("DeviceValidation Failed for deviceId: " + deviceId + " of user: " + owner); + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + return; + } + + String switchToState = state.toUpperCase(); + + if (!switchToState.equals(RaspberrypiConstants.STATE_ON) && !switchToState.equals( + RaspberrypiConstants.STATE_OFF)) { + log.error("The requested state change shoud be either - 'ON' or 'OFF'"); + response.setStatus(Response.Status.BAD_REQUEST.getStatusCode()); + return; + } + + String protocolString = protocol.toUpperCase(); + String callUrlPattern = RaspberrypiConstants.BULB_CONTEXT + switchToState; + + if (log.isDebugEnabled()) { + log.debug("Sending request to switch-bulb of device [" + deviceId + "] via " + protocolString); + } + + try { + switch (protocolString) { + case HTTP_PROTOCOL: + String deviceHTTPEndpoint = deviceToIpMap.get(deviceId); + if (deviceHTTPEndpoint == null) { + response.setStatus(Response.Status.PRECONDITION_FAILED.getStatusCode()); + return; + } + + RaspberrypiServiceUtils.sendCommandViaHTTP(deviceHTTPEndpoint, callUrlPattern, true); + break; + + case MQTT_PROTOCOL: + String mqttMessage = RaspberrypiConstants.BULB_CONTEXT.replace("/", ""); + RaspberrypiServiceUtils.sendCommandViaMQTT(owner, deviceId, mqttMessage, switchToState); + break; + + default: + response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode()); + return; + } + } catch (DeviceManagementException e) { + log.error("Failed to send switch-bulb request to device [" + deviceId + "] via " + protocolString); + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + return; + } + + response.setStatus(Response.Status.OK.getStatusCode()); + } + + + /** + * @param owner + * @param deviceId + * @param protocol + * @param response + * @return + */ + @Path("controller/readtemperature") + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Feature( code="readtemperature", name="Temperature", type="monitor", + description="Request temperature reading from Raspberry Pi agent") + public SensorRecord requestTemperature(@HeaderParam("owner") String owner, + @HeaderParam("deviceId") String deviceId, + @HeaderParam("protocol") String protocol, + @Context HttpServletResponse response) { + SensorRecord sensorRecord = null; + + DeviceValidator deviceValidator = new DeviceValidator(); + try { + if (!deviceValidator.isExist(owner, SUPER_TENANT, new DeviceIdentifier(deviceId, + RaspberrypiConstants.DEVICE_TYPE))) { + response.setStatus(Response.Status.UNAUTHORIZED.getStatusCode()); + } + } catch (DeviceManagementException e) { + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + } + + String protocolString = protocol.toUpperCase(); + + if (log.isDebugEnabled()) { + log.debug( + "Sending request to read raspberrypi-temperature of device [" + deviceId + "] via " + + protocolString); + } + + try { + switch (protocolString) { + case HTTP_PROTOCOL: + String deviceHTTPEndpoint = deviceToIpMap.get(deviceId); + if (deviceHTTPEndpoint == null) { + response.setStatus(Response.Status.PRECONDITION_FAILED.getStatusCode()); + } + + String temperatureValue = RaspberrypiServiceUtils.sendCommandViaHTTP(deviceHTTPEndpoint, + RaspberrypiConstants + .TEMPERATURE_CONTEXT, + false); + SensorDataManager.getInstance().setSensorRecord(deviceId, RaspberrypiConstants.SENSOR_TEMPERATURE, + temperatureValue, + Calendar.getInstance().getTimeInMillis()); + break; + + case MQTT_PROTOCOL: + String mqttMessage = RaspberrypiConstants.BULB_CONTEXT.replace("/", ""); + RaspberrypiServiceUtils.sendCommandViaMQTT(owner, deviceId, mqttMessage, ""); + break; + default: + response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode()); + } + sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId, + RaspberrypiConstants.SENSOR_TEMPERATURE); + } catch (DeviceManagementException | DeviceControllerException e) { + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + } + + response.setStatus(Response.Status.OK.getStatusCode()); + return sensorRecord; + } + + /** + * @param dataMsg + * @param response + */ + @Path("controller/push_temperature") + @POST + @Consumes(MediaType.APPLICATION_JSON) + public void pushTemperatureData(final DeviceJSON dataMsg, + @Context HttpServletResponse response, + @Context HttpServletRequest request) { + String owner = dataMsg.owner; + String deviceId = dataMsg.deviceId; + String deviceIp = dataMsg.reply; //TODO:: Get IP from request + float temperature = dataMsg.value; + + try { + DeviceValidator deviceValidator = new DeviceValidator(); + if (!deviceValidator.isExist(owner, SUPER_TENANT, new DeviceIdentifier(deviceId, + RaspberrypiConstants.DEVICE_TYPE))) { + response.setStatus(Response.Status.UNAUTHORIZED.getStatusCode()); + log.warn("Temperature data Received from unregistered raspberrypi device [" + deviceId + + "] for owner [" + owner + "]"); + return; + } + + String registeredIp = deviceToIpMap.get(deviceId); + + if (registeredIp == null) { + log.warn("Unregistered IP: Temperature Data Received from an un-registered IP " + deviceIp + + " for device ID - " + deviceId); + response.setStatus(Response.Status.PRECONDITION_FAILED.getStatusCode()); + return; + } else if (!registeredIp.equals(deviceIp)) { + log.warn("Conflicting IP: Received IP is " + deviceIp + ". Device with ID " + deviceId + + " is already registered under some other IP. Re-registration required"); + response.setStatus(Response.Status.CONFLICT.getStatusCode()); + return; + } + + if (log.isDebugEnabled()) { + log.debug("Received Pin Data Value: " + temperature + " degrees C"); + } + SensorDataManager.getInstance().setSensorRecord(deviceId, RaspberrypiConstants.SENSOR_TEMPERATURE, + String.valueOf(temperature), + Calendar.getInstance().getTimeInMillis()); + + if (!RaspberrypiServiceUtils.publishToDAS(dataMsg.owner, dataMsg.deviceId, dataMsg.value)) { + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + log.warn("An error occured whilst trying to publish temperature data of raspberrypi with ID [" + + deviceId + "] of owner [" + owner + "]"); + } + + } catch (DeviceManagementException e) { + String errorMsg = "Validation attempt for deviceId [" + deviceId + "] of owner [" + owner + "] failed.\n"; + log.error(errorMsg + Response.Status.INTERNAL_SERVER_ERROR.getReasonPhrase() + "\n" + e.getErrorMessage()); + } + } + +} diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/dto/DeviceJSON.java b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/dto/DeviceJSON.java similarity index 100% rename from components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/dto/DeviceJSON.java rename to components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/dto/DeviceJSON.java diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/exception/RaspberrypiException.java b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/exception/RaspberrypiException.java similarity index 100% rename from components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/exception/RaspberrypiException.java rename to components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/exception/RaspberrypiException.java diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/transport/RaspberryPiMQTTSubscriber.java b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/transport/RaspberryPiMQTTSubscriber.java similarity index 100% rename from components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/transport/RaspberryPiMQTTSubscriber.java rename to components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/transport/RaspberryPiMQTTSubscriber.java diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/util/RaspberrypiServiceUtils.java b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/util/RaspberrypiServiceUtils.java similarity index 100% rename from components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/util/RaspberrypiServiceUtils.java rename to components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/util/RaspberrypiServiceUtils.java diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/webapp/META-INF/webapp-classloading.xml b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/src/main/webapp/META-INF/webapp-classloading.xml similarity index 100% rename from components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/webapp/META-INF/webapp-classloading.xml rename to components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/src/main/webapp/META-INF/webapp-classloading.xml diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/src/main/webapp/WEB-INF/cxf-servlet.xml similarity index 100% rename from components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/webapp/WEB-INF/cxf-servlet.xml rename to components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/src/main/webapp/WEB-INF/cxf-servlet.xml diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/src/main/webapp/WEB-INF/web.xml b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..f2fe934b8d --- /dev/null +++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,54 @@ + + + RaspberryPi + RaspberryPi + + + CXFServlet + org.apache.cxf.transport.servlet.CXFServlet + 1 + + + + + CXFServlet + /* + + + + isAdminService + false + + + doAuthentication + true + + + + + managed-api-enabled + true + + + managed-api-owner + admin + + + managed-api-context-template + /raspberrypi/{version} + + + managed-api-application + raspberrypi + + + managed-api-isSecured + true + + + + diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/pom.xml b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/pom.xml new file mode 100644 index 0000000000..0bc06dc399 --- /dev/null +++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/pom.xml @@ -0,0 +1,160 @@ + + + + + + device-mgt-iot-raspberrypi + org.wso2.carbon.devicemgt-plugins + 1.9.2-SNAPSHOT + ../pom.xml + + + + 4.0.0 + org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl + 1.9.2-SNAPSHOT + war + WSO2 Carbon - IoT Server RaspberryPi API + WSO2 Carbon - RaspberryPi Service API Implementation + http://wso2.org + + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.common + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.core + provided + + + org.apache.axis2.wso2 + axis2-client + + + + + + + org.apache.cxf + cxf-rt-frontend-jaxws + provided + + + org.apache.cxf + cxf-rt-frontend-jaxrs + provided + + + org.apache.cxf + cxf-rt-transports-http + provided + + + + + org.eclipse.paho + mqtt-client + provided + + + + + org.apache.httpcomponents + httpasyncclient + 4.1 + provided + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot + provided + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl + provided + + + + + org.codehaus.jackson + jackson-core-asl + + + org.codehaus.jackson + jackson-jaxrs + + + javax + javaee-web-api + provided + + + javax.ws.rs + jsr311-api + provided + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.analytics + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.annotations + provided + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.webapp.publisher + provided + + + + + + + + + + maven-compiler-plugin + + UTF-8 + ${wso2.maven.compiler.source} + ${wso2.maven.compiler.target} + + + + maven-war-plugin + + raspberrypi_mgt + + + + + + \ No newline at end of file diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/RaspberryPiService.java b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/RaspberryPiService.java similarity index 59% rename from components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/RaspberryPiService.java rename to components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/RaspberryPiService.java index f87698f5c9..adf2a5e1a3 100644 --- a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/RaspberryPiService.java +++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/RaspberryPiService.java @@ -64,7 +64,6 @@ import java.util.List; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -@API(name = "raspberrypi", version = "1.0.0", context = "/raspberrypi") @DeviceType(value = "raspberrypi") public class RaspberryPiService { @@ -388,242 +387,4 @@ public class RaspberryPiService { return Long.toString(l, Character.MAX_RADIX); } - /* --------------------------------------------------------------------------------------- - Device specific APIs - Control APIs + Data-Publishing APIs - --------------------------------------------------------------------------------------- */ - - @Path("controller/register/{owner}/{deviceId}/{ip}/{port}") - @POST - public String registerDeviceIP(@PathParam("owner") String owner, - @PathParam("deviceId") String deviceId, - @PathParam("ip") String deviceIP, - @PathParam("port") String devicePort, - @Context HttpServletResponse response, - @Context HttpServletRequest request) { - - //TODO:: Need to get IP from the request itself - String result; - - if (log.isDebugEnabled()) { - log.debug("Got register call from IP: " + deviceIP + " for Device ID: " + deviceId + " of owner: " + owner); - } - - String deviceHttpEndpoint = deviceIP + ":" + devicePort; - deviceToIpMap.put(deviceId, deviceHttpEndpoint); - - result = "Device-IP Registered"; - response.setStatus(Response.Status.OK.getStatusCode()); - - if (log.isDebugEnabled()) { - log.debug(result); - } - - return result; - } - - - /** - * @param owner - * @param deviceId - * @param protocol - * @param state - * @param response - */ - @Path("controller/bulb") - @POST - @Feature( code="bulb", name="Bulb On / Off", type="operation", - description="Switch on/off Raspberry Pi agent's bulb. (On / Off)") - public void switchBulb(@HeaderParam("owner") String owner, @HeaderParam("deviceId") String deviceId, - @HeaderParam("protocol") String protocol, @FormParam("state") String state, - @Context HttpServletResponse response) { - - try { - DeviceValidator deviceValidator = new DeviceValidator(); - if (!deviceValidator.isExist(owner, SUPER_TENANT, new DeviceIdentifier(deviceId, - RaspberrypiConstants.DEVICE_TYPE))) { - response.setStatus(Response.Status.UNAUTHORIZED.getStatusCode()); - return; - } - } catch (DeviceManagementException e) { - log.error("DeviceValidation Failed for deviceId: " + deviceId + " of user: " + owner); - response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); - return; - } - - String switchToState = state.toUpperCase(); - - if (!switchToState.equals(RaspberrypiConstants.STATE_ON) && !switchToState.equals( - RaspberrypiConstants.STATE_OFF)) { - log.error("The requested state change shoud be either - 'ON' or 'OFF'"); - response.setStatus(Response.Status.BAD_REQUEST.getStatusCode()); - return; - } - - String protocolString = protocol.toUpperCase(); - String callUrlPattern = RaspberrypiConstants.BULB_CONTEXT + switchToState; - - if (log.isDebugEnabled()) { - log.debug("Sending request to switch-bulb of device [" + deviceId + "] via " + protocolString); - } - - try { - switch (protocolString) { - case HTTP_PROTOCOL: - String deviceHTTPEndpoint = deviceToIpMap.get(deviceId); - if (deviceHTTPEndpoint == null) { - response.setStatus(Response.Status.PRECONDITION_FAILED.getStatusCode()); - return; - } - - RaspberrypiServiceUtils.sendCommandViaHTTP(deviceHTTPEndpoint, callUrlPattern, true); - break; - - case MQTT_PROTOCOL: - String mqttMessage = RaspberrypiConstants.BULB_CONTEXT.replace("/", ""); - RaspberrypiServiceUtils.sendCommandViaMQTT(owner, deviceId, mqttMessage, switchToState); - break; - - default: - response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode()); - return; - } - } catch (DeviceManagementException e) { - log.error("Failed to send switch-bulb request to device [" + deviceId + "] via " + protocolString); - response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); - return; - } - - response.setStatus(Response.Status.OK.getStatusCode()); - } - - - /** - * @param owner - * @param deviceId - * @param protocol - * @param response - * @return - */ - @Path("controller/readtemperature") - @GET - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Feature( code="readtemperature", name="Temperature", type="monitor", - description="Request temperature reading from Raspberry Pi agent") - public SensorRecord requestTemperature(@HeaderParam("owner") String owner, - @HeaderParam("deviceId") String deviceId, - @HeaderParam("protocol") String protocol, - @Context HttpServletResponse response) { - SensorRecord sensorRecord = null; - - DeviceValidator deviceValidator = new DeviceValidator(); - try { - if (!deviceValidator.isExist(owner, SUPER_TENANT, new DeviceIdentifier(deviceId, - RaspberrypiConstants.DEVICE_TYPE))) { - response.setStatus(Response.Status.UNAUTHORIZED.getStatusCode()); - } - } catch (DeviceManagementException e) { - response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); - } - - String protocolString = protocol.toUpperCase(); - - if (log.isDebugEnabled()) { - log.debug( - "Sending request to read raspberrypi-temperature of device [" + deviceId + "] via " + - protocolString); - } - - try { - switch (protocolString) { - case HTTP_PROTOCOL: - String deviceHTTPEndpoint = deviceToIpMap.get(deviceId); - if (deviceHTTPEndpoint == null) { - response.setStatus(Response.Status.PRECONDITION_FAILED.getStatusCode()); - } - - String temperatureValue = RaspberrypiServiceUtils.sendCommandViaHTTP(deviceHTTPEndpoint, - RaspberrypiConstants - .TEMPERATURE_CONTEXT, - false); - SensorDataManager.getInstance().setSensorRecord(deviceId, RaspberrypiConstants.SENSOR_TEMPERATURE, - temperatureValue, - Calendar.getInstance().getTimeInMillis()); - break; - - case MQTT_PROTOCOL: - String mqttMessage = RaspberrypiConstants.BULB_CONTEXT.replace("/", ""); - RaspberrypiServiceUtils.sendCommandViaMQTT(owner, deviceId, mqttMessage, ""); - break; - default: - response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode()); - } - sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId, - RaspberrypiConstants.SENSOR_TEMPERATURE); - } catch (DeviceManagementException | DeviceControllerException e) { - response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); - } - - response.setStatus(Response.Status.OK.getStatusCode()); - return sensorRecord; - } - - /** - * @param dataMsg - * @param response - */ - @Path("controller/push_temperature") - @POST - @Consumes(MediaType.APPLICATION_JSON) - public void pushTemperatureData(final DeviceJSON dataMsg, - @Context HttpServletResponse response, - @Context HttpServletRequest request) { - String owner = dataMsg.owner; - String deviceId = dataMsg.deviceId; - String deviceIp = dataMsg.reply; //TODO:: Get IP from request - float temperature = dataMsg.value; - - try { - DeviceValidator deviceValidator = new DeviceValidator(); - if (!deviceValidator.isExist(owner, SUPER_TENANT, new DeviceIdentifier(deviceId, - RaspberrypiConstants.DEVICE_TYPE))) { - response.setStatus(Response.Status.UNAUTHORIZED.getStatusCode()); - log.warn("Temperature data Received from unregistered raspberrypi device [" + deviceId + - "] for owner [" + owner + "]"); - return; - } - - String registeredIp = deviceToIpMap.get(deviceId); - - if (registeredIp == null) { - log.warn("Unregistered IP: Temperature Data Received from an un-registered IP " + deviceIp + - " for device ID - " + deviceId); - response.setStatus(Response.Status.PRECONDITION_FAILED.getStatusCode()); - return; - } else if (!registeredIp.equals(deviceIp)) { - log.warn("Conflicting IP: Received IP is " + deviceIp + ". Device with ID " + deviceId + - " is already registered under some other IP. Re-registration required"); - response.setStatus(Response.Status.CONFLICT.getStatusCode()); - return; - } - - if (log.isDebugEnabled()) { - log.debug("Received Pin Data Value: " + temperature + " degrees C"); - } - SensorDataManager.getInstance().setSensorRecord(deviceId, RaspberrypiConstants.SENSOR_TEMPERATURE, - String.valueOf(temperature), - Calendar.getInstance().getTimeInMillis()); - - if (!RaspberrypiServiceUtils.publishToDAS(dataMsg.owner, dataMsg.deviceId, dataMsg.value)) { - response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); - log.warn("An error occured whilst trying to publish temperature data of raspberrypi with ID [" + - deviceId + "] of owner [" + owner + "]"); - } - - } catch (DeviceManagementException e) { - String errorMsg = "Validation attempt for deviceId [" + deviceId + "] of owner [" + owner + "] failed.\n"; - log.error(errorMsg + Response.Status.INTERNAL_SERVER_ERROR.getReasonPhrase() + "\n" + e.getErrorMessage()); - } - } - } diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/dto/DeviceJSON.java b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/dto/DeviceJSON.java new file mode 100644 index 0000000000..c8695d707d --- /dev/null +++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/dto/DeviceJSON.java @@ -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.raspberrypi.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; +} diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/exception/RaspberrypiException.java b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/exception/RaspberrypiException.java new file mode 100644 index 0000000000..21063ee9dc --- /dev/null +++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/exception/RaspberrypiException.java @@ -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.raspberrypi.service.exception; + +public class RaspberrypiException extends Exception { + private static final long serialVersionUID = 118512086957330189L; + + public RaspberrypiException(String errorMessage) { + super(errorMessage); + } + + public RaspberrypiException(String errorMessage, Throwable throwable) { + super(errorMessage, throwable); + } +} diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/transport/RaspberryPiMQTTSubscriber.java b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/transport/RaspberryPiMQTTSubscriber.java new file mode 100644 index 0000000000..2de9b9a257 --- /dev/null +++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/transport/RaspberryPiMQTTSubscriber.java @@ -0,0 +1,134 @@ +/* + * 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.raspberrypi.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.config.server.DeviceManagementConfigurationManager; +import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig; +import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttSubscriber; +import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants; +import org.wso2.carbon.device.mgt.iot.raspberrypi.service.util.RaspberrypiServiceUtils; +import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager; + +import java.io.File; +import java.util.Calendar; +import java.util.UUID; + +public class RaspberryPiMQTTSubscriber extends MqttSubscriber { + private static Log log = LogFactory.getLog(RaspberryPiMQTTSubscriber.class); + + private static final String serverName = + DeviceManagementConfigurationManager.getInstance().getDeviceManagementServerInfo().getName(); + private static final String subscribeTopic = + serverName + File.separator + "+" + File.separator + RaspberrypiConstants.DEVICE_TYPE + + File.separator + "+" + File.separator + "publisher"; + + private static final String iotServerSubscriber = UUID.randomUUID().toString().substring(0, 5); + private String mqttEndpoint; + + private RaspberryPiMQTTSubscriber() { + super(iotServerSubscriber, RaspberrypiConstants.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 mqttMessage) { + String ownerAndId = topic.replace("wso2" + File.separator + "iot" + File.separator, ""); + ownerAndId = ownerAndId.replace(File.separator + RaspberrypiConstants.DEVICE_TYPE + File.separator, ":"); + ownerAndId = ownerAndId.replace(File.separator + "publisher", ""); + + String owner = ownerAndId.split(":")[0]; + String deviceId = ownerAndId.split(":")[1]; + String receivedMessage = mqttMessage.toString(); + + if (log.isDebugEnabled()) { + log.debug("Received MQTT message for: {OWNER-" + owner + "} & {DEVICE.ID-" + deviceId + "}"); + log.debug("MQTT: Received Message [" + receivedMessage + "] topic: [" + topic + "]"); + } + + if (receivedMessage.contains("PUBLISHER")) { + float temperature = Float.parseFloat(receivedMessage.split(":")[2]); + + if (!RaspberrypiServiceUtils.publishToDAS(owner, deviceId, temperature)) { + log.error("MQTT Subscriber: Publishing data to DAS failed."); + } + + if (log.isDebugEnabled()) { + log.debug("MQTT Subscriber: Published data to DAS successfully."); + } + + } else if (receivedMessage.contains("TEMPERATURE")) { + String temperatureValue = receivedMessage.split(":")[1]; + SensorDataManager.getInstance().setSensorRecord(deviceId, RaspberrypiConstants.SENSOR_TEMPERATURE, + temperatureValue, + Calendar.getInstance().getTimeInMillis()); + } + } + + 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 { + RaspberryPiMQTTSubscriber.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(); + } +} + diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/util/RaspberrypiServiceUtils.java b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/util/RaspberrypiServiceUtils.java new file mode 100644 index 0000000000..56fe46dabb --- /dev/null +++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/util/RaspberrypiServiceUtils.java @@ -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.raspberrypi.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.exception.DeviceControllerException; +import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants; + +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 RaspberrypiServiceUtils { + private static final Log log = LogFactory.getLog(RaspberrypiServiceUtils.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 = RaspberrypiConstants.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 future = httpclient.execute( + request, new FutureCallback() { + @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, RaspberrypiConstants.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, RaspberrypiConstants.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; + } +} diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/webapp/META-INF/webapp-classloading.xml b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/webapp/META-INF/webapp-classloading.xml new file mode 100644 index 0000000000..fa44619195 --- /dev/null +++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/webapp/META-INF/webapp-classloading.xml @@ -0,0 +1,33 @@ + + + + + + + + + false + + + CXF,Carbon + diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/webapp/WEB-INF/cxf-servlet.xml new file mode 100644 index 0000000000..78b5061a0b --- /dev/null +++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/webapp/WEB-INF/web.xml b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/webapp/WEB-INF/web.xml similarity index 74% rename from components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/webapp/WEB-INF/web.xml rename to components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/webapp/WEB-INF/web.xml index 6518ec4e2e..eeb03052d3 100644 --- a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/webapp/WEB-INF/web.xml +++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl/src/main/webapp/WEB-INF/web.xml @@ -31,28 +31,12 @@ managed-api-enabled - true + false managed-api-owner admin - - managed-api-name - raspberrypi - - - managed-api-endpoint - http://localhost:9763/raspberrypi - - - managed-api-version - 1.0.0 - - - managed-api-context - /raspberrypi - managed-api-context-template /raspberrypi/{version} diff --git a/components/device-mgt-iot-raspberrypi/pom.xml b/components/device-mgt-iot-raspberrypi/pom.xml index b765b22f9c..668edbae63 100644 --- a/components/device-mgt-iot-raspberrypi/pom.xml +++ b/components/device-mgt-iot-raspberrypi/pom.xml @@ -37,7 +37,8 @@ org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl - org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl + org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl + org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl diff --git a/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/pom.xml b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/pom.xml index c8ca9b1665..4c346ed589 100644 --- a/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/pom.xml +++ b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/pom.xml @@ -44,7 +44,12 @@ org.wso2.carbon.devicemgt-plugins - org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl + org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl + war + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl war @@ -90,13 +95,22 @@ org.wso2.carbon.devicemgt-plugins - org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl + org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl war true ${basedir}/src/main/resources/webapps/ raspberrypi.war + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl + + war + true + ${basedir}/src/main/resources/webapps/ + raspberrypi_mgt.war + diff --git a/pom.xml b/pom.xml index cf5971b704..957b897342 100644 --- a/pom.xml +++ b/pom.xml @@ -440,7 +440,13 @@ org.wso2.carbon.devicemgt-plugins - org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl + org.wso2.carbon.device.mgt.iot.raspberrypi.mgt.service.impl + ${carbon.iot.device.mgt.version} + war + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.raspberrypi.controller.service.impl ${carbon.iot.device.mgt.version} war @@ -456,7 +462,14 @@ org.wso2.carbon.devicemgt-plugins - org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl + org.wso2.carbon.device.mgt.iot.virtualfirealarm.mgt.service.impl + ${carbon.iot.device.mgt.version} + war + + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.virtualfirealarm.controller.service.impl ${carbon.iot.device.mgt.version} war