diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/androidsense.apk b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/androidsense.apk deleted file mode 100644 index 89acc8aa0..000000000 Binary files a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/androidsense.apk and /dev/null differ diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/DataPublisherService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/DataPublisherService.java index 8840adf70..a95f94767 100644 --- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/DataPublisherService.java +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/DataPublisherService.java @@ -162,7 +162,7 @@ public class DataPublisherService extends Service { if (!mqttTransportHandler.isConnected()) { mqttTransportHandler.connect(); } - String topic = "wso2/" + LocalRegistry.getTenantDomain(context) + "/" + SenseConstants + String topic = LocalRegistry.getTenantDomain(context) + "/" + SenseConstants .DEVICE_TYPE + "/" + deviceId + "/data"; mqttTransportHandler.publishDeviceData(user, deviceId, jsonArray.toString(), topic); } diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/MQTTTransportHandler.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/MQTTTransportHandler.java index c2bd4b5d2..17884381c 100644 --- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/MQTTTransportHandler.java +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/MQTTTransportHandler.java @@ -77,7 +77,7 @@ public abstract class MQTTTransportHandler implements MqttCallback, TransportHan String username = LocalRegistry.getUsername(context); String deviceId = LocalRegistry.getDeviceId(context); this.clientId = deviceId + ":" + SenseConstants.DEVICE_TYPE; - this.subscribeTopic = "wso2/" + LocalRegistry.getTenantDomain(context)+ "/" + SenseConstants.DEVICE_TYPE + "/" + + this.subscribeTopic = LocalRegistry.getTenantDomain(context)+ "/" + SenseConstants.DEVICE_TYPE + "/" + deviceId + "/command/#"; this.clientWillTopic = DISCONNECTION_WILL_TOPIC_PREFIX + SenseConstants.DEVICE_TYPE; this.mqttBrokerEndPoint = LocalRegistry.getMqttEndpoint(context); diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics/src/main/resources/carbonapps/Android_Sense/EventReceiver_AndroidSense_1.0.0/EventReceiver_AndroidSense.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics/src/main/resources/carbonapps/Android_Sense/EventReceiver_AndroidSense_1.0.0/EventReceiver_AndroidSense.xml index 1fa0ea8e8..a72ab6ca2 100644 --- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics/src/main/resources/carbonapps/Android_Sense/EventReceiver_AndroidSense_1.0.0/EventReceiver_AndroidSense.xml +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics/src/main/resources/carbonapps/Android_Sense/EventReceiver_AndroidSense_1.0.0/EventReceiver_AndroidSense.xml @@ -17,13 +17,13 @@ ~ under the License. --> - + - wso2/carbon.super/android_sense/+/data + carbon.super/android_sense/+/data admin - device_id_json_path:event.metaData.deviceId,device_id_topic_hierarchy_index:3 + device_id_json_path:event.metaData.deviceId,device_id_topic_hierarchy_index:2 default - https://${server.host}:${mgt.transport.https.port}/dynamic-client-web/register + https://localhost:${carbon.https.port}/dynamic-client-web/register tcp://${mqtt.broker.host}:${mqtt.broker.port} true diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics/src/main/resources/carbonapps/Android_Sense/EventReceiver_AndroidSense_1.0.0/artifact.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics/src/main/resources/carbonapps/Android_Sense/EventReceiver_AndroidSense_1.0.0/artifact.xml index fd26f6961..1a154bc92 100644 --- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics/src/main/resources/carbonapps/Android_Sense/EventReceiver_AndroidSense_1.0.0/artifact.xml +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics/src/main/resources/carbonapps/Android_Sense/EventReceiver_AndroidSense_1.0.0/artifact.xml @@ -17,6 +17,6 @@ ~ under the License. --> - + EventReceiver_AndroidSense.xml diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics/src/main/resources/carbonapps/Android_Sense/artifacts.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics/src/main/resources/carbonapps/Android_Sense/artifacts.xml index 9f7632e9e..76ee9774c 100644 --- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics/src/main/resources/carbonapps/Android_Sense/artifacts.xml +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.analytics/src/main/resources/carbonapps/Android_Sense/artifacts.xml @@ -20,7 +20,7 @@ - + diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerServiceImpl.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerServiceImpl.java index 778ee067b..b3e448835 100644 --- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerServiceImpl.java +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerServiceImpl.java @@ -23,17 +23,12 @@ import org.apache.commons.logging.LogFactory; import org.wso2.carbon.analytics.dataservice.commons.SORT; import org.wso2.carbon.analytics.dataservice.commons.SortByField; import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException; -import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants; -import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.transport.AndroidSenseMQTTConnector; import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.APIUtil; import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.SensorRecord; import org.wso2.carbon.device.mgt.iot.androidsense.plugin.constants.AndroidSenseConstants; -import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig; -import org.wso2.carbon.device.mgt.iot.service.IoTServerStartupListener; -import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -45,7 +40,9 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * The api for @@ -53,21 +50,22 @@ import java.util.List; public class AndroidSenseControllerServiceImpl implements AndroidSenseControllerService { private static Log log = LogFactory.getLog(AndroidSenseControllerServiceImpl.class); - private static AndroidSenseMQTTConnector androidSenseMQTTConnector; @Path("device/{deviceId}/words") @POST public Response sendKeyWords(@PathParam("deviceId") String deviceId, @QueryParam("keywords") String keywords) { try { if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(new DeviceIdentifier(deviceId, - AndroidSenseConstants.DEVICE_TYPE))) { + AndroidSenseConstants.DEVICE_TYPE))) { return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); } - androidSenseMQTTConnector.publishDeviceData(deviceId, "add", keywords); + Map dynamicProperties = new HashMap<>(); + String publishTopic = APIUtil.getAuthenticatedUserTenantDomain() + + "/" + AndroidSenseConstants.DEVICE_TYPE + "/" + deviceId + "/command/words"; + dynamicProperties.put(AndroidSenseConstants.ADAPTER_TOPIC_PROPERTY, publishTopic); + APIUtil.getOutputEventAdapterService().publish(AndroidSenseConstants.MQTT_ADAPTER_NAME, + dynamicProperties, keywords); return Response.ok().build(); - } catch (TransportHandlerException e) { - log.error(e.getErrorMessage(), e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build(); } catch (DeviceAccessAuthorizationException e) { log.error(e.getErrorMessage(), e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build(); @@ -82,11 +80,13 @@ public class AndroidSenseControllerServiceImpl implements AndroidSenseController AndroidSenseConstants.DEVICE_TYPE), DeviceGroupConstants.Permissions.DEFAULT_OPERATOR_PERMISSIONS)) { return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); } - androidSenseMQTTConnector.publishDeviceData(deviceId, "threshold", threshold); + Map dynamicProperties = new HashMap<>(); + String publishTopic = APIUtil.getAuthenticatedUserTenantDomain() + + "/" + AndroidSenseConstants.DEVICE_TYPE + "/" + deviceId + "/command/threshold"; + dynamicProperties.put(AndroidSenseConstants.ADAPTER_TOPIC_PROPERTY, publishTopic); + APIUtil.getOutputEventAdapterService().publish(AndroidSenseConstants.MQTT_ADAPTER_NAME, + dynamicProperties, threshold); return Response.ok().build(); - } catch (TransportHandlerException e) { - log.error(e.getErrorMessage(), e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build(); } catch (DeviceAccessAuthorizationException e) { return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build(); } @@ -100,11 +100,13 @@ public class AndroidSenseControllerServiceImpl implements AndroidSenseController AndroidSenseConstants.DEVICE_TYPE), DeviceGroupConstants.Permissions.DEFAULT_OPERATOR_PERMISSIONS)) { return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); } - androidSenseMQTTConnector.publishDeviceData(deviceId, "remove", words); + Map dynamicProperties = new HashMap<>(); + String publishTopic = APIUtil.getAuthenticatedUserTenantDomain() + + "/" + AndroidSenseConstants.DEVICE_TYPE + "/" + deviceId + "/command/remove"; + dynamicProperties.put(AndroidSenseConstants.ADAPTER_TOPIC_PROPERTY, publishTopic); + APIUtil.getOutputEventAdapterService().publish(AndroidSenseConstants.MQTT_ADAPTER_NAME, + dynamicProperties, words); return Response.ok().build(); - } catch (TransportHandlerException e) { - log.error(e.getErrorMessage(), e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build(); } catch (DeviceAccessAuthorizationException e) { log.error(e.getErrorMessage(), e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build(); @@ -196,58 +198,4 @@ public class AndroidSenseControllerServiceImpl implements AndroidSenseController return sensorEventTableName; } - /** - * Fetches the `AndroidSenseMQTTConnector` specific to this Android Sense controller service. - * - * @return the 'AndroidSenseMQTTConnector' instance bound to the 'AndroidSenseMQTTConnector' variable of - * this service. - */ - @SuppressWarnings("Unused") - public AndroidSenseMQTTConnector getAndroidSenseMQTTConnector() { - return androidSenseMQTTConnector; - } - - /** - * Sets the `AndroidSenseMQTTConnector` variable of this Android Sense controller service. - * - * @param androidSenseMQTTConnector a 'AndroidSenseMQTTConnector' object that handles all MQTT related - * communications of any connected Android Sense device-type - */ - @SuppressWarnings("Unused") - public void setAndroidSenseMQTTConnector(final AndroidSenseMQTTConnector androidSenseMQTTConnector) { - Runnable connector = new Runnable() { - public void run() { - if (waitForServerStartup()) { - return; - } - //The delay is added for the server to starts up. - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - AndroidSenseControllerServiceImpl.androidSenseMQTTConnector = androidSenseMQTTConnector; - if (MqttConfig.getInstance().isEnabled()) { - synchronized (androidSenseMQTTConnector) { - androidSenseMQTTConnector.connect(); - } - } else { - log.warn("MQTT disabled in 'devicemgt-config.xml'. Hence, VirtualFireAlarmMQTTConnector not started."); - } - } - }; - Thread connectorThread = new Thread(connector); - connectorThread.start(); - } - - private boolean waitForServerStartup() { - while (!IoTServerStartupListener.isServerReady()) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - return true; - } - } - return false; - } } diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerServiceImpl.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerServiceImpl.java index 52bdc9bef..6c6ade4bc 100644 --- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerServiceImpl.java +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerServiceImpl.java @@ -26,11 +26,11 @@ import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants; +import org.wso2.carbon.device.mgt.iot.androidsense.plugin.mqtt.MqttConfig; import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.APIUtil; import org.wso2.carbon.device.mgt.iot.androidsense.plugin.constants.AndroidSenseConstants; import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.AndroidConfiguration; import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.Constants; -import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig; import org.wso2.carbon.device.mgt.iot.exception.IoTException; import org.wso2.carbon.device.mgt.iot.util.IoTUtil; @@ -61,7 +61,7 @@ public class AndroidSenseManagerServiceImpl implements AndroidSenseManagerServic if (APIUtil.getDeviceManagementService().isEnrolled(deviceIdentifier)) { AndroidConfiguration androidConfiguration = new AndroidConfiguration(); androidConfiguration.setTenantDomain(APIUtil.getAuthenticatedUserTenantDomain()); - String mqttEndpoint = MqttConfig.getInstance().getMqttQueueEndpoint(); + String mqttEndpoint = MqttConfig.getInstance().getBrokerEndpoint(); if (mqttEndpoint.contains(Constants.LOCALHOST)) { mqttEndpoint = mqttEndpoint.replace(Constants.LOCALHOST, IoTUtil.getHostName()); } @@ -84,7 +84,7 @@ public class AndroidSenseManagerServiceImpl implements AndroidSenseManagerServic if (added) { AndroidConfiguration androidConfiguration = new AndroidConfiguration(); androidConfiguration.setTenantDomain(APIUtil.getAuthenticatedUserTenantDomain()); - String mqttEndpoint = MqttConfig.getInstance().getMqttQueueEndpoint(); + String mqttEndpoint = MqttConfig.getInstance().getBrokerEndpoint(); if (mqttEndpoint.contains(Constants.LOCALHOST)) { mqttEndpoint = mqttEndpoint.replace(Constants.LOCALHOST, IoTUtil.getHostName()); } diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/transport/AndroidSenseMQTTConnector.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/transport/AndroidSenseMQTTConnector.java deleted file mode 100644 index f491eb2c9..000000000 --- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/transport/AndroidSenseMQTTConnector.java +++ /dev/null @@ -1,199 +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.androidsense.service.impl.transport; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttMessage; -import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService; -import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey; -import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException; -import org.wso2.carbon.context.PrivilegedCarbonContext; -import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.APIUtil; -import org.wso2.carbon.device.mgt.iot.androidsense.plugin.constants.AndroidSenseConstants; -import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig; -import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException; -import org.wso2.carbon.device.mgt.iot.transport.mqtt.MQTTTransportHandler; -import org.wso2.carbon.identity.jwt.client.extension.JWTClient; -import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; -import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; -import org.wso2.carbon.user.api.UserStoreException; - -import java.nio.charset.StandardCharsets; -import java.util.UUID; - -@SuppressWarnings("no JAX-WS annotation") -public class AndroidSenseMQTTConnector extends MQTTTransportHandler { - private static Log log = LogFactory.getLog(AndroidSenseMQTTConnector.class); - private static String subscribeTopic = AndroidSenseConstants.MQTT_SUBSCRIBE_WORDS_TOPIC; - private static String iotServerSubscriber = UUID.randomUUID().toString().substring(0, 5); - private static final String KEY_TYPE = "PRODUCTION"; - private static final String DEFAULT_PASSWORD = ""; - - private AndroidSenseMQTTConnector() { - super(iotServerSubscriber, AndroidSenseConstants.DEVICE_TYPE, - MqttConfig.getInstance().getMqttQueueEndpoint(), subscribeTopic); - } - - @Override - public void connect() { - Runnable connector = new Runnable() { - public void run() { - while (!isConnected()) { - PrivilegedCarbonContext.startTenantFlow(); - PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain( - AndroidSenseConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true); - try { - String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() - .getRealmConfiguration().getAdminUserName(); - PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(applicationUsername); - APIManagementProviderService apiManagementProviderService = APIUtil - .getAPIManagementProviderService(); - String[] tags = {AndroidSenseConstants.DEVICE_TYPE}; - ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys( - AndroidSenseConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true); - JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient(); - String scopes = "device_type_" + AndroidSenseConstants.DEVICE_TYPE + " device_mqtt_connector"; - AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(), - apiApplicationKey.getConsumerSecret(), applicationUsername, scopes); - //create token - String accessToken = accessTokenInfo.getAccessToken(); - setUsernameAndPassword(accessToken, DEFAULT_PASSWORD); - connectToQueue(); - } catch (TransportHandlerException e) { - log.warn("Connection/Subscription to MQTT Broker at: " + mqttBrokerEndPoint + " failed"); - try { - Thread.sleep(timeoutInterval); - } catch (InterruptedException ex) { - log.error("MQTT-Subscriber: Thread Sleep Interrupt Exception.", ex); - } - }catch (JWTClientException e) { - log.error("Failed to retrieve token from JWT Client.", e); - return; - } catch (UserStoreException e) { - log.error("Failed to retrieve the user.", e); - return; - } catch (APIManagerException e) { - log.error("Failed to create an application and generate keys.", e); - return; - } finally { - PrivilegedCarbonContext.endTenantFlow(); - } - } - } - }; - Thread connectorThread = new Thread(connector); - connectorThread.start(); - } - - /** - * @throws TransportHandlerException in the event of any exceptions that occur whilst processing the message. - */ - @Override - public void processIncomingMessage() throws TransportHandlerException { - } - - /** - * @param message the message (of the type specific to the protocol) received from the device. - * @throws TransportHandlerException - */ - @Override - public void processIncomingMessage(MqttMessage message) throws TransportHandlerException { - } - - - @Override - public void publishDeviceData(String... publishData) throws TransportHandlerException { - if (publishData.length != 3) { - String errorMsg = "Incorrect number of arguments received to SEND-MQTT Message. " + - "Need to be [owner, deviceId, content]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg); - } - String deviceId = publishData[0]; - String operation = publishData[1]; - String resource = publishData[2]; - MqttMessage pushMessage = new MqttMessage(); - String publishTopic = "wso2/" + APIUtil.getAuthenticatedUserTenantDomain() - + "/" + AndroidSenseConstants.DEVICE_TYPE + "/" + deviceId + "/command"; - if (operation.equals("add")) { - publishTopic = publishTopic + "/words"; - } else if (operation.equals("remove")) { - publishTopic = publishTopic + "/remove"; - } else if (operation.equals("threshold")) { - publishTopic = publishTopic + "/threshold"; - } else { - return; - } - String actualMessage = resource; - pushMessage.setPayload(actualMessage.getBytes(StandardCharsets.UTF_8)); - pushMessage.setQos(DEFAULT_MQTT_QUALITY_OF_SERVICE); - pushMessage.setRetained(false); - publishToQueue(publishTopic, pushMessage); - } - - @Override - public void processIncomingMessage(MqttMessage mqttMessage, String... strings) throws TransportHandlerException { - - } - - /** - * @throws TransportHandlerException in the event of any exceptions that occur whilst sending the message. - */ - @Override - public void publishDeviceData() throws TransportHandlerException { - - } - - /** - * @param publishData the message (of the type specific to the protocol) to be sent to the device. - * @throws TransportHandlerException in the event of any exceptions that occur whilst sending the message. - */ - @Override - public void publishDeviceData(MqttMessage publishData) throws TransportHandlerException { - - } - - @Override - public void disconnect () { - Runnable stopConnection = new Runnable() { - public void run() { - while (isConnected()) { - try { - closeConnection(); - } catch (MqttException e) { - if (log.isDebugEnabled()) { - log.warn("Unable to 'STOP' MQTT connection at broker at: " + mqttBrokerEndPoint - + " for device-type - " + AndroidSenseConstants.DEVICE_TYPE, e); - } - try { - Thread.sleep(timeoutInterval); - } catch (InterruptedException e1) { - log.error("MQTT-Terminator: Thread Sleep Interrupt Exception at device-type - " + - AndroidSenseConstants.DEVICE_TYPE, e1); - } - } - } - } - }; - Thread terminatorThread = new Thread(stopConnection); - terminatorThread.start(); - } -} diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/APIUtil.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/APIUtil.java index c102b099f..d4d4d922f 100644 --- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/APIUtil.java +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/APIUtil.java @@ -14,6 +14,7 @@ import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService; import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; import java.util.ArrayList; @@ -166,4 +167,22 @@ public class APIUtil { } return deviceAccessAuthorizationService; } + + public static OutputEventAdapterService getOutputEventAdapterService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + OutputEventAdapterService outputEventAdapterService = + (OutputEventAdapterService) ctx.getOSGiService(OutputEventAdapterService.class, null); + if (outputEventAdapterService == null) { + String msg = "Device Authorization service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return outputEventAdapterService; + } + + public static String getTenantDomainOftheUser() { + PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + return threadLocalCarbonContext.getTenantDomain(); + } + } diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/WEB-INF/cxf-servlet.xml index 31dfb6aee..2eee6325f 100644 --- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/WEB-INF/cxf-servlet.xml +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -26,7 +26,6 @@ - @@ -36,19 +35,5 @@ - - - - - - - - - - - - - diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/pom.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/pom.xml index 923d12a83..61c64749f 100644 --- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/pom.xml +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/pom.xml @@ -62,7 +62,13 @@ org.wso2.carbon.device.mgt.common, org.wso2.carbon.device.mgt.iot.*, org.wso2.carbon.device.mgt.extensions.feature.mgt.*, - org.wso2.carbon.utils.* + org.wso2.carbon.utils.*, + org.wso2.carbon.base, + org.wso2.carbon.context, + org.wso2.carbon.core, + org.wso2.carbon.core.util, + org.wso2.carbon.event.output.adapter.core, + org.wso2.carbon.event.output.adapter.core.exception !org.wso2.carbon.device.mgt.iot.androidsense.plugin.internal, @@ -103,5 +109,9 @@ org.wso2.carbon org.wso2.carbon.utils + + org.wso2.carbon.analytics-common + org.wso2.carbon.event.output.adapter.core + \ No newline at end of file diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/constants/AndroidSenseConstants.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/constants/AndroidSenseConstants.java index a467bcdc2..2b89ab00a 100644 --- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/constants/AndroidSenseConstants.java +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/constants/AndroidSenseConstants.java @@ -16,6 +16,10 @@ package org.wso2.carbon.device.mgt.iot.androidsense.plugin.constants; +import org.wso2.carbon.utils.CarbonUtils; + +import java.io.File; + public class AndroidSenseConstants { public final static String DEVICE_TYPE = "android_sense"; @@ -50,4 +54,27 @@ public class AndroidSenseConstants { public static final String MQTT_SUBSCRIBE_WORDS_TOPIC = "wso2/+/android_sense/+/data"; public static final String DATA_SOURCE_NAME = "jdbc/AndroidSenseDM_DB"; public final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super"; + + //mqtt tranport related constants + public static final String MQTT_ADAPTER_NAME = "android_sense_mqtt"; + public static final String MQTT_ADAPTER_TYPE = "oauth-mqtt"; + public static final String ADAPTER_TOPIC_PROPERTY = "topic"; + public static final String MQTT_PORT = "\\$\\{mqtt.broker.port\\}"; + public static final String MQTT_BROKER_HOST = "\\$\\{mqtt.broker.host\\}"; + public static final String CARBON_CONFIG_PORT_OFFSET = "Ports.Offset"; + public static final String DEFAULT_CARBON_LOCAL_IP_PROPERTY = "carbon.local.ip"; + public static final int CARBON_DEFAULT_PORT_OFFSET = 0; + public static final int DEFAULT_MQTT_PORT = 1883; + + public static final String USERNAME_PROPERTY_KEY = "username"; + public static final String DCR_PROPERTY_KEY = "dcrUrl"; + public static final String BROKER_URL_PROPERTY_KEY = "url"; + public static final String SCOPES_PROPERTY_KEY = "scopes"; + public static final String QOS_PROPERTY_KEY = "qos"; + public static final String CLIENT_ID_PROPERTY_KEY = "qos"; + public static final String CLEAR_SESSION_PROPERTY_KEY = "clearSession"; + public static final String TOPIC = "topic"; + + public static final String MQTT_CONFIG_LOCATION = CarbonUtils.getEtcCarbonConfigDirPath() + File.separator + + "mqtt.properties"; } diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/AndroidSenseManagerService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/AndroidSenseManagerService.java index 5241ce2ac..b1af7a224 100644 --- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/AndroidSenseManagerService.java +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/AndroidSenseManagerService.java @@ -50,7 +50,7 @@ public class AndroidSenseManagerService implements DeviceManagementService { @Override public ProvisioningConfig getProvisioningConfig() { - return new ProvisioningConfig(AndroidSenseConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true); + return new ProvisioningConfig(AndroidSenseConstants.DEVICE_TYPE_PROVIDER_DOMAIN, false); } @Override diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/dao/AndroidSenseDAO.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/dao/AndroidSenseDAO.java index 65f7f8e1a..dbd6aae64 100644 --- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/dao/AndroidSenseDAO.java +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/dao/AndroidSenseDAO.java @@ -21,7 +21,7 @@ import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.iot.androidsense.plugin.constants.AndroidSenseConstants; import org.wso2.carbon.device.mgt.iot.androidsense.plugin.exception.AndroidSenseDeviceMgtPluginException; -import org.wso2.carbon.device.mgt.iot.androidsense.plugin.impl.dao.util.AndroidSenseUtils; +import org.wso2.carbon.device.mgt.iot.androidsense.plugin.impl.util.AndroidSenseUtils; import java.sql.Connection; import java.sql.PreparedStatement; diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/dao/util/AndroidSenseUtils.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/dao/util/AndroidSenseUtils.java deleted file mode 100644 index 187649aa6..000000000 --- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/dao/util/AndroidSenseUtils.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * 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. - */ - -package org.wso2.carbon.device.mgt.iot.androidsense.plugin.impl.dao.util; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.device.mgt.common.Device; -import org.wso2.carbon.device.mgt.iot.androidsense.plugin.constants.AndroidSenseConstants; -import org.wso2.carbon.device.mgt.iot.androidsense.plugin.exception.AndroidSenseDeviceMgtPluginException; - -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.sql.DataSource; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.List; - -/** - * Contains utility methods used by plugin. - */ -public class AndroidSenseUtils { - - private static Log log = LogFactory.getLog(AndroidSenseUtils.class); - - public static String getDeviceProperty(List deviceProperties, String propertyKey) { - String deviceProperty = ""; - for(Device.Property property :deviceProperties){ - if(propertyKey.equals(property.getName())){ - deviceProperty = property.getValue(); - } - } - return deviceProperty; - } - - public static Device.Property getProperty(String property, String value) { - if (property != null) { - Device.Property prop = new Device.Property(); - prop.setName(property); - prop.setValue(value); - return prop; - } - return null; - } - - public static void cleanupResources(Connection conn, PreparedStatement stmt, ResultSet rs) { - if (rs != null) { - try { - rs.close(); - } catch (SQLException e) { - log.warn("Error occurred while closing result set", e); - } - } - if (stmt != null) { - try { - stmt.close(); - } catch (SQLException e) { - log.warn("Error occurred while closing prepared statement", e); - } - } - if (conn != null) { - try { - conn.close(); - } catch (SQLException e) { - log.warn("Error occurred while closing database connection", e); - } - } - } - - public static void cleanupResources(PreparedStatement stmt, ResultSet rs) { - cleanupResources(null, stmt, rs); - } - - /** - * Creates the device management schema. - */ - public static void setupDeviceManagementSchema() throws AndroidSenseDeviceMgtPluginException { - try { - Context ctx = new InitialContext(); - DataSource dataSource = (DataSource) ctx.lookup(AndroidSenseConstants.DATA_SOURCE_NAME); - DeviceSchemaInitializer initializer = - new DeviceSchemaInitializer(dataSource); - log.info("Initializing device management repository database schema"); - initializer.createRegistryDatabase(); - - } catch (NamingException e) { - log.error("Error while looking up the data source: " + AndroidSenseConstants.DATA_SOURCE_NAME); - } catch (Exception e) { - throw new AndroidSenseDeviceMgtPluginException("Error occurred while initializing Iot Device " + - "Management database schema", e); - } - } -} diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/util/AndroidSenseStartupListener.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/util/AndroidSenseStartupListener.java new file mode 100644 index 000000000..894d6531e --- /dev/null +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/util/AndroidSenseStartupListener.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.iot.androidsense.plugin.impl.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.core.ServerStartupObserver; + +import java.io.IOException; + +/** + * Startup listener to create an output adapter after server starts up. + */ +public class AndroidSenseStartupListener implements ServerStartupObserver { + private static final Log log = LogFactory.getLog(AndroidSenseStartupListener.class); + + @Override + public void completingServerStartup() { + } + + @Override + public void completedServerStartup() { + try { + AndroidSenseUtils.setupMqttOutputAdapter(); + } catch (IOException e) { + log.error("Failed to intilaize the virtual firealarm output adapter", e); + } + } + +} diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/util/AndroidSenseUtils.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/util/AndroidSenseUtils.java new file mode 100644 index 000000000..cba547d56 --- /dev/null +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/util/AndroidSenseUtils.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ + +package org.wso2.carbon.device.mgt.iot.androidsense.plugin.impl.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.base.ServerConfiguration; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.core.util.Utils; +import org.wso2.carbon.device.mgt.iot.androidsense.plugin.constants.AndroidSenseConstants; +import org.wso2.carbon.device.mgt.iot.androidsense.plugin.exception.AndroidSenseDeviceMgtPluginException; +import org.wso2.carbon.device.mgt.iot.androidsense.plugin.internal.AndroidSenseManagementDataHolder; +import org.wso2.carbon.event.output.adapter.core.MessageType; +import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration; +import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.sql.DataSource; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * Contains utility methods used by plugin. + */ +public class AndroidSenseUtils { + + private static Log log = LogFactory.getLog(AndroidSenseUtils.class); + + public static void cleanupResources(Connection conn, PreparedStatement stmt, ResultSet rs) { + if (rs != null) { + try { + rs.close(); + } catch (SQLException e) { + log.warn("Error occurred while closing result set", e); + } + } + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException e) { + log.warn("Error occurred while closing prepared statement", e); + } + } + if (conn != null) { + try { + conn.close(); + } catch (SQLException e) { + log.warn("Error occurred while closing database connection", e); + } + } + } + + public static void cleanupResources(PreparedStatement stmt, ResultSet rs) { + cleanupResources(null, stmt, rs); + } + + /** + * Creates the device management schema. + */ + public static void setupDeviceManagementSchema() throws AndroidSenseDeviceMgtPluginException { + try { + Context ctx = new InitialContext(); + DataSource dataSource = (DataSource) ctx.lookup(AndroidSenseConstants.DATA_SOURCE_NAME); + DeviceSchemaInitializer initializer = + new DeviceSchemaInitializer(dataSource); + log.info("Initializing device management repository database schema"); + initializer.createRegistryDatabase(); + + } catch (NamingException e) { + log.error("Error while looking up the data source: " + AndroidSenseConstants.DATA_SOURCE_NAME); + } catch (Exception e) { + throw new AndroidSenseDeviceMgtPluginException("Error occurred while initializing Iot Device " + + "Management database schema", e); + } + } + + public static void setupMqttOutputAdapter() throws IOException { + OutputEventAdapterConfiguration outputEventAdapterConfiguration = + createMqttOutputEventAdapterConfiguration(AndroidSenseConstants.MQTT_ADAPTER_NAME, + AndroidSenseConstants.MQTT_ADAPTER_TYPE, MessageType.TEXT); + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain( + AndroidSenseConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true); + AndroidSenseManagementDataHolder.getInstance().getOutputEventAdapterService() + .create(outputEventAdapterConfiguration); + } catch (OutputEventAdapterException e) { + log.error("Unable to create Output Event Adapter : " + AndroidSenseConstants.MQTT_ADAPTER_NAME, e); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } + + /** + * Create Output Event Adapter Configuration for given configuration. + * + * @param name Output Event Adapter name + * @param type Output Event Adapter type + * @param msgFormat Output Event Adapter message format + * @return OutputEventAdapterConfiguration instance for given configuration + */ + private static OutputEventAdapterConfiguration createMqttOutputEventAdapterConfiguration(String name, String type, + String msgFormat) throws IOException { + OutputEventAdapterConfiguration outputEventAdapterConfiguration = new OutputEventAdapterConfiguration(); + outputEventAdapterConfiguration.setName(name); + outputEventAdapterConfiguration.setType(type); + outputEventAdapterConfiguration.setMessageFormat(msgFormat); + File configFile = new File(AndroidSenseConstants.MQTT_CONFIG_LOCATION); + if (configFile.exists()) { + Map mqttAdapterProperties = new HashMap<>(); + InputStream propertyStream = configFile.toURI().toURL().openStream(); + Properties properties = new Properties(); + properties.load(propertyStream); + mqttAdapterProperties.put(AndroidSenseConstants.USERNAME_PROPERTY_KEY, properties.getProperty( + AndroidSenseConstants.USERNAME_PROPERTY_KEY)); + mqttAdapterProperties.put(AndroidSenseConstants.DCR_PROPERTY_KEY, Utils.replaceSystemProperty( + properties.getProperty(AndroidSenseConstants.DCR_PROPERTY_KEY))); + mqttAdapterProperties.put(AndroidSenseConstants.BROKER_URL_PROPERTY_KEY, replaceMqttProperty( + properties.getProperty(AndroidSenseConstants.BROKER_URL_PROPERTY_KEY))); + mqttAdapterProperties.put(AndroidSenseConstants.SCOPES_PROPERTY_KEY, properties.getProperty( + AndroidSenseConstants.SCOPES_PROPERTY_KEY)); + mqttAdapterProperties.put(AndroidSenseConstants.CLEAR_SESSION_PROPERTY_KEY, properties.getProperty( + AndroidSenseConstants.CLEAR_SESSION_PROPERTY_KEY)); + mqttAdapterProperties.put(AndroidSenseConstants.QOS_PROPERTY_KEY, properties.getProperty( + AndroidSenseConstants.QOS_PROPERTY_KEY)); + mqttAdapterProperties.put(AndroidSenseConstants.CLIENT_ID_PROPERTY_KEY, ""); + outputEventAdapterConfiguration.setStaticProperties(mqttAdapterProperties); + } + return outputEventAdapterConfiguration; + } + + public static String replaceMqttProperty(String urlWithPlaceholders) { + urlWithPlaceholders = Utils.replaceSystemProperty(urlWithPlaceholders); + urlWithPlaceholders = urlWithPlaceholders.replaceAll(AndroidSenseConstants.MQTT_PORT, "" + + (AndroidSenseConstants.DEFAULT_MQTT_PORT + getPortOffset())); + urlWithPlaceholders = urlWithPlaceholders.replaceAll(AndroidSenseConstants.MQTT_BROKER_HOST, + System.getProperty(AndroidSenseConstants.DEFAULT_CARBON_LOCAL_IP_PROPERTY, "localhost")); + return urlWithPlaceholders; + } + + private static int getPortOffset() { + ServerConfiguration carbonConfig = ServerConfiguration.getInstance(); + String portOffset = System.getProperty("portOffset", carbonConfig.getFirstProperty( + AndroidSenseConstants.CARBON_CONFIG_PORT_OFFSET)); + try { + if ((portOffset != null)) { + return Integer.parseInt(portOffset.trim()); + } else { + return AndroidSenseConstants.CARBON_DEFAULT_PORT_OFFSET; + } + } catch (NumberFormatException e) { + return AndroidSenseConstants.CARBON_DEFAULT_PORT_OFFSET; + } + } +} diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/dao/util/DeviceSchemaInitializer.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/util/DeviceSchemaInitializer.java similarity index 99% rename from components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/dao/util/DeviceSchemaInitializer.java rename to components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/util/DeviceSchemaInitializer.java index 1b4935010..eabc7f44b 100644 --- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/dao/util/DeviceSchemaInitializer.java +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/util/DeviceSchemaInitializer.java @@ -16,7 +16,7 @@ * under the License. */ -package org.wso2.carbon.device.mgt.iot.androidsense.plugin.impl.dao.util; +package org.wso2.carbon.device.mgt.iot.androidsense.plugin.impl.util; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/internal/AndroidSenseManagementDataHolder.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/internal/AndroidSenseManagementDataHolder.java new file mode 100644 index 000000000..29fde7519 --- /dev/null +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/internal/AndroidSenseManagementDataHolder.java @@ -0,0 +1,48 @@ +/* + * 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.androidsense.plugin.internal; + +import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService; + +/** + * DataHolder class of plugins component. + */ +public class AndroidSenseManagementDataHolder { + + private OutputEventAdapterService outputEventAdapterService; + + private static AndroidSenseManagementDataHolder thisInstance = new AndroidSenseManagementDataHolder(); + + private AndroidSenseManagementDataHolder() { + } + + public static AndroidSenseManagementDataHolder getInstance() { + return thisInstance; + } + + public OutputEventAdapterService getOutputEventAdapterService() { + return outputEventAdapterService; + } + + public void setOutputEventAdapterService( + OutputEventAdapterService outputEventAdapterService) { + this.outputEventAdapterService = outputEventAdapterService; + } + +} diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/internal/AndroidSenseManagementServiceComponent.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/internal/AndroidSenseManagementServiceComponent.java index 4896302ea..f287650ec 100644 --- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/internal/AndroidSenseManagementServiceComponent.java +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/internal/AndroidSenseManagementServiceComponent.java @@ -21,14 +21,23 @@ import org.apache.commons.logging.LogFactory; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.osgi.service.component.ComponentContext; +import org.wso2.carbon.core.ServerStartupObserver; import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService; import org.wso2.carbon.device.mgt.iot.androidsense.plugin.exception.AndroidSenseDeviceMgtPluginException; import org.wso2.carbon.device.mgt.iot.androidsense.plugin.impl.AndroidSenseManagerService; -import org.wso2.carbon.device.mgt.iot.androidsense.plugin.impl.dao.util.AndroidSenseUtils; +import org.wso2.carbon.device.mgt.iot.androidsense.plugin.impl.util.AndroidSenseStartupListener; +import org.wso2.carbon.device.mgt.iot.androidsense.plugin.impl.util.AndroidSenseUtils; +import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService; /** * @scr.component name="org.wso2.carbon.device.mgt.iot.android.internal.AndroidSenseManagementServiceComponent" * immediate="true" + * @scr.reference name="event.output.adapter.service" + * interface="org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService" + * cardinality="1..1" + * policy="dynamic" + * bind="setOutputEventAdapterService" + * unbind="unsetOutputEventAdapterService" */ public class AndroidSenseManagementServiceComponent { @@ -43,6 +52,8 @@ public class AndroidSenseManagementServiceComponent { BundleContext bundleContext = ctx.getBundleContext(); androidServiceRegRef = bundleContext.registerService(DeviceManagementService.class.getName(), new AndroidSenseManagerService(), null); + bundleContext.registerService(ServerStartupObserver.class.getName(), new AndroidSenseStartupListener(), + null); String setupOption = System.getProperty("setup"); if (setupOption != null) { if (log.isDebugEnabled()) { @@ -81,4 +92,20 @@ public class AndroidSenseManagementServiceComponent { log.error("Error occurred while de-activating Android Device Management bundle", e); } } + + /** + * Initialize the Output EventAdapter Service dependency + * + * @param outputEventAdapterService Output EventAdapter Service reference + */ + protected void setOutputEventAdapterService(OutputEventAdapterService outputEventAdapterService) { + AndroidSenseManagementDataHolder.getInstance().setOutputEventAdapterService(outputEventAdapterService); + } + + /** + * De-reference the Output EventAdapter Service dependency. + */ + protected void unsetOutputEventAdapterService(OutputEventAdapterService outputEventAdapterService) { + AndroidSenseManagementDataHolder.getInstance().setOutputEventAdapterService(null); + } } diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/mqtt/MqttConfig.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/mqtt/MqttConfig.java new file mode 100644 index 000000000..893a764dd --- /dev/null +++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/mqtt/MqttConfig.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.iot.androidsense.plugin.mqtt; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.iot.androidsense.plugin.constants.AndroidSenseConstants; +import org.wso2.carbon.device.mgt.iot.androidsense.plugin.impl.util.AndroidSenseUtils; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +public class MqttConfig { + + private static String brokerEndpoint; + + private static MqttConfig mqttConfig = new MqttConfig(); + private static final Log log = LogFactory.getLog(MqttConfig.class); + + private MqttConfig() { + File configFile = new File(AndroidSenseConstants.MQTT_CONFIG_LOCATION); + if (configFile.exists()) { + try { + InputStream propertyStream = configFile.toURI().toURL().openStream(); + Properties properties = new Properties(); + properties.load(propertyStream); + brokerEndpoint = AndroidSenseUtils.replaceMqttProperty( + properties.getProperty(AndroidSenseConstants.BROKER_URL_PROPERTY_KEY)); + } catch (IOException e) { + log.error("Failed to read the mqtt.properties file" + e); + } + } + } + + public static MqttConfig getInstance() { + return mqttConfig; + } + + public String getBrokerEndpoint() { + return brokerEndpoint; + } +} diff --git a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoControllerServiceImpl.java b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoControllerServiceImpl.java index 795885f4f..eecf8aca6 100644 --- a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoControllerServiceImpl.java +++ b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoControllerServiceImpl.java @@ -55,8 +55,7 @@ public class ArduinoControllerServiceImpl implements ArduinoControllerService { public Response switchBulb(@PathParam("deviceId") String deviceId, @QueryParam("state") String state) { try { if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(new DeviceIdentifier(deviceId, - ArduinoConstants.DEVICE_TYPE), - DeviceGroupConstants.Permissions.DEFAULT_OPERATOR_PERMISSIONS)) { + ArduinoConstants.DEVICE_TYPE), DeviceGroupConstants.Permissions.DEFAULT_OPERATOR_PERMISSIONS)) { return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); } LinkedList deviceControlList = internalControlsQueue.get(deviceId); diff --git a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoManagerServiceImpl.java b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoManagerServiceImpl.java index c2e0cd30d..65fdd4ef9 100644 --- a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoManagerServiceImpl.java +++ b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoManagerServiceImpl.java @@ -32,7 +32,6 @@ import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.iot.arduino.service.impl.util.APIUtil; import org.wso2.carbon.device.mgt.iot.arduino.plugin.constants.ArduinoConstants; import org.wso2.carbon.device.mgt.iot.arduino.service.impl.util.ZipUtil; -import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException; import org.wso2.carbon.device.mgt.iot.util.ZipArchive; import org.wso2.carbon.identity.jwt.client.extension.JWTClient; import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; @@ -172,9 +171,6 @@ public class ArduinoManagerServiceImpl implements ArduinoManagerService { } catch (APIManagerException ex) { log.error(ex.getMessage(), ex); return Response.status(500).entity(ex.getMessage()).build(); - } catch (DeviceControllerException ex) { - log.error(ex.getMessage(), ex); - return Response.status(500).entity(ex.getMessage()).build(); } catch (IOException ex) { log.error(ex.getMessage(), ex); return Response.status(500).entity(ex.getMessage()).build(); @@ -185,7 +181,7 @@ public class ArduinoManagerServiceImpl implements ArduinoManagerService { } private ZipArchive createDownloadFile(String owner, String deviceName) - throws DeviceManagementException, JWTClientException, DeviceControllerException, APIManagerException, + throws DeviceManagementException, JWTClientException, APIManagerException, UserStoreException { if (owner == null) { throw new IllegalArgumentException("Error on createDownloadFile() Owner is null!"); diff --git a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/ZipUtil.java b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/ZipUtil.java index 015972a26..31bb0807c 100644 --- a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/ZipUtil.java +++ b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/ZipUtil.java @@ -19,8 +19,6 @@ package org.wso2.carbon.device.mgt.iot.arduino.service.impl.util; import org.wso2.carbon.device.mgt.common.DeviceManagementException; -import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig; -import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig; import org.wso2.carbon.device.mgt.iot.exception.IoTException; import org.wso2.carbon.device.mgt.iot.util.IoTUtil; import org.wso2.carbon.device.mgt.iot.util.IotDeviceManagementUtil; diff --git a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/plugin/impl/ArduinoManagerService.java b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/plugin/impl/ArduinoManagerService.java index 4a4de0cb7..743e9fb48 100644 --- a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/plugin/impl/ArduinoManagerService.java +++ b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/plugin/impl/ArduinoManagerService.java @@ -54,7 +54,7 @@ public class ArduinoManagerService implements DeviceManagementService { @Override public ProvisioningConfig getProvisioningConfig() { - return new ProvisioningConfig(DEVICE_TYPE_PROVIDER_DOMAIN, true); + return new ProvisioningConfig(DEVICE_TYPE_PROVIDER_DOMAIN, false); } @Override diff --git a/components/iot-plugins/iot-analytics/org.wso2.carbon.device.mgt.iot.analytics/src/main/resources/carbonapps/Temperature/Eventreceiver_http_temperature_1.0.0/EventReceiver_http_temperature.xml b/components/iot-plugins/iot-analytics/org.wso2.carbon.device.mgt.iot.analytics/src/main/resources/carbonapps/Temperature/Eventreceiver_http_temperature_1.0.0/EventReceiver_http_temperature.xml index 896c90dc5..c134fa361 100644 --- a/components/iot-plugins/iot-analytics/org.wso2.carbon.device.mgt.iot.analytics/src/main/resources/carbonapps/Temperature/Eventreceiver_http_temperature_1.0.0/EventReceiver_http_temperature.xml +++ b/components/iot-plugins/iot-analytics/org.wso2.carbon.device.mgt.iot.analytics/src/main/resources/carbonapps/Temperature/Eventreceiver_http_temperature_1.0.0/EventReceiver_http_temperature.xml @@ -24,7 +24,7 @@ default all 100 - https://${server.host}:${mgt.transport.https.port}/services/OAuth2TokenValidationService + https://localhost:${carbon.https.port}/services/OAuth2TokenValidationService admin diff --git a/components/iot-plugins/iot-analytics/org.wso2.carbon.device.mgt.iot.analytics/src/main/resources/carbonapps/Temperature/Eventreceiver_mqtt_temperature_1.0.0/EventReceiver_mqtt_temperature.xml b/components/iot-plugins/iot-analytics/org.wso2.carbon.device.mgt.iot.analytics/src/main/resources/carbonapps/Temperature/Eventreceiver_mqtt_temperature_1.0.0/EventReceiver_mqtt_temperature.xml index 9c93e8d49..e49b93544 100644 --- a/components/iot-plugins/iot-analytics/org.wso2.carbon.device.mgt.iot.analytics/src/main/resources/carbonapps/Temperature/Eventreceiver_mqtt_temperature_1.0.0/EventReceiver_mqtt_temperature.xml +++ b/components/iot-plugins/iot-analytics/org.wso2.carbon.device.mgt.iot.analytics/src/main/resources/carbonapps/Temperature/Eventreceiver_mqtt_temperature_1.0.0/EventReceiver_mqtt_temperature.xml @@ -19,11 +19,11 @@ - wso2/carbon.super/raspberrypi/+/temperature + carbon.super/+/+/temperature admin - device_id_json_path:event.metaData.deviceId,device_id_topic_hierarchy_index:3 + device_id_json_path:event.metaData.deviceId,device_id_topic_hierarchy_index:2 default - https://${server.host}:${mgt.transport.https.port}/dynamic-client-web/register + https://localhost:${carbon.https.port}/dynamic-client-web/register temperatureMqttClient tcp://${mqtt.broker.host}:${mqtt.broker.port} true diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.extension/pom.xml b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.extension/pom.xml new file mode 100644 index 000000000..8690f20dd --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.extension/pom.xml @@ -0,0 +1,57 @@ + + + + + iot-base-plugin + org.wso2.carbon.devicemgt-plugins + 2.1.0-SNAPSHOT + ../pom.xml + + 4.0.0 + + org.wso2.carbon.device.mgt.iot.input.adapter.extension + bundle + WSO2 Carbon - Device Mgt Input Adaptor Extensions Module + Provides the back-end functionality of Input adaptor + http://wso2.org + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.artifactId} + ${project.artifactId} + + org.wso2.carbon.device.mgt.iot.input.adapter.extension.* + + + + + + + + \ No newline at end of file diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/extension/ContentInfo.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/extension/ContentInfo.java new file mode 100644 index 000000000..b5cb23acf --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/extension/ContentInfo.java @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +package org.wso2.carbon.device.mgt.iot.input.adapter.extension; + +/** + * This is the return type of the ContentValidator. + */ +public class ContentInfo { + /** + * true if the content is valid if not when false then content will not be published. + */ + private boolean isValidContent; + /** + * msgText to be returned. eg: if the content is encrypted then we can decrypt the content and then validate and + * return it. + */ + private Object message; + + public ContentInfo(boolean isValidContent, Object message) { + this.isValidContent = isValidContent; + this.message = message; + } + + public boolean isValidContent() { + return isValidContent; + } + + public void setIsValidContent(boolean isValidContent) { + this.isValidContent = isValidContent; + } + + public Object getMessage() { + return message; + } + + public void setMessage(Object message) { + this.message = message; + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/extension/ContentTransformer.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/extension/ContentTransformer.java new file mode 100644 index 000000000..c38e80af4 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/extension/ContentTransformer.java @@ -0,0 +1,17 @@ +package org.wso2.carbon.device.mgt.iot.input.adapter.extension; + +import java.util.Map; + +/** + * Content Transformer will be triggered through input adapters + */ +public interface ContentTransformer { + + /** + * This is used to transform the receiver content + * @param message message to be format + * @param dynamicProperties related to transport. + * @return transformed message + */ + Object transform(Object message, Map dynamicProperties); +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/extension/ContentValidator.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/extension/ContentValidator.java new file mode 100644 index 000000000..f53a0a775 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/extension/ContentValidator.java @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +package org.wso2.carbon.device.mgt.iot.input.adapter.extension; + +import java.util.Map; + +/** + * This interface will be triggered to validate the stream content before publishing. + */ +public interface ContentValidator { + /** + * @param contentValidationParams that related to input adapter. + * @param dynamicParameter that message. + * @return ContentInfo. + */ + ContentInfo validate(Object message, Map contentValidationParams, Map dynamicParameter); +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/extension/DefaultContentTransformer.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/extension/DefaultContentTransformer.java new file mode 100644 index 000000000..a14f6b022 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/extension/DefaultContentTransformer.java @@ -0,0 +1,14 @@ +package org.wso2.carbon.device.mgt.iot.input.adapter.extension; + +import java.util.Map; + +/** + * This holds the default implementation of ContentTransformer + */ +public class DefaultContentTransformer implements ContentTransformer{ + + @Override + public Object transform(Object message, Map dynamicProperties) { + return message; + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/extension/DefaultContentValidator.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/extension/DefaultContentValidator.java new file mode 100644 index 000000000..a2abeef76 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.extension/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/extension/DefaultContentValidator.java @@ -0,0 +1,15 @@ +package org.wso2.carbon.device.mgt.iot.input.adapter.extension; + +import java.util.Map; + +/** + * This holds the default implementation of content validator interface. + */ +public class DefaultContentValidator implements ContentValidator { + + @Override + public ContentInfo validate(Object message, Map params, Map dynamicParams) { + return new ContentInfo(true, message); + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/pom.xml b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/pom.xml new file mode 100644 index 000000000..cd398000a --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/pom.xml @@ -0,0 +1,142 @@ + + + + + iot-base-plugin + org.wso2.carbon.devicemgt-plugins + 2.1.0-SNAPSHOT + ../pom.xml + + 4.0.0 + + org.wso2.carbon.device.mgt.iot.input.adapter.http + bundle + WSO2 Carbon - Device Mgt Input Adaptor Module - Http + Provides the back-end functionality of Input adaptor + http://wso2.org + + + + org.wso2.carbon.analytics-common + org.wso2.carbon.event.input.adapter.core + + + org.wso2.carbon + org.wso2.carbon.logging + + + org.wso2.carbon + org.wso2.carbon.core + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.input.adapter.extension + + + com.googlecode.json-simple.wso2 + json-simple + + + com.jayway.jsonpath + json-path + + + org.wso2.carbon.identity + org.wso2.carbon.identity.oauth.stub + + + org.wso2.orbit.com.nimbusds + nimbus-jose-jwt + + + org.wso2.carbon + org.wso2.carbon.user.api + + + org.wso2.carbon + org.wso2.carbon.user.core + + + commons-pool.wso2 + commons-pool + + + + + + + org.apache.felix + maven-scr-plugin + + + generate-scr-descriptor + + scr + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.artifactId} + ${project.artifactId} + + org.wso2.carbon.device.mgt.iot.input.adapter.http.internal, + org.wso2.carbon.device.mgt.iot.input.adapter.http.internal.* + + + !org.wso2.carbon.device.mgt.iot.input.adapter.http.internal, + !org.wso2.carbon.device.mgt.iot.input.adapter.http.internal.*, + org.wso2.carbon.device.mgt.iot.input.adapter.http.* + + + org.wso2.carbon.event.input.adapter.core, + org.wso2.carbon.event.input.adapter.core.*, + javax.xml.namespace; version=0.0.0, + com.jayway.jsonpath.*, + com.nimbusds.jose, + com.nimbusds.jose.crypto, + com.nimbusds.jwt, + org.osgi.framework, + org.osgi.service.component, + javax.servlet, + javax.servlet.http, + org.osgi.service.http, + org.wso2.carbon.user.api, + org.wso2.carbon.user.core.service, + org.wso2.carbon.user.core.tenant, + org.apache.commons.pool, + org.apache.commons.pool.impl + + * + + + + + + + \ No newline at end of file diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/HTTPEventAdapter.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/HTTPEventAdapter.java new file mode 100644 index 000000000..bed31990e --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/HTTPEventAdapter.java @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ + +package org.wso2.carbon.device.mgt.iot.input.adapter.http; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.service.http.HttpService; +import org.osgi.service.http.NamespaceException; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.iot.input.adapter.http.internal.InputAdapterServiceDataHolder; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapter; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener; +import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterException; +import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterRuntimeException; +import org.wso2.carbon.event.input.adapter.core.exception.TestConnectionNotSupportedException; +import org.wso2.carbon.device.mgt.iot.input.adapter.http.util.HTTPEventAdapterConstants; +import org.wso2.carbon.utils.multitenancy.MultitenantConstants; + +import javax.servlet.ServletException; +import java.util.Hashtable; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +public final class HTTPEventAdapter implements InputEventAdapter { + + private final InputEventAdapterConfiguration eventAdapterConfiguration; + private final Map globalProperties; + private InputEventAdapterListener eventAdaptorListener; + private final String id = UUID.randomUUID().toString(); + public static ExecutorService executorService; + private static final Log log = LogFactory.getLog(HTTPEventAdapter.class); + private boolean isConnected = false; + + public HTTPEventAdapter(InputEventAdapterConfiguration eventAdapterConfiguration, + Map globalProperties) { + this.eventAdapterConfiguration = eventAdapterConfiguration; + this.globalProperties = globalProperties; + } + + @Override + public void init(InputEventAdapterListener eventAdaptorListener) throws InputEventAdapterException { + this.eventAdaptorListener = eventAdaptorListener; + + //ThreadPoolExecutor will be assigned if it is null + if (executorService == null) { + int minThread; + int maxThread; + long defaultKeepAliveTime; + int jobQueueSize; + + //If global properties are available those will be assigned else constant values will be assigned + if (globalProperties.get(HTTPEventAdapterConstants.ADAPTER_MIN_THREAD_POOL_SIZE_NAME) != null) { + minThread = Integer + .parseInt(globalProperties.get(HTTPEventAdapterConstants.ADAPTER_MIN_THREAD_POOL_SIZE_NAME)); + } else { + minThread = HTTPEventAdapterConstants.ADAPTER_MIN_THREAD_POOL_SIZE; + } + + if (globalProperties.get(HTTPEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE_NAME) != null) { + maxThread = Integer + .parseInt(globalProperties.get(HTTPEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE_NAME)); + } else { + maxThread = HTTPEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE; + } + + if (globalProperties.get(HTTPEventAdapterConstants.ADAPTER_KEEP_ALIVE_TIME_NAME) != null) { + defaultKeepAliveTime = Integer + .parseInt(globalProperties.get(HTTPEventAdapterConstants.ADAPTER_KEEP_ALIVE_TIME_NAME)); + } else { + defaultKeepAliveTime = HTTPEventAdapterConstants.DEFAULT_KEEP_ALIVE_TIME_IN_MILLS; + } + + if (globalProperties.get(HTTPEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME) != null) { + jobQueueSize = Integer + .parseInt(globalProperties.get(HTTPEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME)); + } else { + jobQueueSize = HTTPEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE; + } + + RejectedExecutionHandler rejectedExecutionHandler = new RejectedExecutionHandler() { + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + try { + executor.getQueue().put(r); + } catch (InterruptedException e) { + log.error("Exception while adding event to executor queue : " + e.getMessage(), e); + } + } + + }; + + executorService = new ThreadPoolExecutor(minThread, maxThread, defaultKeepAliveTime, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue(jobQueueSize), rejectedExecutionHandler); + + } + } + + @Override + public void testConnect() throws TestConnectionNotSupportedException { + throw new TestConnectionNotSupportedException("not-supported"); + } + + @Override + public void connect() { + registerDynamicEndpoint(eventAdapterConfiguration.getName()); + isConnected = true; + } + + @Override + public void disconnect() { + if (isConnected){ + isConnected = false; + unregisterDynamicEndpoint(eventAdapterConfiguration.getName()); + } + } + + @Override + public void destroy() { + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof HTTPEventAdapter)) + return false; + + HTTPEventAdapter that = (HTTPEventAdapter) o; + + return id.equals(that.id); + + } + + @Override + public int hashCode() { + return id.hashCode(); + } + + @Override + public boolean isEventDuplicatedInCluster() { + return false; + } + + @Override + public boolean isPolling() { + return false; + } + + private void registerDynamicEndpoint(String adapterName) { + + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + + String endpoint; + if (MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { + endpoint = HTTPEventAdapterConstants.ENDPOINT_PREFIX + adapterName; + } else { + endpoint = HTTPEventAdapterConstants.ENDPOINT_PREFIX + HTTPEventAdapterConstants.ENDPOINT_TENANT_KEY + + HTTPEventAdapterConstants.ENDPOINT_URL_SEPARATOR + tenantDomain + + HTTPEventAdapterConstants.ENDPOINT_URL_SEPARATOR + adapterName; + } + + try { + HttpService httpService = InputAdapterServiceDataHolder.getHTTPService(); + if (httpService == null) { + throw new InputEventAdapterRuntimeException( + "HttpService not available, Error in registering endpoint " + endpoint); + } + httpService.registerServlet(endpoint, new HTTPMessageServlet(eventAdaptorListener, tenantId, + eventAdapterConfiguration), + new Hashtable(), httpService.createDefaultHttpContext()); + } catch (ServletException | NamespaceException e) { + throw new InputEventAdapterRuntimeException("Error in registering endpoint " + endpoint, e); + } + + } + + private void unregisterDynamicEndpoint(String adapterName) { + HttpService httpService = InputAdapterServiceDataHolder.getHTTPService(); + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String endpoint; + if (MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { + endpoint = HTTPEventAdapterConstants.ENDPOINT_PREFIX + adapterName; + } else { + endpoint = HTTPEventAdapterConstants.ENDPOINT_PREFIX + HTTPEventAdapterConstants.ENDPOINT_TENANT_KEY + + HTTPEventAdapterConstants.ENDPOINT_URL_SEPARATOR + tenantDomain + + HTTPEventAdapterConstants.ENDPOINT_URL_SEPARATOR + adapterName; + } + if (httpService != null) { + httpService.unregister(endpoint); + } + + } +} \ No newline at end of file diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/HTTPEventAdapterFactory.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/HTTPEventAdapterFactory.java new file mode 100644 index 000000000..f5197a030 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/HTTPEventAdapterFactory.java @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2005 - 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ +package org.wso2.carbon.device.mgt.iot.input.adapter.http; + +import org.wso2.carbon.event.input.adapter.core.InputEventAdapter; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterFactory; +import org.wso2.carbon.event.input.adapter.core.MessageType; +import org.wso2.carbon.event.input.adapter.core.Property; +import org.wso2.carbon.device.mgt.iot.input.adapter.http.util.HTTPEventAdapterConstants; +import org.wso2.carbon.utils.CarbonUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.ResourceBundle; + +/** + * The http event adapter factory class to create a http input adapter + */ +public class HTTPEventAdapterFactory extends InputEventAdapterFactory { + + private ResourceBundle resourceBundle = + ResourceBundle.getBundle("org.wso2.carbon.device.mgt.iot.input.adapter.http.i18n.Resources", Locale.getDefault()); + private int httpPort; + private int httpsPort; + + public HTTPEventAdapterFactory() { + int portOffset = getPortOffset(); + httpPort = HTTPEventAdapterConstants.DEFAULT_HTTP_PORT + portOffset; + httpsPort = HTTPEventAdapterConstants.DEFAULT_HTTPS_PORT + portOffset; + } + + @Override + public String getType() { + return HTTPEventAdapterConstants.ADAPTER_TYPE_HTTP; + } + + @Override + public List getSupportedMessageFormats() { + List supportInputMessageTypes = new ArrayList<>(); + supportInputMessageTypes.add(MessageType.JSON); + supportInputMessageTypes.add(MessageType.TEXT); + supportInputMessageTypes.add(MessageType.XML); + supportInputMessageTypes.add(MessageType.WSO2EVENT); + return supportInputMessageTypes; + } + + @Override + public List getPropertyList() { + + List propertyList = new ArrayList<>(); + + // Transport Exposed + Property exposedTransportsProperty = new Property(HTTPEventAdapterConstants.EXPOSED_TRANSPORTS); + exposedTransportsProperty.setRequired(true); + exposedTransportsProperty.setDisplayName( + resourceBundle.getString(HTTPEventAdapterConstants.EXPOSED_TRANSPORTS)); + exposedTransportsProperty.setOptions( + new String[]{HTTPEventAdapterConstants.HTTPS, HTTPEventAdapterConstants.HTTP, + HTTPEventAdapterConstants.LOCAL, HTTPEventAdapterConstants.ALL}); + exposedTransportsProperty.setDefaultValue(HTTPEventAdapterConstants.ALL); + propertyList.add(exposedTransportsProperty); + + // OAUTH validation endpoint admin service username + Property username = new Property(HTTPEventAdapterConstants.USERNAME); + username.setRequired(true); + username.setDisplayName(resourceBundle.getString(HTTPEventAdapterConstants.USERNAME)); + username.setHint(resourceBundle.getString(HTTPEventAdapterConstants.USERNAME_HINT)); + propertyList.add(username); + + // OAUTH validation endpoint admin service password + Property password = new Property(HTTPEventAdapterConstants.PASSWORD); + password.setRequired(true); + password.setDisplayName(resourceBundle.getString(HTTPEventAdapterConstants.PASSWORD)); + password.setHint(resourceBundle.getString(HTTPEventAdapterConstants.PASSWORD_HINT)); + propertyList.add(password); + + // OAUTH validation endpoint + Property tokenValidationEndpoint = new Property(HTTPEventAdapterConstants.TOKEN_VALIDATION_ENDPOINT_URL); + tokenValidationEndpoint.setRequired(true); + tokenValidationEndpoint.setDisplayName(resourceBundle.getString(HTTPEventAdapterConstants.TOKEN_VALIDATION_ENDPOINT_URL)); + tokenValidationEndpoint.setHint(resourceBundle.getString(HTTPEventAdapterConstants.TOKEN_VALIDATION_ENDPOINT_URL_HINT)); + propertyList.add(tokenValidationEndpoint); + + Property maximumHttpConnectionPerHost = new Property(HTTPEventAdapterConstants.MAXIMUM_HTTP_CONNECTION_PER_HOST); + maximumHttpConnectionPerHost.setRequired(true); + maximumHttpConnectionPerHost.setDisplayName(resourceBundle.getString( + HTTPEventAdapterConstants.MAXIMUM_HTTP_CONNECTION_PER_HOST)); + maximumHttpConnectionPerHost.setHint(resourceBundle.getString( + HTTPEventAdapterConstants.MAXIMUM_HTTP_CONNECTION_PER_HOST_HINT)); + maximumHttpConnectionPerHost.setDefaultValue(HTTPEventAdapterConstants.MAX_HTTP_CONNECTION); + propertyList.add(maximumHttpConnectionPerHost); + + Property maxTotalHttpConnection = new Property(HTTPEventAdapterConstants.MAXIMUM_TOTAL_HTTP_CONNECTION); + maxTotalHttpConnection.setRequired(true); + maxTotalHttpConnection.setDisplayName(resourceBundle.getString( + HTTPEventAdapterConstants.MAXIMUM_TOTAL_HTTP_CONNECTION)); + maxTotalHttpConnection.setHint(resourceBundle.getString( + HTTPEventAdapterConstants.MAXIMUM_TOTAL_HTTP_CONNECTION_HINT)); + maxTotalHttpConnection.setDefaultValue(HTTPEventAdapterConstants.MAX_TOTAL_HTTP_CONNECTION); + propertyList.add(maxTotalHttpConnection); + + //Content Validator details + Property contentValidator = new Property(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME); + contentValidator.setDisplayName( + resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME)); + contentValidator.setRequired(false); + contentValidator.setHint( + resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT)); + contentValidator.setDefaultValue(HTTPEventAdapterConstants.DEFAULT); + propertyList.add(contentValidator); + + //Content Validator Params details + Property contentValidatorParams = new Property(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS); + contentValidatorParams.setDisplayName( + resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS)); + contentValidatorParams.setRequired(false); + contentValidatorParams.setHint( + resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS_HINT)); + contentValidatorParams.setDefaultValue(HTTPEventAdapterConstants.HTTP_CONTENT_VALIDATION_DEFAULT_PARAMETERS); + propertyList.add(contentValidatorParams); + + //Content Transformer details + Property contentTransformer = new Property(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME); + contentTransformer.setDisplayName( + resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME)); + contentTransformer.setRequired(false); + contentTransformer.setHint( + resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT)); + contentTransformer.setDefaultValue(HTTPEventAdapterConstants.DEFAULT); + propertyList.add(contentTransformer); + return propertyList; + } + + @Override + public String getUsageTips() { + return resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_USAGE_TIPS_PREFIX) + httpPort + + resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_USAGE_TIPS_MID1) + httpsPort + + resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_USAGE_TIPS_MID2) + httpPort + + resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_USAGE_TIPS_MID3) + httpsPort + + resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_USAGE_TIPS_POSTFIX); + } + + @Override + public InputEventAdapter createEventAdapter(InputEventAdapterConfiguration eventAdapterConfiguration, + Map globalProperties) { + return new HTTPEventAdapter(eventAdapterConfiguration, globalProperties); + } + + private int getPortOffset() { + return CarbonUtils.getPortFromServerConfig(HTTPEventAdapterConstants.CARBON_CONFIG_PORT_OFFSET_NODE) + 1; + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/HTTPMessageServlet.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/HTTPMessageServlet.java new file mode 100644 index 000000000..41e783700 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/HTTPMessageServlet.java @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2005 - 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ + +package org.wso2.carbon.device.mgt.iot.input.adapter.http; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentInfo; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentTransformer; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.DefaultContentTransformer; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.DefaultContentValidator; +import org.wso2.carbon.device.mgt.iot.input.adapter.http.exception.HTTPContentInitializationException; +import org.wso2.carbon.device.mgt.iot.input.adapter.http.jwt.JWTAuthenticator; +import org.wso2.carbon.device.mgt.iot.input.adapter.http.oauth.OAuthAuthenticator; +import org.wso2.carbon.device.mgt.iot.input.adapter.http.util.AuthenticationInfo; +import org.wso2.carbon.device.mgt.iot.input.adapter.http.util.HTTPEventAdapterConstants; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentValidator; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +/** + * This will act as the event reciver. + */ +public class HTTPMessageServlet extends HttpServlet { + + private static final String AUTH_MESSAGE_STORE_AUTHENTICATION_INFO = "AUTH_MESSAGE_STORE_AUTHENTICATION_INFO"; + private static final String AUTH_FAILURE_RESPONSE = "_AUTH_FAILURE_"; + + + + private static Log log = LogFactory.getLog(HTTPMessageServlet.class); + + private static Map contentValidationProperties; + private static ContentValidator contentValidator; + private static ContentTransformer contentTransformer; + private InputEventAdapterListener eventAdaptorListener; + private int tenantId; + private String exposedTransports; + private static JWTAuthenticator jwtAuthenticator; + private static OAuthAuthenticator oAuthAuthenticator; + + public HTTPMessageServlet(InputEventAdapterListener eventAdaptorListener, int tenantId, + InputEventAdapterConfiguration eventAdapterConfiguration) { + this.eventAdaptorListener = eventAdaptorListener; + this.tenantId = tenantId; + this.exposedTransports = eventAdapterConfiguration.getProperties().get( + HTTPEventAdapterConstants.EXPOSED_TRANSPORTS); + HTTPMessageServlet.contentValidationProperties = new HashMap<>(); + String contentValidationParams = eventAdapterConfiguration.getProperties().get( + HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS); + if (contentValidationParams != null && !contentValidationParams.isEmpty()) { + String validationParams[] = contentValidationParams.split(","); + for (String validationParam : validationParams) { + String[] validationProperty = validationParam.split(":"); + if (validationProperty.length == 2) { + contentValidationProperties.put(validationProperty[0], validationProperty[1]); + } + } + } + + String className = eventAdapterConfiguration.getProperties().get( + HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME); + if (HTTPEventAdapterConstants.DEFAULT.equals(className)) { + contentValidator = new DefaultContentValidator(); + } else { + try { + Class contentValidatorClass = Class.forName(className) + .asSubclass(ContentValidator.class); + contentValidator = contentValidatorClass.newInstance(); + } catch (ClassNotFoundException e) { + throw new HTTPContentInitializationException( + "Unable to find the class validator: " + className, e); + } catch (InstantiationException e) { + throw new HTTPContentInitializationException( + "Unable to create an instance of :" + className, e); + } catch (IllegalAccessException e) { + throw new HTTPContentInitializationException("Access of the instance in not allowed.", e); + } + } + + String contentTransformerClassName = eventAdapterConfiguration.getProperties().get( + HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME); + if (contentTransformerClassName != null && contentTransformerClassName.equals(HTTPEventAdapterConstants.DEFAULT)) { + contentTransformer = new DefaultContentTransformer(); + } else if (contentTransformerClassName != null && !contentTransformerClassName.isEmpty()) { + try { + Class contentTransformerClass = Class.forName(contentTransformerClassName) + .asSubclass(ContentTransformer.class); + contentTransformer = contentTransformerClass.newInstance(); + } catch (ClassNotFoundException e) { + throw new HTTPContentInitializationException( + "Unable to find the class transformer: " + contentTransformerClassName, e); + } catch (InstantiationException e) { + throw new HTTPContentInitializationException( + "Unable to create an instance of :" + contentTransformerClassName, e); + } catch (IllegalAccessException e) { + throw new HTTPContentInitializationException("Access of the instance in not allowed.", e); + } + } + + jwtAuthenticator = new JWTAuthenticator(); + oAuthAuthenticator = new OAuthAuthenticator(eventAdapterConfiguration); + } + + @Override + protected void doPost(HttpServletRequest req, + HttpServletResponse res) throws IOException { + + String data = this.inputStreamToString(req.getInputStream()); + if (data == null) { + log.warn("Event Object is empty/null"); + return; + } + AuthenticationInfo authenticationInfo = null; + if (exposedTransports.equalsIgnoreCase(HTTPEventAdapterConstants.HTTPS)) { + if (!req.isSecure()) { + res.setStatus(403); + log.error("Only Secured endpoint is enabled for requests"); + return; + } else { + authenticationInfo = this.checkAuthentication(req); + int tenantId = authenticationInfo != null ? authenticationInfo.getTenantId() : -1; + if (tenantId == -1) { + res.getOutputStream().write(AUTH_FAILURE_RESPONSE.getBytes()); + res.setStatus(401); + log.error("Authentication failed for the request"); + return; + } else if (tenantId != this.tenantId) { + res.getOutputStream().write(AUTH_FAILURE_RESPONSE.getBytes()); + res.setStatus(401); + log.error("Authentication failed for the request"); + return; + } + } + } else if (exposedTransports.equalsIgnoreCase(HTTPEventAdapterConstants.HTTP)) { + if (req.isSecure()) { + res.setStatus(403); + log.error("Only unsecured endpoint is enabled for requests"); + return; + } + } else { + authenticationInfo = this.checkAuthentication(req); + int tenantId = authenticationInfo != null ? authenticationInfo.getTenantId() : -1; + if (tenantId == -1) { + res.getOutputStream().write(AUTH_FAILURE_RESPONSE.getBytes()); + res.setStatus(401); + log.error("Authentication failed for the request"); + return; + } else if (tenantId != this.tenantId) { + res.getOutputStream().write(AUTH_FAILURE_RESPONSE.getBytes()); + res.setStatus(401); + log.error("Authentication failed for the request"); + return; + } + } + + if (log.isDebugEnabled()) { + log.debug("Message : " + data); + } + + if (authenticationInfo != null) { + Map paramMap = new HashMap<>(); + Enumeration reqParameterNames = req.getParameterNames(); + while (reqParameterNames.hasMoreElements()) { + String paramterName = reqParameterNames.nextElement(); + paramMap.put(paramterName, req.getParameter(paramterName)); + } + paramMap.put(HTTPEventAdapterConstants.USERNAME_TAG, authenticationInfo.getUsername()); + paramMap.put(HTTPEventAdapterConstants.TENANT_DOMAIN_TAG, authenticationInfo.getTenantDomain()); + if (contentValidator != null && contentTransformer != null) { + data = (String) contentTransformer.transform(data, paramMap); + ContentInfo contentInfo = contentValidator.validate(data, contentValidationProperties, paramMap); + if (contentInfo != null && contentInfo.isValidContent()) { + HTTPEventAdapter.executorService.submit(new HTTPRequestProcessor(eventAdaptorListener, + (String) contentInfo.getMessage(), tenantId)); + } + } + } + } + + @Override + protected void doGet(HttpServletRequest req, + HttpServletResponse res) throws IOException { + doPost(req, res); + } + + public class HTTPRequestProcessor implements Runnable { + + private InputEventAdapterListener inputEventAdapterListener; + private String payload; + private int tenantId; + + public HTTPRequestProcessor(InputEventAdapterListener inputEventAdapterListener, String payload, int tenantId) { + this.inputEventAdapterListener = inputEventAdapterListener; + this.payload = payload; + this.tenantId = tenantId; + } + + public void run() { + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true); + if (log.isDebugEnabled()) { + log.debug("Event received in HTTP Event Adapter - " + payload); + } + if (payload != null) { + inputEventAdapterListener.onEvent(payload); + } else { + log.warn("Dropping the empty/null event received through http adapter"); + } + } catch (Exception e) { + log.error("Error while parsing http request for processing: " + e.getMessage(), e); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } + } + + private AuthenticationInfo checkAuthentication(HttpServletRequest req) { + AuthenticationInfo authenticationInfo = (AuthenticationInfo) req.getSession().getAttribute( + AUTH_MESSAGE_STORE_AUTHENTICATION_INFO); + if (authenticationInfo != null) { + return authenticationInfo; + } + if (jwtAuthenticator.isJWTHeaderExist(req)) { + authenticationInfo = jwtAuthenticator.authenticate(req); + } else { + authenticationInfo = oAuthAuthenticator.authenticate(req); + } + if (authenticationInfo != null) { + boolean success = authenticationInfo.isAuthenticated(); + if (success) { + req.getSession().setAttribute(AUTH_MESSAGE_STORE_AUTHENTICATION_INFO, authenticationInfo); + } + } + return authenticationInfo; + } + + private String inputStreamToString(InputStream in) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] buff = new byte[1024]; + int i; + while ((i = in.read(buff)) > 0) { + out.write(buff, 0, i); + } + out.close(); + return out.toString(); + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/exception/HTTPContentInitializationException.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/exception/HTTPContentInitializationException.java new file mode 100644 index 000000000..3b30ed4b8 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/exception/HTTPContentInitializationException.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.mgt.iot.input.adapter.http.exception; + +/** + * This exception will thrown when content validator is failed to intialiaze. + */ +public class HTTPContentInitializationException extends RuntimeException { + private String errMessage; + + public HTTPContentInitializationException(String msg, Exception nestedEx) { + super(msg, nestedEx); + setErrorMessage(msg); + } + + public HTTPContentInitializationException(String message, Throwable cause) { + super(message, cause); + setErrorMessage(message); + } + + public HTTPContentInitializationException(String msg) { + super(msg); + setErrorMessage(msg); + } + + public HTTPContentInitializationException() { + super(); + } + + public HTTPContentInitializationException(Throwable cause) { + super(cause); + } + + public String getErrorMessage() { + return errMessage; + } + + public void setErrorMessage(String errMessage) { + this.errMessage = errMessage; + } +} \ No newline at end of file diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/internal/InputAdapterServiceComponent.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/internal/InputAdapterServiceComponent.java new file mode 100644 index 000000000..6d452804b --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/internal/InputAdapterServiceComponent.java @@ -0,0 +1,70 @@ +/* +* 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.input.adapter.http.internal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.http.HttpService; +import org.wso2.carbon.device.mgt.iot.input.adapter.http.HTTPEventAdapterFactory; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterFactory; +import org.wso2.carbon.user.core.service.RealmService; + +/** + * @scr.component name="input.iot.http.AdapterService.component" immediate="true" + * @scr.reference name="user.realmservice.default" + * interface="org.wso2.carbon.user.core.service.RealmService" cardinality="1..1" + * policy="dynamic" bind="setRealmService" unbind="unsetRealmService" + * @scr.reference name="http.service" interface="org.osgi.service.http.HttpService" + * cardinality="1..1" policy="dynamic" bind="setHttpService" unbind="unsetHttpService" + */ +public class InputAdapterServiceComponent { + + private static final Log log = LogFactory.getLog( + org.wso2.carbon.device.mgt.iot.input.adapter.http.internal.InputAdapterServiceComponent.class); + + protected void activate(ComponentContext context) { + try { + InputEventAdapterFactory httpEventEventAdapterFactory = new HTTPEventAdapterFactory(); + context.getBundleContext().registerService(InputEventAdapterFactory.class.getName(), + httpEventEventAdapterFactory, null); + if (log.isDebugEnabled()) { + log.debug("Successfully deployed the input adapter service"); + } + } catch (RuntimeException e) { + log.error("Can not create the input adapter service ", e); + } + } + + protected void setRealmService(RealmService realmService) { + InputAdapterServiceDataHolder.registerRealmService(realmService); + } + + protected void unsetRealmService(RealmService realmService) { + InputAdapterServiceDataHolder.registerRealmService(null); + } + + protected void setHttpService(HttpService httpService) { + InputAdapterServiceDataHolder.registerHTTPService(httpService); + } + + protected void unsetHttpService(HttpService httpService) { + InputAdapterServiceDataHolder.registerHTTPService(null); + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/internal/InputAdapterServiceDataHolder.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/internal/InputAdapterServiceDataHolder.java new file mode 100644 index 000000000..95d28c9ef --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/internal/InputAdapterServiceDataHolder.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ +package org.wso2.carbon.device.mgt.iot.input.adapter.http.internal; + +import org.osgi.service.http.HttpService; +import org.wso2.carbon.user.core.service.RealmService; + +/** + * common place to hold some OSGI service references. + */ +public final class InputAdapterServiceDataHolder { + + private static RealmService realmService; + private static HttpService httpService; + + private InputAdapterServiceDataHolder() { + } + + public static void registerRealmService( + RealmService realmService) { + InputAdapterServiceDataHolder.realmService = realmService; + } + + public static RealmService getRealmService() { + return realmService; + } + + public static void registerHTTPService( + HttpService httpService) { + InputAdapterServiceDataHolder.httpService = httpService; + } + + public static HttpService getHTTPService() { + return httpService; + } + + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/jwt/JWTAuthenticator.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/jwt/JWTAuthenticator.java new file mode 100644 index 000000000..4d1be0250 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/jwt/JWTAuthenticator.java @@ -0,0 +1,120 @@ +/* + * 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.input.adapter.http.jwt; + +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.JWSVerifier; +import com.nimbusds.jose.crypto.RSASSAVerifier; +import com.nimbusds.jwt.SignedJWT; +import org.apache.axiom.util.base64.Base64Utils; +import org.apache.axis2.transport.http.HTTPConstants; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.core.util.KeyStoreManager; +import org.wso2.carbon.device.mgt.iot.input.adapter.http.internal.InputAdapterServiceDataHolder; +import org.wso2.carbon.device.mgt.iot.input.adapter.http.util.AuthenticationInfo; +import org.wso2.carbon.user.api.TenantManager; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; +import org.wso2.carbon.utils.multitenancy.MultitenantConstants; +import org.wso2.carbon.utils.multitenancy.MultitenantUtils; +import javax.servlet.http.HttpServletRequest; +import java.security.interfaces.RSAPublicKey; +import java.text.ParseException; + +/** + * This authenticator authenticates HTTP requests using JWT header. + */ +public class JWTAuthenticator { + + private static final Log log = LogFactory.getLog(JWTAuthenticator.class); + public static final String SIGNED_JWT_AUTH_USERNAME = "Username"; + private static final String JWT_ASSERTION_HEADER = "X-JWT-Assertion"; + + public boolean isJWTHeaderExist(HttpServletRequest request) { + String authorizationHeader = request.getHeader(JWT_ASSERTION_HEADER); + if((authorizationHeader != null) && !authorizationHeader.isEmpty()){ + return true; + } + return false; + } + + public AuthenticationInfo authenticate(HttpServletRequest request) { + AuthenticationInfo authenticationInfo = new AuthenticationInfo(); + //Get the filesystem keystore default primary certificate + KeyStoreManager keyStoreManager = KeyStoreManager.getInstance(MultitenantConstants.SUPER_TENANT_ID); + try { + keyStoreManager.getDefaultPrimaryCertificate(); + String authorizationHeader = request.getHeader(HTTPConstants.HEADER_AUTHORIZATION); + String headerData = decodeAuthorizationHeader(authorizationHeader); + JWSVerifier verifier = + new RSASSAVerifier((RSAPublicKey) keyStoreManager.getDefaultPublicKey()); + SignedJWT jwsObject = SignedJWT.parse(headerData); + if (jwsObject.verify(verifier)) { + String username = jwsObject.getJWTClaimsSet().getStringClaim(SIGNED_JWT_AUTH_USERNAME); + String tenantDomain = MultitenantUtils.getTenantDomain(username); + username = MultitenantUtils.getTenantAwareUsername(username); + TenantManager tenantManager = InputAdapterServiceDataHolder.getRealmService(). + getTenantManager(); + int tenantId = tenantManager.getTenantId(tenantDomain); + if (tenantId == -1) { + log.error("tenantDomain is not valid. username : " + username + ", tenantDomain " + + ": " + tenantDomain); + } else { + UserStoreManager userStore = InputAdapterServiceDataHolder.getRealmService(). + getTenantUserRealm(tenantId).getUserStoreManager(); + if (userStore.isExistingUser(username)) { + authenticationInfo.setTenantId(tenantId); + authenticationInfo.setUsername(username); + authenticationInfo.setTenantDomain(tenantDomain); + authenticationInfo.setAuthenticated(true); + } + } + } + } catch (UserStoreException e) { + log.error("Error occurred while obtaining the user.", e); + } catch (ParseException e) { + log.error("Error occurred while parsing the JWT header.", e); + } catch (JOSEException e) { + log.error("Error occurred while verifying the JWT header.", e); + } catch (Exception e) { + log.error("Error occurred while verifying the JWT header.", e); + } + return authenticationInfo; + } + + private String decodeAuthorizationHeader(String authorizationHeader) { + + if(authorizationHeader == null) { + return null; + } + + String[] splitValues = authorizationHeader.trim().split(" "); + byte[] decodedBytes = Base64Utils.decode(splitValues[1].trim()); + if (decodedBytes != null) { + return new String(decodedBytes); + } else { + if (log.isDebugEnabled()) { + log.debug("Error decoding authorization header."); + } + return null; + } + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/oauth/OAuthAuthenticator.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/oauth/OAuthAuthenticator.java new file mode 100644 index 000000000..76c4c8481 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/oauth/OAuthAuthenticator.java @@ -0,0 +1,174 @@ +/* + * 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.input.adapter.http.oauth; + +import org.apache.axis2.context.ServiceContext; +import org.apache.axis2.transport.http.HTTPConstants; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.commons.pool.impl.GenericObjectPool; +import org.wso2.carbon.device.mgt.iot.input.adapter.http.internal.InputAdapterServiceDataHolder; +import org.wso2.carbon.device.mgt.iot.input.adapter.http.util.AuthenticationInfo; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration; +import org.wso2.carbon.identity.oauth2.stub.OAuth2TokenValidationServiceStub; +import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationRequestDTO; +import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationRequestDTO_OAuth2AccessToken; +import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationResponseDTO; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.core.service.RealmService; +import org.wso2.carbon.utils.multitenancy.MultitenantUtils; + +import javax.servlet.http.HttpServletRequest; +import java.rmi.RemoteException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Authenticate use oauth validator + */ +public class OAuthAuthenticator { + private static String cookie; + private GenericObjectPool stubs; + + private static final Pattern PATTERN = Pattern.compile("[B|b]earer\\s"); + private static final String TOKEN_TYPE = "bearer"; + private static final String AUTHORIZATION_HEADER = "Authorization"; + private static Log log = LogFactory.getLog(OAuthAuthenticator.class); + + public OAuthAuthenticator(InputEventAdapterConfiguration eventAdapterConfiguration) { + this.stubs = new GenericObjectPool(new OAuthTokenValidaterStubFactory(eventAdapterConfiguration)); + } + + public AuthenticationInfo authenticate(HttpServletRequest req) { + AuthenticationInfo authenticationInfo = new AuthenticationInfo(); + String bearerToken = getBearerToken(req); + if (bearerToken == null) { + return authenticationInfo; + } + try { + authenticationInfo = validateToken(bearerToken); + } catch (Exception e) { + if (log.isDebugEnabled()) { + log.debug("checkAuthentication() fail: " + e.getMessage(), e); + } + } + return authenticationInfo; + } + + private String getBearerToken(HttpServletRequest request) { + String authorizationHeader = request.getHeader(AUTHORIZATION_HEADER); + if (authorizationHeader != null) { + Matcher matcher = PATTERN.matcher(authorizationHeader); + if (matcher.find()) { + authorizationHeader = authorizationHeader.substring(matcher.end()); + } + } + return authorizationHeader; + } + + /** + * This creates an AuthenticationInfo object that is used for authorization. This method will validate the token + * and + * sets the required parameters to the object. + * + * @param token that needs to be validated. + * @param tokenValidationServiceStub stub that is used to call the external service. + * @return AuthenticationInfo This contains the information related to authenticated client. + * @throws RemoteException that triggers when failing to call the external service.. + */ + private AuthenticationInfo getAuthenticationInfo(String token, + OAuth2TokenValidationServiceStub tokenValidationServiceStub) + throws RemoteException, UserStoreException { + AuthenticationInfo authenticationInfo = new AuthenticationInfo(); + OAuth2TokenValidationRequestDTO validationRequest = new OAuth2TokenValidationRequestDTO(); + OAuth2TokenValidationRequestDTO_OAuth2AccessToken accessToken = + new OAuth2TokenValidationRequestDTO_OAuth2AccessToken(); + accessToken.setTokenType(TOKEN_TYPE); + accessToken.setIdentifier(token); + validationRequest.setAccessToken(accessToken); + boolean authenticated; + OAuth2TokenValidationResponseDTO tokenValidationResponse; + tokenValidationResponse = tokenValidationServiceStub.validate(validationRequest); + if (tokenValidationResponse == null) { + authenticationInfo.setAuthenticated(false); + return authenticationInfo; + } + authenticated = tokenValidationResponse.getValid(); + if (authenticated) { + String authorizedUser = tokenValidationResponse.getAuthorizedUser(); + String username = MultitenantUtils.getTenantAwareUsername(authorizedUser); + String tenantDomain = MultitenantUtils.getTenantDomain(authorizedUser); + authenticationInfo.setUsername(username); + authenticationInfo.setTenantDomain(tenantDomain); + RealmService realmService = InputAdapterServiceDataHolder.getRealmService(); + int tenantId = realmService.getTenantManager().getTenantId(authenticationInfo.getTenantDomain()); + authenticationInfo.setTenantId(tenantId); + } else { + if (log.isDebugEnabled()) { + log.debug("Token validation failed for token: " + token); + } + } + ServiceContext serviceContext = tokenValidationServiceStub._getServiceClient() + .getLastOperationContext().getServiceContext(); + cookie = (String) serviceContext.getProperty(HTTPConstants.COOKIE_STRING); + authenticationInfo.setAuthenticated(authenticated); + return authenticationInfo; + } + + /** + * This method gets a string accessToken and validates it + * + * @param token which need to be validated. + * @return AuthenticationInfo with the validated results. + */ + private AuthenticationInfo validateToken(String token) { + OAuth2TokenValidationServiceStub tokenValidationServiceStub = null; + try { + Object stub = this.stubs.borrowObject(); + if (stub != null) { + tokenValidationServiceStub = (OAuth2TokenValidationServiceStub) stub; + if (cookie != null) { + tokenValidationServiceStub._getServiceClient().getOptions().setProperty( + HTTPConstants.COOKIE_STRING, cookie); + } + return getAuthenticationInfo(token, tokenValidationServiceStub); + } else { + log.warn("Stub initialization failed."); + } + } catch (RemoteException e) { + log.error("Error on connecting with the validation endpoint.", e); + } catch (Exception e) { + log.error("Error occurred in borrowing an validation stub from the pool.", e); + + } finally { + try { + if (tokenValidationServiceStub != null) { + this.stubs.returnObject(tokenValidationServiceStub); + } + } catch (Exception e) { + log.warn("Error occurred while returning the object back to the oauth token validation service " + + "stub pool.", e); + } + } + AuthenticationInfo authenticationInfo = new AuthenticationInfo(); + authenticationInfo.setAuthenticated(false); + authenticationInfo.setTenantId(-1); + return authenticationInfo; + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/oauth/OAuthTokenValidaterStubFactory.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/oauth/OAuthTokenValidaterStubFactory.java new file mode 100644 index 000000000..101f04620 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/oauth/OAuthTokenValidaterStubFactory.java @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.mgt.iot.input.adapter.http.oauth; + +import org.apache.axis2.AxisFault; +import org.apache.axis2.Constants; +import org.apache.axis2.client.Options; +import org.apache.axis2.client.ServiceClient; +import org.apache.axis2.transport.http.HTTPConstants; +import org.apache.axis2.transport.http.HttpTransportProperties; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpConnectionManager; +import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; +import org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory; +import org.apache.commons.httpclient.params.HttpConnectionManagerParams; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; +import org.apache.commons.pool.BasePoolableObjectFactory; +import org.apache.log4j.Logger; +import org.wso2.carbon.core.util.Utils; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration; +import org.wso2.carbon.device.mgt.iot.input.adapter.http.oauth.exception.OAuthTokenValidationException; +import org.wso2.carbon.device.mgt.iot.input.adapter.http.util.HTTPEventAdapterConstants; +import org.wso2.carbon.identity.oauth2.stub.OAuth2TokenValidationServiceStub; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.GeneralSecurityException; + +/** + * This follows object pool pattern to manage the stub for oauth validation service. + */ +public class OAuthTokenValidaterStubFactory extends BasePoolableObjectFactory { + private static final Logger log = Logger.getLogger(OAuthTokenValidaterStubFactory.class); + private HttpClient httpClient; + InputEventAdapterConfiguration eventAdapterConfiguration; + + + public OAuthTokenValidaterStubFactory(InputEventAdapterConfiguration eventAdapterConfiguration) { + this.eventAdapterConfiguration = eventAdapterConfiguration; + this.httpClient = createHttpClient(); + } + + /** + * This creates a OAuth2TokenValidationServiceStub object to the pool. + * + * @return an OAuthValidationStub object + * @throws Exception thrown when creating the object. + */ + @Override + public Object makeObject() throws Exception { + return this.generateStub(); + } + + /** + * This is used to clean up the OAuth validation stub and releases to the object pool. + * + * @param o object that needs to be released. + * @throws Exception throws when failed to release to the pool + */ + @Override + public void passivateObject(Object o) throws Exception { + if (o instanceof OAuth2TokenValidationServiceStub) { + OAuth2TokenValidationServiceStub stub = (OAuth2TokenValidationServiceStub) o; + stub._getServiceClient().cleanupTransport(); + } + } + + /** + * This is used to create a stub which will be triggered through object pool factory, which will create an + * instance of it. + * + * @return OAuth2TokenValidationServiceStub stub that is used to call an external service. + * @throws OAuthTokenValidationException will be thrown when initialization failed. + */ + private OAuth2TokenValidationServiceStub generateStub() throws OAuthTokenValidationException { + OAuth2TokenValidationServiceStub stub; + try { + URL hostURL = new URL(Utils.replaceSystemProperty(eventAdapterConfiguration.getProperties().get( + HTTPEventAdapterConstants.TOKEN_VALIDATION_ENDPOINT_URL))); + if (hostURL != null) { + stub = new OAuth2TokenValidationServiceStub(hostURL.toString()); + if (stub != null) { + ServiceClient client = stub._getServiceClient(); + client.getServiceContext().getConfigurationContext().setProperty( + HTTPConstants.CACHED_HTTP_CLIENT, httpClient); + + HttpTransportProperties.Authenticator auth = + new HttpTransportProperties.Authenticator(); + auth.setPreemptiveAuthentication(true); + String username = eventAdapterConfiguration.getProperties().get(HTTPEventAdapterConstants + .USERNAME); + String password = eventAdapterConfiguration.getProperties().get(HTTPEventAdapterConstants + .PASSWORD); + auth.setPassword(username); + auth.setUsername(password); + Options options = client.getOptions(); + options.setProperty(HTTPConstants.AUTHENTICATE, auth); + options.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, Constants.VALUE_TRUE); + client.setOptions(options); + if (hostURL.getProtocol().equals("https")) { + // set up ssl factory since axis2 https transport is used. + EasySSLProtocolSocketFactory sslProtocolSocketFactory = + createProtocolSocketFactory(); + Protocol authhttps = new Protocol(hostURL.getProtocol(), + (ProtocolSocketFactory) sslProtocolSocketFactory, + hostURL.getPort()); + Protocol.registerProtocol(hostURL.getProtocol(), authhttps); + options.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER, authhttps); + } + } else { + String errorMsg = "OAuth Validation instanization failed."; + throw new OAuthTokenValidationException(errorMsg); + } + } else { + String errorMsg = "host url is invalid"; + throw new OAuthTokenValidationException(errorMsg); + } + } catch (AxisFault axisFault) { + throw new OAuthTokenValidationException( + "Error occurred while creating the OAuth2TokenValidationServiceStub.", axisFault); + } catch (MalformedURLException e) { + throw new OAuthTokenValidationException( + "Error occurred while parsing token endpoint URL", e); + } + + return stub; + } + + /** + * This is required to create a trusted connection with the external entity. + * Have to manually configure it since we use CommonHTTPTransport(axis2 transport) in axis2. + * + * @return an EasySSLProtocolSocketFactory for SSL communication. + */ + private EasySSLProtocolSocketFactory createProtocolSocketFactory() throws OAuthTokenValidationException { + try { + EasySSLProtocolSocketFactory easySSLPSFactory = new EasySSLProtocolSocketFactory(); + return easySSLPSFactory; + } catch (IOException e) { + String errorMsg = "Failed to initiate EasySSLProtocolSocketFactory."; + throw new OAuthTokenValidationException(errorMsg, e); + } catch (GeneralSecurityException e) { + String errorMsg = "Failed to set the key material in easy ssl factory."; + throw new OAuthTokenValidationException(errorMsg, e); + } + } + + /** + * This created httpclient pool that can be used to connect to external entity. This connection can be configured + * via broker.xml by setting up the required http connection parameters. + * + * @return an instance of HttpClient that is configured with MultiThreadedHttpConnectionManager + */ + private HttpClient createHttpClient() { + HttpConnectionManagerParams params = new HttpConnectionManagerParams(); + params.setDefaultMaxConnectionsPerHost(Integer.parseInt(eventAdapterConfiguration.getProperties().get( + HTTPEventAdapterConstants.MAXIMUM_HTTP_CONNECTION_PER_HOST))); + params.setMaxTotalConnections(Integer.parseInt(eventAdapterConfiguration.getProperties().get( + HTTPEventAdapterConstants.MAXIMUM_TOTAL_HTTP_CONNECTION))); + HttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); + connectionManager.setParams(params); + return new HttpClient(connectionManager); + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/oauth/exception/OAuthTokenValidationException.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/oauth/exception/OAuthTokenValidationException.java new file mode 100644 index 000000000..95cfb7cca --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/oauth/exception/OAuthTokenValidationException.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.mgt.iot.input.adapter.http.oauth.exception; + +/** + * This Exception will be thrown, when there any interference with token validation flow. + */ +public class OAuthTokenValidationException extends Exception { + private String errMessage; + + public OAuthTokenValidationException(String msg, Exception nestedEx) { + super(msg, nestedEx); + setErrorMessage(msg); + } + + public OAuthTokenValidationException(String message, Throwable cause) { + super(message, cause); + setErrorMessage(message); + } + + public OAuthTokenValidationException(String msg) { + super(msg); + setErrorMessage(msg); + } + + public OAuthTokenValidationException() { + super(); + } + + public OAuthTokenValidationException(Throwable cause) { + super(cause); + } + + public String getErrorMessage() { + return errMessage; + } + + public void setErrorMessage(String errMessage) { + this.errMessage = errMessage; + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/util/AuthenticationInfo.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/util/AuthenticationInfo.java new file mode 100644 index 000000000..8bcf62e23 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/util/AuthenticationInfo.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + * + */ + +package org.wso2.carbon.device.mgt.iot.input.adapter.http.util; + +/** + * This will be return after authentication and this will consist of the authenticated user info. + */ +public class AuthenticationInfo { + + /** + * this variable is used to check whether the client is authenticated. + */ + private boolean authenticated; + private String username; + private String tenantDomain; + private int tenantId; + /** + * returns whether the client is authenticated + */ + public boolean isAuthenticated() { + return authenticated; + } + + public void setAuthenticated(boolean authenticated) { + this.authenticated = authenticated; + } + + /** + * returns the authenticated client username + */ + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + /** + * return the authenticated client tenant domain + */ + public String getTenantDomain() { + return tenantDomain; + } + + public void setTenantDomain(String tenantDomain) { + this.tenantDomain = tenantDomain; + } + + public int getTenantId() { + return tenantId; + } + + public void setTenantId(int tenantId) { + this.tenantId = tenantId; + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/util/HTTPContentValidator.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/util/HTTPContentValidator.java new file mode 100644 index 000000000..4c260c29d --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/util/HTTPContentValidator.java @@ -0,0 +1,77 @@ +/* +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +package org.wso2.carbon.device.mgt.iot.input.adapter.http.util; + +import com.jayway.jsonpath.JsonPath; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.simple.JSONArray; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentInfo; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentValidator; + +import java.util.Map; + +public class HTTPContentValidator implements ContentValidator { + private static final Log log = LogFactory.getLog(HTTPContentValidator.class); + private static String JSON_ARRAY_START_CHAR = "["; + + @Override + public ContentInfo validate(Object msgPayload, Map contentValidationParams, + Map dynamicParams) { + String deviceId = dynamicParams.get("deviceId"); + String msg = (String) msgPayload; + String deviceIdJsonPath = contentValidationParams.get(HTTPEventAdapterConstants.DEVICE_ID_JSON_PATH); + boolean status; + if (msg.startsWith(JSON_ARRAY_START_CHAR)) { + status = processMultipleEvents(msg, deviceId, deviceIdJsonPath); + } else { + status = processSingleEvent(msg, deviceId, deviceIdJsonPath); + } + return new ContentInfo(status, msg); + } + + private boolean processSingleEvent(String msg, String deviceIdFromTopic, String deviceIdJsonPath) { + Object res = JsonPath.read(msg, deviceIdJsonPath); + String deviceIdFromContent = (res != null) ? res.toString() : ""; + if (deviceIdFromContent.equals(deviceIdFromTopic)) { + return true; + } + return false; + } + + private boolean processMultipleEvents(String msg, String deviceIdFromTopic, String deviceIdJsonPath) { + try { + JSONParser jsonParser = new JSONParser(); + JSONArray jsonArray = (JSONArray) jsonParser.parse(msg); + boolean status = false; + for (int i = 0; i < jsonArray.size(); i++) { + status = processSingleEvent(jsonArray.get(i).toString(), deviceIdFromTopic, deviceIdJsonPath); + if (!status) { + return status; + } + } + return status; + } catch (ParseException e) { + log.error("Invalid input " + msg, e); + return false; + } + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/util/HTTPEventAdapterConstants.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/util/HTTPEventAdapterConstants.java new file mode 100644 index 000000000..5eb7ed488 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/util/HTTPEventAdapterConstants.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ +package org.wso2.carbon.device.mgt.iot.input.adapter.http.util; + +/** + * This holds the constants related to HTTP event adapter. + */ +public final class HTTPEventAdapterConstants { + + private HTTPEventAdapterConstants() { + } + + public static final String ADAPTER_TYPE_HTTP = "oauth-http"; + public static final String ADAPTER_USAGE_TIPS_PREFIX = "http.usage.tips_prefix"; + public static final String ADAPTER_USAGE_TIPS_MID1 = "http.usage.tips_mid1"; + public static final String ADAPTER_USAGE_TIPS_MID2 = "http.usage.tips_mid2"; + public static final String ADAPTER_USAGE_TIPS_MID3 = "http.usage.tips_mid3"; + public static final String ADAPTER_USAGE_TIPS_POSTFIX = "http.usage.tips_postfix"; + public static final int ADAPTER_MIN_THREAD_POOL_SIZE = 8; + public static final int ADAPTER_MAX_THREAD_POOL_SIZE = 100; + public static final int ADAPTER_EXECUTOR_JOB_QUEUE_SIZE = 10000; + public static final long DEFAULT_KEEP_ALIVE_TIME_IN_MILLS = 20000; + public static final String ENDPOINT_PREFIX = "/endpoints/"; + public static final String ENDPOINT_URL_SEPARATOR = "/"; + public static final String ENDPOINT_TENANT_KEY = "t"; + public static final String ADAPTER_MIN_THREAD_POOL_SIZE_NAME = "minThread"; + public static final String ADAPTER_MAX_THREAD_POOL_SIZE_NAME = "maxThread"; + public static final String ADAPTER_KEEP_ALIVE_TIME_NAME = "keepAliveTimeInMillis"; + public static final String ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME = "jobQueueSize"; + public static final String EXPOSED_TRANSPORTS = "transports"; + public static final String HTTPS = "https"; + public static final String HTTP = "http"; + public static final String LOCAL = "local"; + public static final String ALL = "all"; + public static final String CARBON_CONFIG_PORT_OFFSET_NODE = "Ports.Offset"; + public static final int DEFAULT_HTTP_PORT = 9763; + public static final int DEFAULT_HTTPS_PORT = 9443; + public static final String MAXIMUM_TOTAL_HTTP_CONNECTION = "maximumTotalHttpConnection"; + public static final String MAXIMUM_TOTAL_HTTP_CONNECTION_HINT = "maximumTotalHttpConnection.hint"; + public static final String MAXIMUM_HTTP_CONNECTION_PER_HOST = "maximumHttpConnectionPerHost"; + public static final String MAXIMUM_HTTP_CONNECTION_PER_HOST_HINT = "maximumHttpConnectionPerHost.hint"; + public static final String TOKEN_VALIDATION_ENDPOINT_URL = "tokenValidationEndpointUrl"; + public static final String TOKEN_VALIDATION_ENDPOINT_URL_HINT = "tokenValidationEndpointUrl.hint"; + public static final String USERNAME = "username"; + public static final String USERNAME_HINT = "username.hint"; + public static final String PASSWORD = "password"; + public static final String PASSWORD_HINT = "password.hint"; + public static final String DEFAULT_STRING = "default"; + public static final String MAX_HTTP_CONNECTION = "2"; + public static final String MAX_TOTAL_HTTP_CONNECTION = "100"; + public static final String TENANT_DOMAIN_TAG = "tenantDomain"; + public static final String USERNAME_TAG = "username"; + public static final String PAYLOAD_TAG = "payload"; + public static final String DEVICE_ID_JSON_PATH = "device_id_json_path"; + public static final String ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME = "contentValidation"; + public static final String ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT = "contentValidation.hint"; + public static final String ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS = "contentValidationParams"; + public static final String ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS_HINT = "contentValidationParams.hint"; + public static final String DEFAULT = "default"; + public static final String HTTP_CONTENT_VALIDATION_DEFAULT_PARAMETERS = ""; + public static final String ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME = "contentTransformer"; + public static final String ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT = "contentTransformer.hint"; +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/resources/org/wso2/carbon/device/mgt/iot/input/adapter/http/i18n/Resources.properties b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/resources/org/wso2/carbon/device/mgt/iot/input/adapter/http/i18n/Resources.properties new file mode 100644 index 000000000..f84f46ab1 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.http/src/main/resources/org/wso2/carbon/device/mgt/iot/input/adapter/http/i18n/Resources.properties @@ -0,0 +1,40 @@ +# +# Copyright (c) 2005-2014, 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. +# + +transports=Transport(s) +http.usage.tips_prefix=Following url formats are used to receive events
For super tenants:
  http://localhost: +http.usage.tips_mid1=/endpoints/<event_receiver_name>
  https://localhost: +http.usage.tips_mid2=/endpoints/<event_receiver_name>

For other tenants:
  http://localhost: +http.usage.tips_mid3=/endpoints/t/<tenant_domain>/<event_receiver_name>
  https://localhost: +http.usage.tips_postfix=/endpoints/t/<tenant_domain>/<event_receiver_name> +tokenValidationEndpointUrl=tokenEndpointUrl +tokenValidationEndpointUrl.hint=OAUTH Token Validation Endpoint +username=username +username.hint=username of the user to connect to the admin services +password=password +password.hint=password of the user to connect to the admin services. +maximumTotalHttpConnection=maximumTotalHttpConnection +maximumTotalHttpConnection.hint=Maximum Total connection to be made with the endpoint +maximumHttpConnectionPerHost=maximumHttpConnectionPerHost +maximumHttpConnectionPerHost.hint=Maximum Http connection per host. +contentValidation=contentValidation +contentValidation.hint=Class Name of the content Validation or 'default' to set default class, required to implement (if required) +contentValidationParams=contentValidationParams +contentValidationParams.hint=ContentValidationParams, comma seperated. (if required) +contentTransformer=contentTransformer +contentTransformer.hint=Class Name of the content transformer or 'default' to set default class, required to implement (if required) \ No newline at end of file diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/pom.xml b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/pom.xml new file mode 100644 index 000000000..44dd1dc5f --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/pom.xml @@ -0,0 +1,141 @@ + + + + + iot-base-plugin + org.wso2.carbon.devicemgt-plugins + 2.1.0-SNAPSHOT + ../pom.xml + + 4.0.0 + + org.wso2.carbon.device.mgt.iot.input.adapter.mqtt + bundle + WSO2 Carbon - Device Mgt Input Adaptor Module - MQTT + Provides the back-end functionality of Input adaptor + http://wso2.org + + + + org.wso2.carbon.analytics-common + org.wso2.carbon.event.input.adapter.core + + + org.wso2.carbon + org.wso2.carbon.logging + + + org.wso2.carbon + org.wso2.carbon.core + + + org.eclipse.paho + org.eclipse.paho.client.mqttv3 + + + org.apache.httpcomponents.wso2 + httpcore + + + org.wso2.orbit.org.apache.httpcomponents + httpclient + + + com.googlecode.json-simple.wso2 + json-simple + + + org.wso2.carbon.devicemgt + org.wso2.carbon.identity.jwt.client.extension + + + com.jayway.jsonpath + json-path + + + org.wso2.carbon.identity + org.wso2.carbon.identity.oauth.stub + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.input.adapter.extension + + + + + + + org.apache.felix + maven-scr-plugin + + + generate-scr-descriptor + + scr + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.artifactId} + ${project.artifactId} + + org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.internal, + org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.internal.* + + + !org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.internal, + !org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.internal.*, + org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.* + + + org.wso2.carbon.event.input.adapter.core, + org.wso2.carbon.event.input.adapter.core.*, + javax.xml.namespace; version=0.0.0, + org.eclipse.paho.client.mqttv3.*, + org.apache.http;version="${httpclient.version.range}", + org.apache.http.message;version="${httpclient.version.range}", + org.apache.http.client;version="${httpclient.version.range}", + org.apache.http.impl;version="${httpclient.version.range}", + org.apache.http.conn.*;version="${httpclient.version.range}", + org.apache.http.util;version="${httpclient.version.range}", + org.apache.http.client.entity;version="${httpclient.version.range}", + org.apache.http.client.methods;version="${httpclient.version.range}", + org.apache.http.impl.client;version="${httpclient.version.range}", + org.json.simple.*, + org.wso2.carbon.identity.jwt.client.extension.*, + com.jayway.jsonpath.* + + * + + + + + + + \ No newline at end of file diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/MQTTEventAdapter.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/MQTTEventAdapter.java new file mode 100644 index 000000000..536ea06ed --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/MQTTEventAdapter.java @@ -0,0 +1,166 @@ +/* +* 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.input.adapter.mqtt; + +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.util.MQTTBrokerConnectionConfiguration; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapter; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener; +import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterException; +import org.wso2.carbon.event.input.adapter.core.exception.TestConnectionNotSupportedException; +import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.util.MQTTAdapterListener; +import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.util.MQTTEventAdapterConstants; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * Input XMPPEventAdapter will be used to receive events with MQTT protocol using specified broker and topic. + */ +public class MQTTEventAdapter implements InputEventAdapter { + + private final InputEventAdapterConfiguration eventAdapterConfiguration; + private final Map globalProperties; + private InputEventAdapterListener eventAdapterListener; + private final String id = UUID.randomUUID().toString(); + private MQTTAdapterListener mqttAdapterListener; + private MQTTBrokerConnectionConfiguration mqttBrokerConnectionConfiguration; + + + public MQTTEventAdapter(InputEventAdapterConfiguration eventAdapterConfiguration, + Map globalProperties) { + this.eventAdapterConfiguration = eventAdapterConfiguration; + this.globalProperties = globalProperties; + } + + @Override + public void init(InputEventAdapterListener eventAdapterListener) throws InputEventAdapterException { + this.eventAdapterListener = eventAdapterListener; + try { + int keepAlive; + + //If global properties are available those will be assigned else constant values will be assigned + if (globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_KEEP_ALIVE) != null) { + keepAlive = Integer.parseInt((globalProperties.get(MQTTEventAdapterConstants.ADAPTER_CONF_KEEP_ALIVE))); + } else { + keepAlive = MQTTEventAdapterConstants.ADAPTER_CONF_DEFAULT_KEEP_ALIVE; + } + String contentValidationParams = eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS); + Map paramsMap = new HashMap<>(); + if (contentValidationParams != null && !contentValidationParams.isEmpty()) { + String params[] = contentValidationParams.split(","); + for (String param : params) { + String paramsKeyAndValue[] = splitOnFirst(param, ':'); + if (paramsKeyAndValue.length != 2) { + throw new InputEventAdapterException("Invalid parameters for content validation - " + param); + } + paramsMap.put(paramsKeyAndValue[0], paramsKeyAndValue[1]); + } + } + mqttBrokerConnectionConfiguration = new MQTTBrokerConnectionConfiguration( + eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_URL), + eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME), + eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES), + eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL), + eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CLEAN_SESSION), + keepAlive, + eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME), + paramsMap, + eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME) + ); + mqttAdapterListener = new MQTTAdapterListener(mqttBrokerConnectionConfiguration, + eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_MESSAGE_TOPIC), + eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CLIENTID), + eventAdapterListener, PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId()); + + } catch (Throwable t) { + throw new InputEventAdapterException(t.getMessage(), t); + } + } + + private String[] splitOnFirst(String str, char c) { + int idx = str.indexOf(c); + String head = str.substring(0, idx); + String tail = str.substring(idx + 1); + return new String[] { head, tail} ; + } + + @Override + public void testConnect() throws TestConnectionNotSupportedException { + throw new TestConnectionNotSupportedException("not-supported"); + } + + @Override + public void connect() { + mqttAdapterListener.createConnection(); + } + + @Override + public void disconnect() { + //when mqtt and this feature both together then this method becomes a blocking method, Therefore + // have used a thread to skip it. + try { + Thread thread = new Thread(new Runnable() { + public void run() { + if (mqttAdapterListener != null) { + mqttAdapterListener.stopListener(eventAdapterConfiguration.getName()); + } + } + }); + thread.start(); + thread.join(2000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + @Override + public void destroy() { + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof MQTTEventAdapter)) return false; + + MQTTEventAdapter that = (MQTTEventAdapter) o; + + if (!id.equals(that.id)) return false; + + return true; + } + + @Override + public int hashCode() { + return id.hashCode(); + } + + + @Override + public boolean isEventDuplicatedInCluster() { + return true; + } + + @Override + public boolean isPolling() { + return true; + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/MQTTEventAdapterFactory.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/MQTTEventAdapterFactory.java new file mode 100644 index 000000000..f5150cfb5 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/MQTTEventAdapterFactory.java @@ -0,0 +1,148 @@ +/* +* 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.input.adapter.mqtt; + +import org.wso2.carbon.event.input.adapter.core.*; +import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.util.MQTTEventAdapterConstants; + +import java.util.*; + +/** + * The mqtt event adapter factory class to create a mqtt input adapter + */ +public class MQTTEventAdapterFactory extends InputEventAdapterFactory { + + private ResourceBundle resourceBundle = ResourceBundle.getBundle + ("org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.i18n.Resources", Locale.getDefault()); + + @Override + public String getType() { + return MQTTEventAdapterConstants.ADAPTER_TYPE_MQTT; + } + + @Override + public List getSupportedMessageFormats() { + List supportInputMessageTypes = new ArrayList(); + supportInputMessageTypes.add(MessageType.JSON); + supportInputMessageTypes.add(MessageType.TEXT); + supportInputMessageTypes.add(MessageType.XML); + supportInputMessageTypes.add(MessageType.WSO2EVENT); + return supportInputMessageTypes; + } + + @Override + public List getPropertyList() { + List propertyList = new ArrayList(); + + // set topic + Property topicProperty = new Property(MQTTEventAdapterConstants.ADAPTER_MESSAGE_TOPIC); + topicProperty.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_MESSAGE_TOPIC)); + topicProperty.setRequired(true); + topicProperty.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_MESSAGE_TOPIC_HINT)); + propertyList.add(topicProperty); + + //Broker Url + Property brokerUrl = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_URL); + brokerUrl.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_URL)); + brokerUrl.setRequired(true); + brokerUrl.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_URL_HINT)); + propertyList.add(brokerUrl); + + //DCR endpoint details + Property dcrUrl = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL); + dcrUrl.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL)); + dcrUrl.setRequired(false); + dcrUrl.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL_HINT)); + propertyList.add(dcrUrl); + + //Content Validator details + Property contentValidator = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME); + contentValidator.setDisplayName( + resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME)); + contentValidator.setRequired(false); + contentValidator.setHint( + resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT)); + contentValidator.setDefaultValue(MQTTEventAdapterConstants.DEFAULT); + propertyList.add(contentValidator); + + //Content Validator Params details + Property contentValidatorParams = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS); + contentValidatorParams.setDisplayName( + resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS)); + contentValidatorParams.setRequired(false); + contentValidatorParams.setHint( + resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS_HINT)); + contentValidatorParams.setDefaultValue(MQTTEventAdapterConstants.MQTT_CONTENT_VALIDATION_DEFAULT_PARAMETERS); + propertyList.add(contentValidatorParams); + + //Broker Username + Property userName = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME); + userName.setDisplayName( + resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME)); + userName.setRequired(false); + userName.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME_HINT)); + propertyList.add(userName); + + //Broker Required Scopes. + Property scopes = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES); + scopes.setDisplayName( + resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES)); + scopes.setRequired(false); + scopes.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES_HINT)); + propertyList.add(scopes); + + //Broker clear session + Property clearSession = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_CLEAN_SESSION); + clearSession.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CLEAN_SESSION)); + clearSession.setRequired(false); + clearSession.setOptions(new String[]{"true", "false"}); + clearSession.setDefaultValue("true"); + clearSession.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CLEAN_SESSION_HINT)); + propertyList.add(clearSession); + + //Content Transformer details + Property contentTransformer = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME); + contentTransformer.setDisplayName( + resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME)); + contentTransformer.setRequired(false); + contentTransformer.setHint( + resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT)); + contentTransformer.setDefaultValue(MQTTEventAdapterConstants.DEFAULT); + propertyList.add(contentTransformer); + + // set clientId + Property clientId = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_CLIENTID); + clientId.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CLIENTID)); + clientId.setRequired(false); + clientId.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CLIENTID_HINT)); + propertyList.add(clientId); + + return propertyList; + } + + @Override + public String getUsageTips() { + return null; + } + + @Override + public InputEventAdapter createEventAdapter(InputEventAdapterConfiguration eventAdapterConfiguration, + Map globalProperties) { + return new MQTTEventAdapter(eventAdapterConfiguration, globalProperties); + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/exception/MQTTContentInitializationException.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/exception/MQTTContentInitializationException.java new file mode 100644 index 000000000..ddb60f53e --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/exception/MQTTContentInitializationException.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.exception; + +/** + * This exception will thrown when content validator is failed to intialiaze. + */ +public class MQTTContentInitializationException extends RuntimeException { + private String errMessage; + + public MQTTContentInitializationException(String msg, Exception nestedEx) { + super(msg, nestedEx); + setErrorMessage(msg); + } + + public MQTTContentInitializationException(String message, Throwable cause) { + super(message, cause); + setErrorMessage(message); + } + + public MQTTContentInitializationException(String msg) { + super(msg); + setErrorMessage(msg); + } + + public MQTTContentInitializationException() { + super(); + } + + public MQTTContentInitializationException(Throwable cause) { + super(cause); + } + + public String getErrorMessage() { + return errMessage; + } + + public void setErrorMessage(String errMessage) { + this.errMessage = errMessage; + } +} \ No newline at end of file diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/internal/InputAdapterServiceComponent.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/internal/InputAdapterServiceComponent.java new file mode 100644 index 000000000..4da8c37ca --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/internal/InputAdapterServiceComponent.java @@ -0,0 +1,67 @@ +/* +* 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.input.adapter.mqtt.internal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.http.HttpService; +import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.MQTTEventAdapterFactory; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterFactory; +import org.wso2.carbon.user.core.service.RealmService; + +/** + * @scr.component name="input.iot.mqtt.AdapterService.component" immediate="true" + * @scr.reference name="user.realmservice.default" + * interface="org.wso2.carbon.user.core.service.RealmService" cardinality="1..1" + * policy="dynamic" bind="setRealmService" unbind="unsetRealmService" + */ +public class InputAdapterServiceComponent { + + private static final Log log = LogFactory.getLog(InputAdapterServiceComponent.class); + + protected void activate(ComponentContext context) { + try { + InputEventAdapterFactory mqttEventAdapterFactory = new MQTTEventAdapterFactory(); + context.getBundleContext().registerService(InputEventAdapterFactory.class.getName(), + mqttEventAdapterFactory, null); + if (log.isDebugEnabled()) { + log.debug("Successfully deployed the input adapter service"); + } + } catch (RuntimeException e) { + log.error("Can not create the input adapter service ", e); + } + } + + protected void setRealmService(RealmService realmService) { + InputAdapterServiceDataHolder.registerRealmService(realmService); + } + + protected void unsetRealmService(RealmService realmService) { + InputAdapterServiceDataHolder.registerRealmService(null); + } + + protected void setHttpService(HttpService httpService) { + InputAdapterServiceDataHolder.registerHTTPService(httpService); + } + + protected void unsetHttpService(HttpService httpService) { + InputAdapterServiceDataHolder.registerHTTPService(null); + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/internal/InputAdapterServiceDataHolder.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/internal/InputAdapterServiceDataHolder.java new file mode 100644 index 000000000..9938b0861 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/internal/InputAdapterServiceDataHolder.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ +package org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.internal; + +import org.osgi.service.http.HttpService; +import org.wso2.carbon.user.core.service.RealmService; + +/** + * common place to hold some OSGI service references. + */ +public final class InputAdapterServiceDataHolder { + + private static RealmService realmService; + private static HttpService httpService; + + private InputAdapterServiceDataHolder() { + } + + public static void registerRealmService( + RealmService realmService) { + InputAdapterServiceDataHolder.realmService = realmService; + } + + public static RealmService getRealmService() { + return realmService; + } + + public static void registerHTTPService( + HttpService httpService) { + InputAdapterServiceDataHolder.httpService = httpService; + } + + public static HttpService getHTTPService() { + return httpService; + } + + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTAdapterListener.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTAdapterListener.java new file mode 100644 index 000000000..305367141 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTAdapterListener.java @@ -0,0 +1,285 @@ +/* +* 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.input.adapter.mqtt.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.eclipse.paho.client.mqttv3.*; +import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.core.ServerStatus; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentInfo; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentTransformer; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentValidator; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.DefaultContentTransformer; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.DefaultContentValidator; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener; +import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterRuntimeException; +import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.exception.MQTTContentInitializationException; +import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.Map; + +public class MQTTAdapterListener implements MqttCallback, Runnable { + private static final Log log = LogFactory.getLog(MQTTAdapterListener.class); + + private MqttClient mqttClient; + private MqttConnectOptions connectionOptions; + private boolean cleanSession; + + private MQTTBrokerConnectionConfiguration mqttBrokerConnectionConfiguration; + private String topic; + private int tenantId; + private boolean connectionSucceeded = false; + ContentValidator contentValidator; + Map contentValidationParams; + ContentTransformer contentTransformer; + + private InputEventAdapterListener eventAdapterListener = null; + + + public MQTTAdapterListener(MQTTBrokerConnectionConfiguration mqttBrokerConnectionConfiguration, + String topic, String mqttClientId, + InputEventAdapterListener inputEventAdapterListener, int tenantId) { + + if(mqttClientId == null || mqttClientId.trim().isEmpty()){ + mqttClientId = MqttClient.generateClientId(); + } + this.mqttBrokerConnectionConfiguration = mqttBrokerConnectionConfiguration; + this.cleanSession = mqttBrokerConnectionConfiguration.isCleanSession(); + int keepAlive = mqttBrokerConnectionConfiguration.getKeepAlive(); + this.topic = topic; + this.eventAdapterListener = inputEventAdapterListener; + this.tenantId = tenantId; + + //SORTING messages until the server fetches them + String temp_directory = System.getProperty("java.io.tmpdir"); + MqttDefaultFilePersistence dataStore = new MqttDefaultFilePersistence(temp_directory); + + + try { + connectionOptions = new MqttConnectOptions(); + connectionOptions.setCleanSession(cleanSession); + connectionOptions.setKeepAliveInterval(keepAlive); + + // Construct an MQTT blocking mode client + mqttClient = new MqttClient(this.mqttBrokerConnectionConfiguration.getBrokerUrl(), mqttClientId, + dataStore); + + // Set this wrapper as the callback handler + mqttClient.setCallback(this); + String contentValidatorClassName = this.mqttBrokerConnectionConfiguration.getContentValidatorClassName(); + + if (contentValidatorClassName != null && contentValidatorClassName.equals(MQTTEventAdapterConstants.DEFAULT)) { + contentValidator = new DefaultContentValidator(); + } else if (contentValidatorClassName != null && !contentValidatorClassName.isEmpty()) { + try { + Class contentValidatorClass = Class.forName(contentValidatorClassName) + .asSubclass(ContentValidator.class); + contentValidator = contentValidatorClass.newInstance(); + } catch (ClassNotFoundException e) { + throw new MQTTContentInitializationException( + "Unable to find the class validator: " + contentValidatorClassName, e); + } catch (InstantiationException e) { + throw new MQTTContentInitializationException( + "Unable to create an instance of :" + contentValidatorClassName, e); + } catch (IllegalAccessException e) { + throw new MQTTContentInitializationException("Access of the instance in not allowed.", e); + } + } + + contentValidationParams = mqttBrokerConnectionConfiguration.getContentValidatorParams(); + + String contentTransformerClassName = this.mqttBrokerConnectionConfiguration.getContentTransformerClassName(); + if (contentTransformerClassName != null && contentTransformerClassName.equals(MQTTEventAdapterConstants.DEFAULT)) { + contentTransformer = new DefaultContentTransformer(); + } else if (contentTransformerClassName != null && !contentTransformerClassName.isEmpty()) { + try { + Class contentTransformerClass = Class.forName(contentTransformerClassName) + .asSubclass(ContentTransformer.class); + contentTransformer = contentTransformerClass.newInstance(); + } catch (ClassNotFoundException e) { + throw new MQTTContentInitializationException( + "Unable to find the class transfoer: " + contentTransformerClassName, e); + } catch (InstantiationException e) { + throw new MQTTContentInitializationException( + "Unable to create an instance of :" + contentTransformerClassName, e); + } catch (IllegalAccessException e) { + throw new MQTTContentInitializationException("Access of the instance in not allowed.", e); + } + } + } catch (MqttException e) { + log.error("Exception occurred while subscribing to MQTT broker at " + + mqttBrokerConnectionConfiguration.getBrokerUrl()); + throw new InputEventAdapterRuntimeException(e); + } + } + + public void startListener() throws MqttException { + if (this.mqttBrokerConnectionConfiguration.getBrokerUsername() != null && + this.mqttBrokerConnectionConfiguration.getDcrUrl() != null) { + String username = this.mqttBrokerConnectionConfiguration.getBrokerUsername(); + String dcrUrlString = this.mqttBrokerConnectionConfiguration.getDcrUrl(); + String scopes = this.mqttBrokerConnectionConfiguration.getBrokerScopes(); + //getJWT Client Parameters. + if (dcrUrlString != null && !dcrUrlString.isEmpty()) { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(username); + try { + URL dcrUrl = new URL(dcrUrlString); + HttpClient httpClient = MQTTUtil.getHttpClient(dcrUrl.getProtocol()); + HttpPost postMethod = new HttpPost(dcrUrlString); + RegistrationProfile registrationProfile = new RegistrationProfile(); + registrationProfile.setCallbackUrl(MQTTEventAdapterConstants.EMPTY_STRING); + registrationProfile.setGrantType(MQTTEventAdapterConstants.GRANT_TYPE); + registrationProfile.setOwner(username); + registrationProfile.setTokenScope(MQTTEventAdapterConstants.TOKEN_SCOPE); + registrationProfile.setApplicationType(MQTTEventAdapterConstants.APPLICATION_TYPE); + registrationProfile.setClientName(username + "_" + tenantId); + String jsonString = registrationProfile.toJSON(); + StringEntity requestEntity = new StringEntity(jsonString, ContentType.APPLICATION_JSON); + postMethod.setEntity(requestEntity); + HttpResponse httpResponse = httpClient.execute(postMethod); + String response = MQTTUtil.getResponseString(httpResponse); + try { + JSONParser jsonParser = new JSONParser(); + JSONObject jsonPayload = (JSONObject) jsonParser.parse(response); + String clientId = (String) jsonPayload.get(MQTTEventAdapterConstants.CLIENT_ID); + String clientSecret = (String) jsonPayload.get(MQTTEventAdapterConstants.CLIENT_SECRET); + JWTClientManagerService jwtClientManagerService = MQTTUtil.getJWTClientManagerService(); + AccessTokenInfo accessTokenInfo = jwtClientManagerService.getJWTClient().getAccessToken( + clientId, clientSecret, username, scopes); + connectionOptions.setUserName(accessTokenInfo.getAccessToken()); + } catch (ParseException e) { + String msg = "error occurred while parsing client credential payload"; + log.error(msg, e); + } catch (JWTClientException e) { + String msg = "error occurred while parsing the response from JWT Client"; + log.error(msg, e); + } + } catch (MalformedURLException e) { + log.error("Invalid dcrUrl : " + dcrUrlString); + } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | IOException e) { + log.error("Failed to create an https connection.", e); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } + } + mqttClient.connect(connectionOptions); + mqttClient.subscribe(topic); + } + + public void stopListener(String adapterName) { + if (connectionSucceeded) { + try { + if (!ServerStatus.getCurrentStatus().equals(ServerStatus.STATUS_SHUTTING_DOWN) || cleanSession) { + mqttClient.unsubscribe(topic); + } + mqttClient.disconnect(3000); + } catch (MqttException e) { + log.error("Can not unsubscribe from the destination " + topic + + " with the event adapter " + adapterName, e); + } + } + connectionSucceeded = true; + } + + @Override + public void connectionLost(Throwable throwable) { + log.warn("MQTT connection not reachable " + throwable); + connectionSucceeded = false; + new Thread(this).start(); + } + + @Override + public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception { + try { + String msgText = mqttMessage.toString(); + if (log.isDebugEnabled()) { + log.debug(msgText); + } + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId); + + if (log.isDebugEnabled()) { + log.debug("Event received in MQTT Event Adapter - " + msgText); + } + + if (contentValidator != null && contentTransformer != null) { + ContentInfo contentInfo; + Map dynamicProperties = new HashMap<>(); + dynamicProperties.put(MQTTEventAdapterConstants.TOPIC, topic); + msgText = (String) contentTransformer.transform(msgText, dynamicProperties); + contentInfo = contentValidator.validate(msgText,contentValidationParams, dynamicProperties); + if (contentInfo != null && contentInfo.isValidContent()) { + eventAdapterListener.onEvent(contentInfo.getMessage()); + } + } else { + eventAdapterListener.onEvent(msgText); + } + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } + + @Override + public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { + + } + + @Override + public void run() { + while (!connectionSucceeded) { + try { + MQTTEventAdapterConstants.initialReconnectDuration = MQTTEventAdapterConstants.initialReconnectDuration + * MQTTEventAdapterConstants.reconnectionProgressionFactor; + Thread.sleep(MQTTEventAdapterConstants.initialReconnectDuration); + startListener(); + connectionSucceeded = true; + log.info("MQTT Connection successful"); + } catch (InterruptedException e) { + log.error("Interruption occurred while waiting for reconnection", e); + } catch (MqttException e) { + log.error("MQTT Exception occurred when starting listener", e); + } + } + } + + public void createConnection() { + new Thread(this).start(); + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTBrokerConnectionConfiguration.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTBrokerConnectionConfiguration.java new file mode 100644 index 000000000..d0d3f02cd --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTBrokerConnectionConfiguration.java @@ -0,0 +1,94 @@ +/* +* 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.input.adapter.mqtt.util; + +import java.util.Map; + +/** + * This holds the configurations related to MQTT Broker. + */ +public class MQTTBrokerConnectionConfiguration { + + private String brokerUsername = null; + private String brokerScopes = null; + private boolean cleanSession = true; + private int keepAlive; + private String brokerUrl; + private String dcrUrl; + private String contentValidatorClassName; + private Map contentValidatorParams; + private String contentTransformerClassName; + + public String getBrokerScopes() { + return brokerScopes; + } + + public String getBrokerUsername() { + return brokerUsername; + } + + public boolean isCleanSession() { + return cleanSession; + } + + public String getBrokerUrl() { + return brokerUrl; + } + + public String getDcrUrl() { + return dcrUrl; + } + + public int getKeepAlive() { + return keepAlive; + } + + public String getContentValidatorClassName() { + return contentValidatorClassName; + } + + public Map getContentValidatorParams() { + return contentValidatorParams; + } + + public String getContentTransformerClassName() { + return contentTransformerClassName; + } + + public MQTTBrokerConnectionConfiguration(String brokerUrl, String brokerUsername, String brokerScopes, + String dcrUrl, String cleanSession, int keepAlive, + String contentValidatorClassName, Map contentValidatorParams, + String contentTransformerClassName) { + this.brokerUsername = brokerUsername; + this.brokerScopes = brokerScopes; + if (brokerScopes == null) { + this.brokerScopes = MQTTEventAdapterConstants.EMPTY_STRING; + } + this.brokerUrl = PropertyUtils.replaceMqttProperty(brokerUrl); + this.dcrUrl = PropertyUtils.replaceMqttProperty(dcrUrl); + this.contentValidatorClassName = contentValidatorClassName; + if (cleanSession != null) { + this.cleanSession = Boolean.parseBoolean(cleanSession); + } + this.keepAlive = keepAlive; + if (contentValidatorParams != null) { + this.contentValidatorParams = contentValidatorParams; + } + this.contentTransformerClassName = contentTransformerClassName; + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTContentValidator.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTContentValidator.java new file mode 100644 index 000000000..f07a16868 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTContentValidator.java @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +package org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.util; + +import com.jayway.jsonpath.JsonPath; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.simple.JSONArray; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentInfo; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentValidator; + +import java.util.Map; + +public class MQTTContentValidator implements ContentValidator { + private static final String JSON_ARRAY_START_CHAR = "["; + private static final Log log = LogFactory.getLog(MQTTContentValidator.class); + + @Override + public ContentInfo validate(Object msgPayload, Map contentValidationParams, + Map dynamicParams) { + String topic = dynamicParams.get(MQTTEventAdapterConstants.TOPIC); + String topics[] = topic.split("/"); + String deviceIdJsonPath = contentValidationParams.get(MQTTEventAdapterConstants.DEVICE_ID_JSON_PATH); + String deviceIdInTopicHierarchyLevel = contentValidationParams.get( + MQTTEventAdapterConstants.DEVICE_ID_TOPIC_HIERARCHY_INDEX); + int deviceIdInTopicHierarchyLevelIndex = 0; + if (deviceIdInTopicHierarchyLevel != null && !deviceIdInTopicHierarchyLevel.isEmpty()) { + deviceIdInTopicHierarchyLevelIndex = Integer.parseInt(deviceIdInTopicHierarchyLevel); + } + String deviceIdFromTopic = topics[deviceIdInTopicHierarchyLevelIndex]; + boolean status; + String message = (String) msgPayload; + if (message.startsWith(JSON_ARRAY_START_CHAR)) { + status = processMultipleEvents(message, deviceIdFromTopic, deviceIdJsonPath); + } else { + status = processSingleEvent(message, deviceIdFromTopic, deviceIdJsonPath); + } + return new ContentInfo(status, msgPayload); + } + + private boolean processSingleEvent(String msg, String deviceIdFromTopic, String deviceIdJsonPath) { + Object res = JsonPath.read(msg, deviceIdJsonPath); + String deviceIdFromContent = (res != null) ? res.toString() : ""; + if (deviceIdFromContent.equals(deviceIdFromTopic)) { + return true; + } + return false; + } + + private boolean processMultipleEvents(String msg, String deviceIdFromTopic, String deviceIdJsonPath) { + try { + JSONParser jsonParser = new JSONParser(); + JSONArray jsonArray = (JSONArray) jsonParser.parse(msg); + boolean status = false; + for (int i = 0; i < jsonArray.size(); i++) { + status = processSingleEvent(jsonArray.get(i).toString(), deviceIdFromTopic, deviceIdJsonPath); + if (!status) { + return false; + } + } + return status; + } catch (ParseException e) { + log.error("Invalid input " + msg, e); + return false; + } + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTEventAdapterConstants.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTEventAdapterConstants.java new file mode 100644 index 000000000..27ff7acc4 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTEventAdapterConstants.java @@ -0,0 +1,66 @@ +/* +* 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.input.adapter.mqtt.util; + + +/** + * This holds the constants related to mqtt event adapter. + */ +public class MQTTEventAdapterConstants { + + public static final String ADAPTER_TYPE_MQTT = "oauth-mqtt"; + public static final String ADAPTER_CONF_URL = "url"; + public static final String ADAPTER_CONF_USERNAME = "username"; + public static final String ADAPTER_CONF_USERNAME_HINT = "username.hint"; + public static final String ADAPTER_CONF_SCOPES = "scopes"; + public static final String ADAPTER_CONF_SCOPES_HINT = "scopes.hint"; + public static final String ADAPTER_CONF_URL_HINT = "url.hint"; + public static final String ADAPTER_CONF_DCR_URL = "dcrUrl"; + public static final String ADAPTER_CONF_DCR_URL_HINT = "dcrUrl.hint"; + public static final String ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME = "contentValidation"; + public static final String ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT = "contentValidation.hint"; + public static final String ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS = "contentValidationParams"; + public static final String ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS_HINT = "contentValidationParams.hint"; + public static final String ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME = "contentTransformer"; + public static final String ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT = "contentTransformer.hint"; + public static final String ADAPTER_MESSAGE_TOPIC = "topic"; + public static final String ADAPTER_MESSAGE_TOPIC_HINT = "topic.hint"; + public static final String ADAPTER_CONF_CLIENTID = "clientId"; + public static final String ADAPTER_CONF_CLIENTID_HINT = "clientId.hint"; + public static final String ADAPTER_CONF_CLEAN_SESSION = "cleanSession"; + public static final String ADAPTER_CONF_CLEAN_SESSION_HINT = "cleanSession.hint"; + public static final String ADAPTER_CONF_KEEP_ALIVE = "keepAlive"; + public static final int ADAPTER_CONF_DEFAULT_KEEP_ALIVE = 60000; + + public static int initialReconnectDuration = 10000; + public static final int reconnectionProgressionFactor = 2; + + public static final String EMPTY_STRING = ""; + public static final String GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer refresh_token"; + public static final String TOKEN_SCOPE = "production"; + public static final String APPLICATION_TYPE = "device"; + public static final String CLIENT_ID = "client_id"; + public static final String CLIENT_SECRET = "client_secret"; + public static final String CLIENT_NAME = "client_name"; + public static final String DEFAULT = "default"; + public static final String MQTT_CONTENT_VALIDATION_DEFAULT_PARAMETERS = ""; + public static final String TOPIC = "topic"; + public static final String PAYLOAD = "payload"; + public static final String DEVICE_ID_JSON_PATH = "device_id_json_path"; + public static final String DEVICE_ID_TOPIC_HIERARCHY_INDEX = "device_id_topic_hierarchy_index"; +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTUtil.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTUtil.java new file mode 100644 index 000000000..1d1fea18d --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTUtil.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLContextBuilder; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; + +/** + * This is the utility class that is used for MQTT input adapater. + */ +public class MQTTUtil { + private static final String HTTPS_PROTOCOL = "https"; + private static final Log log = LogFactory.getLog(MQTTUtil.class); + /** + * Return a http client instance + * + * @param protocol- service endpoint protocol http/https + * @return + */ + public static HttpClient getHttpClient(String protocol) + throws IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException { + HttpClient httpclient; + if (HTTPS_PROTOCOL.equals(protocol)) { + SSLContextBuilder builder = new SSLContextBuilder(); + builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); + SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build()); + httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); + } else { + httpclient = HttpClients.createDefault(); + } + return httpclient; + } + + public static String getResponseString(HttpResponse httpResponse) throws IOException { + BufferedReader br = null; + try { + br = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent())); + String readLine; + String response = ""; + while (((readLine = br.readLine()) != null)) { + response += readLine; + } + return response; + } finally { + EntityUtils.consumeQuietly(httpResponse.getEntity()); + if (br != null) { + try { + br.close(); + } catch (IOException e) { + log.warn("Error while closing the connection! " + e.getMessage()); + } + } + } + } + + public static JWTClientManagerService getJWTClientManagerService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + JWTClientManagerService jwtClientManagerService = + (JWTClientManagerService) ctx.getOSGiService(JWTClientManagerService.class, null); + if (jwtClientManagerService == null) { + String msg = "JWT management service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return jwtClientManagerService; + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/PropertyUtils.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/PropertyUtils.java new file mode 100644 index 000000000..5e511de3e --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/PropertyUtils.java @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +package org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.util; + +import org.wso2.carbon.base.ServerConfiguration; +import org.wso2.carbon.core.util.Utils; + +public class PropertyUtils { + private static final String MQTT_PORT = "\\$\\{mqtt.broker.port\\}"; + private static final String MQTT_BROKER_HOST = "\\$\\{mqtt.broker.host\\}"; + private static final String CARBON_CONFIG_PORT_OFFSET = "Ports.Offset"; + private static final String DEFAULT_CARBON_LOCAL_IP_PROPERTY = "carbon.local.ip"; + private static final int CARBON_DEFAULT_PORT_OFFSET = 0; + private static final int DEFAULT_MQTT_PORT = 1883; + + //This method is only used if the mb features are within DAS. + public static String replaceMqttProperty (String urlWithPlaceholders) { + urlWithPlaceholders = Utils.replaceSystemProperty(urlWithPlaceholders); + urlWithPlaceholders = urlWithPlaceholders.replaceAll(MQTT_PORT, "" + (DEFAULT_MQTT_PORT + getPortOffset())); + urlWithPlaceholders = urlWithPlaceholders.replaceAll(MQTT_BROKER_HOST, System.getProperty( + DEFAULT_CARBON_LOCAL_IP_PROPERTY, "localhost")); + return urlWithPlaceholders; + } + + private static int getPortOffset() { + ServerConfiguration carbonConfig = ServerConfiguration.getInstance(); + String portOffset = System.getProperty("portOffset", carbonConfig.getFirstProperty(CARBON_CONFIG_PORT_OFFSET)); + try { + if ((portOffset != null)) { + return Integer.parseInt(portOffset.trim()); + } else { + return CARBON_DEFAULT_PORT_OFFSET; + } + } catch (NumberFormatException e) { + return CARBON_DEFAULT_PORT_OFFSET; + } + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/RegistrationProfile.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/RegistrationProfile.java new file mode 100644 index 000000000..5871fa5b8 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/RegistrationProfile.java @@ -0,0 +1,73 @@ +package org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.util; + +/** + * This class represents the data that are required to register + * the oauth application. + */ +public class RegistrationProfile { + + private String callbackUrl; + private String clientName; + private String tokenScope; + private String owner; + private String grantType; + private String applicationType; + + private static final String TAG = RegistrationProfile.class.getSimpleName(); + + public String getCallbackUrl() { + return callbackUrl; + } + + public void setCallbackUrl(String callBackUrl) { + this.callbackUrl = callBackUrl; + } + + public String getClientName() { + return clientName; + } + + public void setClientName(String clientName) { + this.clientName = clientName; + } + + public String getTokenScope() { + return tokenScope; + } + + public void setTokenScope(String tokenScope) { + this.tokenScope = tokenScope; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public String getGrantType() { + return grantType; + } + + public void setGrantType(String grantType) { + this.grantType = grantType; + } + + public String getApplicationType() { + return applicationType; + } + + public void setApplicationType(String applicationType) { + this.applicationType = applicationType; + } + + public String toJSON() { + String jsonString = + "{\"callbackUrl\": \"" + callbackUrl + "\",\"clientName\": \"" + clientName + "\", \"tokenScope\": " + + "\"" + tokenScope + "\", \"owner\": \"" + owner + "\"," + "\"grantType\": \"" + grantType + + "\", \"saasApp\" :false }\n"; + return jsonString; + } +} \ No newline at end of file diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/resources/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/i18n/Resources.properties b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/resources/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/i18n/Resources.properties new file mode 100644 index 000000000..d1f6676ed --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.mqtt/src/main/resources/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/i18n/Resources.properties @@ -0,0 +1,40 @@ +# +# 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. +# + +topic=Topic +topic.hint=Topic subscribed +clientId=Client Id +clientId.hint=client identifier is used by the server to identify a client when it reconnects, It used for durable subscriptions or reliable delivery of messages is required. +url=Broker Url +username=Username +username.hint=Username of the broker (if required) +scopes=Scopes +scopes.hint=Scopes required to connect to broker (if required) +dcrUrl=dcrUrl +dcrUrl.hint=dynamic client registration endpoint URL to create application (if required) eg: https://localhost:9443/dynamic-client-web/register +contentValidation=contentValidation +contentValidation.hint=Class Name of the content Validation or 'default' to set default class, required to implement (if required) +contentValidationParams=contentValidationParams +contentValidationParams.hint=ContentValidationParams, comma seperated. (if required) +url.hint=MQTT broker url tcp://localhost:1883 +cleanSession=Clean Session +cleanSession.hint=Persist topic subscriptions and ack positions across client sessions +keepAlive=Keep Alive (In seconds) +events.duplicated.in.cluster=Is events duplicated in cluster +contentTransformer=contentTransformer +contentTransformer.hint=Class Name of the content transformer or 'default' to set default class, required to implement (if required) \ No newline at end of file diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/pom.xml b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/pom.xml new file mode 100644 index 000000000..f4cc2eff8 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/pom.xml @@ -0,0 +1,128 @@ + + + + + iot-base-plugin + org.wso2.carbon.devicemgt-plugins + 2.1.0-SNAPSHOT + ../pom.xml + + 4.0.0 + + org.wso2.carbon.device.mgt.iot.input.adapter.xmpp + bundle + WSO2 Carbon - Device Mgt Input Adaptor Module - XMPP + Provides the back-end functionality of Input adaptor + http://wso2.org + + + + org.wso2.carbon.analytics-common + org.wso2.carbon.event.input.adapter.core + + + org.wso2.carbon + org.wso2.carbon.logging + + + org.wso2.carbon + org.wso2.carbon.core + + + com.googlecode.json-simple.wso2 + json-simple + + + com.jayway.jsonpath + json-path + + + org.igniterealtime.smack.wso2 + smack + + + org.igniterealtime.smack.wso2 + smackx + + + org.wso2.carbon + org.wso2.carbon.user.api + + + org.wso2.carbon + org.wso2.carbon.user.core + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.input.adapter.extension + + + + + + + org.apache.felix + maven-scr-plugin + + + generate-scr-descriptor + + scr + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.artifactId} + ${project.artifactId} + + org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.internal, + org.wso2.carbon.device.mgt.iot.input.adapter.http.internal.* + + + !org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.internal, + !org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.internal.*, + org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.* + + + org.wso2.carbon.event.input.adapter.core, + org.wso2.carbon.event.input.adapter.core.*, + javax.xml.namespace; version=0.0.0, + org.jivesoftware.smack.*, + org.apache.log4j, + org.wso2.carbon.base, + org.wso2.carbon.core.util + + * + + + + + + + \ No newline at end of file diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/XMPPEventAdapter.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/XMPPEventAdapter.java new file mode 100644 index 000000000..54a9913a5 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/XMPPEventAdapter.java @@ -0,0 +1,163 @@ +/* +* 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.input.adapter.xmpp; + +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.util.XMPPAdapterListener; +import org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.util.XMPPServerConnectionConfiguration; +import org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.util.XMPPEventAdapterConstants; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapter; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener; +import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterException; +import org.wso2.carbon.event.input.adapter.core.exception.TestConnectionNotSupportedException; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * Input XMPPEventAdapter will be used to receive events with XMPP protocol using specified broker and topic. + */ +public class XMPPEventAdapter implements InputEventAdapter { + + private final InputEventAdapterConfiguration eventAdapterConfiguration; + private final Map globalProperties; + private InputEventAdapterListener eventAdapterListener; + private final String id = UUID.randomUUID().toString(); + private XMPPAdapterListener xmppAdapterListener; + private XMPPServerConnectionConfiguration xmppServerConnectionConfiguration; + + + public XMPPEventAdapter(InputEventAdapterConfiguration eventAdapterConfiguration, + Map globalProperties) { + this.eventAdapterConfiguration = eventAdapterConfiguration; + this.globalProperties = globalProperties; + } + + @Override + public void init(InputEventAdapterListener eventAdapterListener) throws InputEventAdapterException { + this.eventAdapterListener = eventAdapterListener; + try { + + String contentValidationParams = eventAdapterConfiguration.getProperties().get( + XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS); + Map paramsMap = new HashMap<>(); + if (contentValidationParams != null && !contentValidationParams.isEmpty()) { + String params[] = contentValidationParams.split(","); + for (String param : params) { + String paramsKeyAndValue[] = splitOnFirst(param, ':'); + if (paramsKeyAndValue.length != 2) { + throw new InputEventAdapterException("Invalid parameters for content validation - " + param); + } + paramsMap.put(paramsKeyAndValue[0], paramsKeyAndValue[1]); + } + } + int xmppPort = XMPPEventAdapterConstants.DEFAULT_XMPP_PORT; + String xmppPortString = eventAdapterConfiguration.getProperties() + .get(XMPPEventAdapterConstants.ADAPTER_CONF_PORT); + if (xmppPortString != null && !xmppPortString.trim().isEmpty()) { + xmppPort = Integer.parseInt(xmppPortString); + } + int timeoutInterval = XMPPEventAdapterConstants.DEFAULT_TIMEOUT_INTERVAL; + String timeoutIntervalString = eventAdapterConfiguration.getProperties().get( + XMPPEventAdapterConstants.ADAPTER_CONF_TIMEOUT_INTERVAL); + if (timeoutIntervalString != null && !timeoutIntervalString.trim().isEmpty()) { + timeoutInterval = Integer.parseInt(timeoutIntervalString); + } + xmppServerConnectionConfiguration = + new XMPPServerConnectionConfiguration(eventAdapterConfiguration.getProperties() + .get(XMPPEventAdapterConstants.ADAPTER_CONF_HOST), + xmppPort, + eventAdapterConfiguration.getProperties().get(XMPPEventAdapterConstants.ADAPTER_CONF_USERNAME), + eventAdapterConfiguration.getProperties().get(XMPPEventAdapterConstants.ADAPTER_CONF_PASSWORD), + timeoutInterval, + eventAdapterConfiguration.getProperties().get(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE), + eventAdapterConfiguration.getProperties().get(XMPPEventAdapterConstants + .ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME), + paramsMap, + eventAdapterConfiguration.getProperties().get(XMPPEventAdapterConstants.ADAPTER_CONF_RECIEVER_JID), + eventAdapterConfiguration.getProperties().get(XMPPEventAdapterConstants + .ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME) + ); + + xmppAdapterListener = new XMPPAdapterListener(xmppServerConnectionConfiguration, + eventAdapterListener, PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true)); + + } catch (Throwable t) { + throw new InputEventAdapterException(t.getMessage(), t); + } + } + + private String[] splitOnFirst(String str, char c) { + int idx = str.indexOf(c); + String head = str.substring(0, idx); + String tail = str.substring(idx + 1); + return new String[] { head, tail} ; + } + + @Override + public void testConnect() throws TestConnectionNotSupportedException { + throw new TestConnectionNotSupportedException("not-supported"); + } + + @Override + public void connect() { + xmppAdapterListener.createConnection(); + } + + @Override + public void disconnect() { + if (xmppAdapterListener != null) { + xmppAdapterListener.stopListener(eventAdapterConfiguration.getName()); + } + } + + @Override + public void destroy() { + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof XMPPEventAdapter)) return false; + + XMPPEventAdapter that = (XMPPEventAdapter) o; + + if (!id.equals(that.id)) return false; + + return true; + } + + @Override + public int hashCode() { + return id.hashCode(); + } + + + @Override + public boolean isEventDuplicatedInCluster() { + return true; + } + + @Override + public boolean isPolling() { + return true; + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/XMPPEventAdapterFactory.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/XMPPEventAdapterFactory.java new file mode 100644 index 000000000..996daa187 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/XMPPEventAdapterFactory.java @@ -0,0 +1,150 @@ +/* +* 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.input.adapter.xmpp; + +import org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.util.XMPPEventAdapterConstants; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapter; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterFactory; +import org.wso2.carbon.event.input.adapter.core.MessageType; +import org.wso2.carbon.event.input.adapter.core.Property; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.ResourceBundle; + +/** + * The xmpp event adapter factory class to create a xmpp input adapter + */ +public class XMPPEventAdapterFactory extends InputEventAdapterFactory { + + private ResourceBundle resourceBundle = ResourceBundle.getBundle + ("org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.i18n.Resources", Locale.getDefault()); + + @Override + public String getType() { + return XMPPEventAdapterConstants.ADAPTER_TYPE_XMPP; + } + + @Override + public List getSupportedMessageFormats() { + List supportInputMessageTypes = new ArrayList(); + supportInputMessageTypes.add(MessageType.JSON); + supportInputMessageTypes.add(MessageType.TEXT); + supportInputMessageTypes.add(MessageType.XML); + supportInputMessageTypes.add(MessageType.WSO2EVENT); + return supportInputMessageTypes; + } + + @Override + public List getPropertyList() { + List propertyList = new ArrayList(); + // Url + Property host = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_HOST); + host.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_HOST)); + host.setRequired(true); + host.setHint(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_HOST_HINT)); + + // Host Port + Property port = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_PORT); + port.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_PORT)); + port.setRequired(true); + port.setHint(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_PORT_HINT)); + + //Broker Username + Property userName = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_USERNAME); + userName.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_USERNAME)); + userName.setRequired(true); + userName.setHint(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_USERNAME_HINT)); + + //Broker Password + Property password = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_PASSWORD); + password.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_PASSWORD)); + password.setRequired(true); + password.setHint(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_PASSWORD_HINT)); + + //Timeout Interval + Property timooutInterval = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_TIMEOUT_INTERVAL); + timooutInterval.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_TIMEOUT_INTERVAL_HINT)); + timooutInterval.setRequired(false); + timooutInterval.setHint(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_TIMEOUT_INTERVAL_HINT)); + + //Resource + Property resource = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE); + resource.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE)); + resource.setRequired(false); + resource.setHint(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE_HINT)); + + //Content Validator details + Property contentValidator = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME); + contentValidator.setDisplayName( + resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME)); + contentValidator.setRequired(false); + contentValidator.setHint( + resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT)); + contentValidator.setDefaultValue(XMPPEventAdapterConstants.DEFAULT); + + //Content Validator Params details + Property contentValidatorParams = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS); + contentValidatorParams.setDisplayName( + resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS)); + contentValidatorParams.setRequired(false); + contentValidatorParams.setHint( + resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS_HINT)); + contentValidatorParams.setDefaultValue(XMPPEventAdapterConstants.XMPP_CONTENT_VALIDATION_DEFAULT_PARAMETERS); + + Property jid = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_RECIEVER_JID); + jid.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_RECIEVER_JID)); + jid.setRequired(true); + jid.setHint(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_RECIEVER_JID_HINT)); + + //Content Transformer details + Property contentTransformer = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME); + contentTransformer.setDisplayName( + resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME)); + contentTransformer.setRequired(false); + contentTransformer.setHint( + resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT)); + contentTransformer.setDefaultValue(XMPPEventAdapterConstants.DEFAULT); + + propertyList.add(host); + propertyList.add(port); + propertyList.add(userName); + propertyList.add(password); + propertyList.add(timooutInterval); + propertyList.add(resource); + propertyList.add(contentValidator); + propertyList.add(contentValidatorParams); + propertyList.add(jid); + propertyList.add(contentTransformer); + return propertyList; + } + + @Override + public String getUsageTips() { + return null; + } + + @Override + public InputEventAdapter createEventAdapter(InputEventAdapterConfiguration eventAdapterConfiguration, + Map globalProperties) { + return new XMPPEventAdapter(eventAdapterConfiguration, globalProperties); + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/exception/XMPPContentInitializationException.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/exception/XMPPContentInitializationException.java new file mode 100644 index 000000000..ec26e4976 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/exception/XMPPContentInitializationException.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.exception; + +/** + * This exception will thrown when content validator is failed to intialiaze. + */ +public class XMPPContentInitializationException extends RuntimeException { + private String errMessage; + + public XMPPContentInitializationException(String msg, Exception nestedEx) { + super(msg, nestedEx); + setErrorMessage(msg); + } + + public XMPPContentInitializationException(String message, Throwable cause) { + super(message, cause); + setErrorMessage(message); + } + + public XMPPContentInitializationException(String msg) { + super(msg); + setErrorMessage(msg); + } + + public XMPPContentInitializationException() { + super(); + } + + public XMPPContentInitializationException(Throwable cause) { + super(cause); + } + + public String getErrorMessage() { + return errMessage; + } + + public void setErrorMessage(String errMessage) { + this.errMessage = errMessage; + } +} \ No newline at end of file diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/internal/InputAdapterServiceComponent.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/internal/InputAdapterServiceComponent.java new file mode 100644 index 000000000..b02f11075 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/internal/InputAdapterServiceComponent.java @@ -0,0 +1,67 @@ +/* +* 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.input.adapter.xmpp.internal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.http.HttpService; +import org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.XMPPEventAdapterFactory; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterFactory; +import org.wso2.carbon.user.core.service.RealmService; + +/** + * @scr.component name="input.iot.xmpp.AdapterService.component" immediate="true" + * @scr.reference name="user.realmservice.default" + * interface="org.wso2.carbon.user.core.service.RealmService" cardinality="1..1" + * policy="dynamic" bind="setRealmService" unbind="unsetRealmService" + */ +public class InputAdapterServiceComponent { + + private static final Log log = LogFactory.getLog(InputAdapterServiceComponent.class); + + protected void activate(ComponentContext context) { + try { + InputEventAdapterFactory xmppEventEventAdapterFactory = new XMPPEventAdapterFactory(); + context.getBundleContext().registerService(InputEventAdapterFactory.class.getName(), + xmppEventEventAdapterFactory, null); + if (log.isDebugEnabled()) { + log.debug("Successfully deployed the input adapter service"); + } + } catch (RuntimeException e) { + log.error("Can not create the input adapter service ", e); + } + } + + protected void setRealmService(RealmService realmService) { + InputAdapterServiceDataHolder.registerRealmService(realmService); + } + + protected void unsetRealmService(RealmService realmService) { + InputAdapterServiceDataHolder.registerRealmService(null); + } + + protected void setHttpService(HttpService httpService) { + InputAdapterServiceDataHolder.registerHTTPService(httpService); + } + + protected void unsetHttpService(HttpService httpService) { + InputAdapterServiceDataHolder.registerHTTPService(null); + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/internal/InputAdapterServiceDataHolder.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/internal/InputAdapterServiceDataHolder.java new file mode 100644 index 000000000..fac88721b --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/internal/InputAdapterServiceDataHolder.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ +package org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.internal; + +import org.osgi.service.http.HttpService; +import org.wso2.carbon.user.core.service.RealmService; + +/** + * common place to hold some OSGI service references. + */ +public final class InputAdapterServiceDataHolder { + + private static RealmService realmService; + private static HttpService httpService; + + private InputAdapterServiceDataHolder() { + } + + public static void registerRealmService( + RealmService realmService) { + InputAdapterServiceDataHolder.realmService = realmService; + } + + public static RealmService getRealmService() { + return realmService; + } + + public static void registerHTTPService( + HttpService httpService) { + InputAdapterServiceDataHolder.httpService = httpService; + } + + public static HttpService getHTTPService() { + return httpService; + } + + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/util/XMPPAdapterListener.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/util/XMPPAdapterListener.java new file mode 100644 index 000000000..bf5c6fde8 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/util/XMPPAdapterListener.java @@ -0,0 +1,224 @@ +/* +* 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.input.adapter.xmpp.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jivesoftware.smack.ConnectionConfiguration; +import org.jivesoftware.smack.PacketListener; +import org.jivesoftware.smack.SmackConfiguration; +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.filter.AndFilter; +import org.jivesoftware.smack.filter.PacketFilter; +import org.jivesoftware.smack.filter.PacketTypeFilter; +import org.jivesoftware.smack.filter.ToContainsFilter; +import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.Packet; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.core.ServerStatus; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentInfo; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentTransformer; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentValidator; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.DefaultContentTransformer; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.DefaultContentValidator; +import org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.exception.XMPPContentInitializationException; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener; +import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterRuntimeException; +import java.util.HashMap; +import java.util.Map; + +public class XMPPAdapterListener implements Runnable { + private static final Log log = LogFactory.getLog(XMPPAdapterListener.class); + + private XMPPConnection xmppConnection; + private XMPPServerConnectionConfiguration xmppServerConnectionConfiguration; + private int tenantId; + private boolean connectionSucceeded = false; + private ContentValidator contentValidator; + private Map contentValidationParams; + private ContentTransformer contentTransformer; + private PacketListener packetListener; + + private InputEventAdapterListener eventAdapterListener = null; + + + public XMPPAdapterListener(XMPPServerConnectionConfiguration xmppServerConnectionConfiguration, + InputEventAdapterListener inputEventAdapterListener, int tenantId) { + this.xmppServerConnectionConfiguration = xmppServerConnectionConfiguration; + this.eventAdapterListener = inputEventAdapterListener; + this.tenantId = tenantId; + + try { + String contentValidatorClassName = this.xmppServerConnectionConfiguration.getContentValidatorClassName(); + if (contentValidatorClassName != null && contentValidatorClassName.equals(XMPPEventAdapterConstants.DEFAULT)) { + contentValidator = new DefaultContentValidator(); + } else if (contentValidatorClassName != null && !contentValidatorClassName.isEmpty()) { + try { + Class contentValidatorClass = Class.forName(contentValidatorClassName) + .asSubclass(ContentValidator.class); + contentValidator = contentValidatorClass.newInstance(); + } catch (ClassNotFoundException e) { + throw new XMPPContentInitializationException( + "Unable to find the class validator: " + contentValidatorClassName, e); + } catch (InstantiationException e) { + throw new XMPPContentInitializationException( + "Unable to create an instance of :" + contentValidatorClassName, e); + } catch (IllegalAccessException e) { + throw new XMPPContentInitializationException("Access of the instance in not allowed.", e); + } + } + contentValidationParams = xmppServerConnectionConfiguration.getContentValidatorParams(); + + String contentTransformerClassName = this.xmppServerConnectionConfiguration.getContentTransformerClassName(); + if (contentTransformerClassName != null && contentTransformerClassName.equals(XMPPEventAdapterConstants.DEFAULT)) { + contentTransformer = new DefaultContentTransformer(); + } else if (contentTransformerClassName != null && !contentTransformerClassName.isEmpty()) { + try { + Class contentTransformerClass = Class.forName(contentTransformerClassName) + .asSubclass(ContentTransformer.class); + contentTransformer = contentTransformerClass.newInstance(); + } catch (ClassNotFoundException e) { + throw new XMPPContentInitializationException( + "Unable to find the class transformer: " + contentTransformerClassName, e); + } catch (InstantiationException e) { + throw new XMPPContentInitializationException( + "Unable to create an instance of :" + contentTransformerClassName, e); + } catch (IllegalAccessException e) { + throw new XMPPContentInitializationException("Access of the instance in not allowed.", e); + } + } + } catch (Throwable e) { + log.error("Exception occurred while subscribing to MQTT broker at " + + xmppServerConnectionConfiguration.getHost()); + throw new InputEventAdapterRuntimeException(e); + } + + } + + public void startListener() throws XMPPException { + SmackConfiguration.setPacketReplyTimeout(xmppServerConnectionConfiguration.getTimeoutInterval()); + ConnectionConfiguration config = new ConnectionConfiguration(xmppServerConnectionConfiguration.getHost(), + xmppServerConnectionConfiguration.getPort()); + config.setSASLAuthenticationEnabled(false); + config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled); + xmppConnection = new XMPPConnection(config); + xmppConnection.connect(); + String resource = xmppServerConnectionConfiguration.getResource(); + String username = xmppServerConnectionConfiguration.getUsername(); + String password = xmppServerConnectionConfiguration.getPassword(); + try { + if (resource == null || resource.trim().isEmpty()) { + xmppConnection.login(username, password); + } else { + xmppConnection.login(username, password, resource); + } + setFilterOnReceiver(xmppServerConnectionConfiguration.getJid()); + } catch (XMPPException e) { + String errorMsg = "Login attempt to the XMPP Server with username - " + username + " failed."; + log.info(errorMsg); + throw new InputEventAdapterRuntimeException(errorMsg, e); + } + } + + public void stopListener(String adapterName) { + if (connectionSucceeded) { + // Un-subscribe accordingly and disconnect from the MQTT server. + if (!ServerStatus.getCurrentStatus().equals(ServerStatus.STATUS_SHUTTING_DOWN)) { + xmppConnection.removePacketListener(packetListener); + } + xmppConnection.disconnect(); + } + //This is to stop all running reconnection threads + connectionSucceeded = true; + } + + protected void setFilterOnReceiver(String receiverJID) { + PacketFilter packetFilter = new AndFilter(new PacketTypeFilter(Message.class), new ToContainsFilter( + receiverJID)); + packetListener = new PacketListener() { + @Override + public void processPacket(Packet packet) { + if (packet instanceof Message) { + final Message xmppMessage = (Message) packet; + Thread msgProcessThread = new Thread() { + public void run() { + processIncomingMessage(xmppMessage); + } + }; + msgProcessThread.start(); + } + } + }; + xmppConnection.addPacketListener(packetListener, packetFilter); + } + + public void processIncomingMessage(Message xmppMessage) { + try { + String from = xmppMessage.getFrom(); + String subject = xmppMessage.getSubject(); + String message = xmppMessage.getBody(); + if (log.isDebugEnabled()) { + log.debug(message); + } + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId); + + if (log.isDebugEnabled()) { + log.debug("Event received in MQTT Event Adapter - " + message); + } + + if (contentValidator != null && contentTransformer != null) { + Map dynamicParmaters = new HashMap<>(); + dynamicParmaters.put(XMPPEventAdapterConstants.FROM_KEY, from); + dynamicParmaters.put(XMPPEventAdapterConstants.SUBJECT_KEY, subject); + message = (String) contentTransformer.transform(message, dynamicParmaters); + ContentInfo contentInfo = contentValidator.validate(message, contentValidationParams, dynamicParmaters); + if (contentInfo != null && contentInfo.isValidContent()) { + eventAdapterListener.onEvent(contentInfo.getMessage()); + } + } else { + eventAdapterListener.onEvent(message); + } + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } + + @Override + public void run() { + while (!connectionSucceeded) { + try { + XMPPEventAdapterConstants.initialReconnectDuration = XMPPEventAdapterConstants.initialReconnectDuration + * XMPPEventAdapterConstants.reconnectionProgressionFactor; + Thread.sleep(XMPPEventAdapterConstants.initialReconnectDuration); + startListener(); + connectionSucceeded = true; + log.info("XMPP Connection successful"); + } catch (InterruptedException e) { + log.error("Interruption occurred while waiting for reconnection", e); + } catch (XMPPException e) { + log.error("XMPP Exception occurred when starting listener", e); + } + } + } + + public void createConnection() { + new Thread(this).start(); + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/util/XMPPEventAdapterConstants.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/util/XMPPEventAdapterConstants.java new file mode 100644 index 000000000..70ebf950a --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/util/XMPPEventAdapterConstants.java @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ +package org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.util; + + +/** + * This holds the constants related to xmpp event adapter. + */ +public class XMPPEventAdapterConstants { + + public static final String ADAPTER_TYPE_XMPP = "xmpp"; + + //static properties + public static final String ADAPTER_CONF_HOST = "host"; + public static final String ADAPTER_CONF_HOST_HINT = "host.hint"; + public static final String ADAPTER_CONF_PORT = "port"; + public static final String ADAPTER_CONF_PORT_HINT = "port.hint"; + public static final String ADAPTER_CONF_USERNAME = "username"; + public static final String ADAPTER_CONF_USERNAME_HINT = "username.hint"; + public static final String ADAPTER_CONF_PASSWORD = "password"; + public static final String ADAPTER_CONF_PASSWORD_HINT = "password.hint"; + public static final String ADAPTER_CONF_RESOURCE = "resource"; + public static final String ADAPTER_CONF_RESOURCE_HINT = "resource.hint"; + public static final String ADAPTER_CONF_TIMEOUT_INTERVAL = "timeoutInterval"; + public static final String ADAPTER_CONF_TIMEOUT_INTERVAL_HINT = "timeoutInterval.hint"; + public static final String ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME = "contentValidation"; + public static final String ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT = "contentValidation.hint"; + public static final String ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS = "contentValidationParams"; + public static final String ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS_HINT = "contentValidationParams.hint"; + public static final String ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME = "contentTransformer"; + public static final String ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT = "contentTransformer.hint"; + public static final String ADAPTER_CONF_RECIEVER_JID = "jid"; + public static final String ADAPTER_CONF_RECIEVER_JID_HINT = "jid.hint"; + public static final int DEFAULT_XMPP_PORT = 5222; + public static final int DEFAULT_TIMEOUT_INTERVAL = 5000; + + public static int initialReconnectDuration = 10000; + public static final int reconnectionProgressionFactor = 2; + + public static final String DEFAULT = "default"; + + public static final String XMPP_CONTENT_VALIDATION_DEFAULT_PARAMETERS = ""; + public static final String FROM_KEY = "from"; + public static final String SUBJECT_KEY = "subject"; +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/util/XMPPServerConnectionConfiguration.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/util/XMPPServerConnectionConfiguration.java new file mode 100644 index 000000000..4f55225b5 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/util/XMPPServerConnectionConfiguration.java @@ -0,0 +1,96 @@ +/* +* 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.input.adapter.xmpp.util; + +import java.util.Map; + +/** + * This holds the configurations related to MQTT Broker. + */ +public class XMPPServerConnectionConfiguration { + + private String host; + private int port; + private String username; + private String password; + private int timeoutInterval; + private String resource; + private String jid; + private String contentValidatorClassName; + private Map contentValidatorParams; + private String contentTransformerClassName; + + public String getHost() { + return host; + } + + public int getPort() { + return port; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public int getTimeoutInterval() { + return timeoutInterval; + } + + public String getResource() { + return resource; + } + + public String getContentValidatorClassName() { + return contentValidatorClassName; + } + + public Map getContentValidatorParams() { + return contentValidatorParams; + } + + public String getJid() { + return jid; + } + + public String getContentTransformerClassName() { + return contentTransformerClassName; + } + + public XMPPServerConnectionConfiguration(String host, int port, String username, String password, + int timeoutInterval, String resource, String contentValidatorClassName, + Map contentValidatorParams, String jid, + String contentTransformerClassName) { + this.host = host; + this.port = port; + this.username = username; + this.password = password; + this.timeoutInterval = timeoutInterval; + this.resource = resource; + this.contentValidatorClassName = contentValidatorClassName; + if (contentValidatorParams != null) { + this.contentValidatorParams = contentValidatorParams; + } + this.contentTransformerClassName = contentTransformerClassName; + this.jid = jid; + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/resources/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/i18n/Resources.properties b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/resources/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/i18n/Resources.properties new file mode 100644 index 000000000..95a62ec03 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter.xmpp/src/main/resources/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/i18n/Resources.properties @@ -0,0 +1,38 @@ +# +# 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. +# + +host=Server Url +host.hint=XMPP Server url +port=Server Port +port.hint=Server Port Number +username=Username +username.hint=Username of the broker +password=Password +password.hint=Password to connect to the server. +timeoutInterval=Time out Interval +timeoutInterval.hint=used by listeners to the server and for reconnection schedules. +resource=Resource +resource.hint=specific to the XMPP-Account to which the login is made to. +contentValidation=contentValidation +contentValidation.hint=Class Name of the content Validation or 'default' to set default class, required to implement (if required) +contentValidationParams=contentValidationParams +contentValidationParams.hint=ContentValidationParams, comma seperated. (if required) +jid=jid +jid.hint=JID - XMPP Account Name. +contentTransformer=contentTransformer +contentTransformer.hint=Class Name of the content transformer or 'default' to set default class, required to implement (if required) \ No newline at end of file diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/pom.xml b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/pom.xml new file mode 100644 index 000000000..50d0474e0 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/pom.xml @@ -0,0 +1,132 @@ + + + + + iot-base-plugin + org.wso2.carbon.devicemgt-plugins + 2.1.0-SNAPSHOT + ../pom.xml + + 4.0.0 + org.wso2.carbon.device.mgt.iot.output.adapter.mqtt + + bundle + WSO2 Carbon - Device Mgt Output MQTT Adaptor Module + org.wso2.carbon.device.mgt.iot.output.adapter.mqtt provides the back-end functionality of mqtt adaptor + + http://wso2.org + + + + org.wso2.carbon.analytics-common + org.wso2.carbon.event.output.adapter.core + + + org.eclipse.paho + org.eclipse.paho.client.mqttv3 + + + org.wso2.carbon + org.wso2.carbon.core + + + org.wso2.carbon + org.wso2.carbon.logging + + + org.apache.httpcomponents.wso2 + httpcore + + + org.wso2.orbit.org.apache.httpcomponents + httpclient + + + com.googlecode.json-simple.wso2 + json-simple + + + org.wso2.carbon.devicemgt + org.wso2.carbon.identity.jwt.client.extension + + + + + + org.apache.felix + maven-scr-plugin + + + generate-scr-descriptor + + scr + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.artifactId} + ${project.artifactId} + + org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.internal, + org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.internal.* + + + !org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.internal, + !org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.internal.*, + org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.*, + + + org.wso2.carbon.event.output.adapter.core, + org.wso2.carbon.event.output.adapter.core.*, + javax.net.ssl, + org.apache.commons.logging, + org.apache.http, + org.apache.http.client, + org.apache.http.client.methods, + org.apache.http.conn.socket, + org.apache.http.conn.ssl, + org.apache.http.entity, + org.apache.http.impl.client, + org.apache.http.util, + org.eclipse.paho.client.mqttv3, + org.eclipse.paho.client.mqttv3.persist, + org.json.simple, + org.json.simple.parser, + org.osgi.framework, + org.osgi.service.component, + org.wso2.carbon.context, + org.wso2.carbon.identity.jwt.client.extension.* + + + + + + + \ No newline at end of file diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/MQTTEventAdapter.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/MQTTEventAdapter.java new file mode 100644 index 000000000..9a98060a5 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/MQTTEventAdapter.java @@ -0,0 +1,204 @@ +/* +* 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.output.adapter.mqtt; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.util.MQTTAdapterPublisher; +import org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.util.MQTTEventAdapterConstants; +import org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.util.MQTTBrokerConnectionConfiguration; +import org.wso2.carbon.event.output.adapter.core.EventAdapterUtil; +import org.wso2.carbon.event.output.adapter.core.OutputEventAdapter; +import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration; +import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException; +import org.wso2.carbon.event.output.adapter.core.exception.TestConnectionNotSupportedException; + +import java.util.Map; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Output MQTTEventAdapter will be used to publish events with MQTT protocol to specified broker and topic. + */ +public class MQTTEventAdapter implements OutputEventAdapter { + + private OutputEventAdapterConfiguration eventAdapterConfiguration; + private Map globalProperties; + private MQTTAdapterPublisher mqttAdapterPublisher; + private int connectionKeepAliveInterval; + private String qos; + private static ThreadPoolExecutor threadPoolExecutor; + private static final Log log = LogFactory.getLog(MQTTEventAdapter.class); + private int tenantId; + + public MQTTEventAdapter(OutputEventAdapterConfiguration eventAdapterConfiguration, + Map globalProperties) { + this.eventAdapterConfiguration = eventAdapterConfiguration; + this.globalProperties = globalProperties; + Object keeAliveInternal = globalProperties.get(MQTTEventAdapterConstants.CONNECTION_KEEP_ALIVE_INTERVAL); + if (keeAliveInternal != null) { + try { + connectionKeepAliveInterval = Integer.parseInt(keeAliveInternal.toString()); + } catch (NumberFormatException e) { + log.error("Error when configuring user specified connection keep alive time, using default value", e); + connectionKeepAliveInterval = MQTTEventAdapterConstants.DEFAULT_CONNECTION_KEEP_ALIVE_INTERVAL; + } + } else { + connectionKeepAliveInterval = MQTTEventAdapterConstants.DEFAULT_CONNECTION_KEEP_ALIVE_INTERVAL; + } + } + + @Override + public void init() throws OutputEventAdapterException { + tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + //ThreadPoolExecutor will be assigned if it is null + if (threadPoolExecutor == null) { + int minThread; + int maxThread; + int jobQueSize; + long defaultKeepAliveTime; + //If global properties are available those will be assigned else constant values will be assigned + if (globalProperties.get(MQTTEventAdapterConstants.ADAPTER_MIN_THREAD_POOL_SIZE_NAME) != null) { + minThread = Integer.parseInt(globalProperties.get( + MQTTEventAdapterConstants.ADAPTER_MIN_THREAD_POOL_SIZE_NAME)); + } else { + minThread = MQTTEventAdapterConstants.DEFAULT_MIN_THREAD_POOL_SIZE; + } + + if (globalProperties.get(MQTTEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE_NAME) != null) { + maxThread = Integer.parseInt(globalProperties.get( + MQTTEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE_NAME)); + } else { + maxThread = MQTTEventAdapterConstants.DEFAULT_MAX_THREAD_POOL_SIZE; + } + + if (globalProperties.get(MQTTEventAdapterConstants.ADAPTER_KEEP_ALIVE_TIME_NAME) != null) { + defaultKeepAliveTime = Integer.parseInt(globalProperties.get( + MQTTEventAdapterConstants.ADAPTER_KEEP_ALIVE_TIME_NAME)); + } else { + defaultKeepAliveTime = MQTTEventAdapterConstants.DEFAULT_KEEP_ALIVE_TIME_IN_MILLIS; + } + + if (globalProperties.get(MQTTEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME) != null) { + jobQueSize = Integer.parseInt(globalProperties.get( + MQTTEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME)); + } else { + jobQueSize = MQTTEventAdapterConstants.DEFAULT_EXECUTOR_JOB_QUEUE_SIZE; + } + + threadPoolExecutor = new ThreadPoolExecutor(minThread, maxThread, defaultKeepAliveTime, + TimeUnit.MILLISECONDS, new LinkedBlockingQueue( + jobQueSize)); + } + } + + @Override + public void testConnect() throws TestConnectionNotSupportedException { + throw new TestConnectionNotSupportedException("Test connection is not available"); + } + + @Override + public void connect() { + MQTTBrokerConnectionConfiguration mqttBrokerConnectionConfiguration = + new MQTTBrokerConnectionConfiguration(eventAdapterConfiguration.getStaticProperties() + .get(MQTTEventAdapterConstants.ADAPTER_CONF_URL), + eventAdapterConfiguration.getStaticProperties() + .get(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME), + eventAdapterConfiguration.getStaticProperties() + .get(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL), + eventAdapterConfiguration.getStaticProperties() + .get(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES), + connectionKeepAliveInterval, + eventAdapterConfiguration.getStaticProperties() + .get(MQTTEventAdapterConstants.ADAPTER_CONF_CLEAN_SESSION) + ); + + String clientId = eventAdapterConfiguration.getStaticProperties().get( + MQTTEventAdapterConstants.ADAPTER_CONF_CLIENTID); + qos = eventAdapterConfiguration.getStaticProperties().get(MQTTEventAdapterConstants.ADAPTER_MESSAGE_QOS); + mqttAdapterPublisher = new MQTTAdapterPublisher(mqttBrokerConnectionConfiguration, clientId); + } + + @Override + public void publish(Object message, Map dynamicProperties) { + String topic = dynamicProperties.get(MQTTEventAdapterConstants.ADAPTER_MESSAGE_TOPIC); + try { + threadPoolExecutor.submit(new MQTTSender(topic, message)); + } catch (RejectedExecutionException e) { + EventAdapterUtil.logAndDrop(eventAdapterConfiguration.getName(), message, "Job queue is full", e, log, + tenantId); + } + } + + @Override + public void disconnect() { + try { + if (mqttAdapterPublisher != null) { + mqttAdapterPublisher.close(); + mqttAdapterPublisher = null; + } + } catch (OutputEventAdapterException e) { + log.error("Exception when closing the mqtt publisher connection on Output MQTT Adapter '" + + eventAdapterConfiguration.getName() + "'", e); + } + } + + @Override + public void destroy() { + //not required + } + + @Override + public boolean isPolled() { + return false; + } + + class MQTTSender implements Runnable { + + String topic; + Object message; + + MQTTSender(String topic, Object message) { + this.topic = topic; + this.message = message; + } + + @Override + public void run() { + try { + if (!mqttAdapterPublisher.isConnected()) { + synchronized (MQTTEventAdapter.class) { + if (!mqttAdapterPublisher.isConnected()) { + mqttAdapterPublisher.connect(); + } + } + } + if (qos == null || qos.trim().isEmpty()) { + mqttAdapterPublisher.publish(message.toString(), topic); + } else { + mqttAdapterPublisher.publish(Integer.parseInt(qos), message.toString(), topic); + } + } catch (Throwable t) { + EventAdapterUtil.logAndDrop(eventAdapterConfiguration.getName(), message, null, t, log, tenantId); + } + } + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/MQTTEventAdapterFactory.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/MQTTEventAdapterFactory.java new file mode 100644 index 000000000..0caa6b8f7 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/MQTTEventAdapterFactory.java @@ -0,0 +1,126 @@ +/* +* 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.output.adapter.mqtt; + +import org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.util.MQTTEventAdapterConstants; +import org.wso2.carbon.event.output.adapter.core.*; + +import java.util.*; + +/** + * The mqtt event adapter factory class to create a mqtt output adapter + */ +public class MQTTEventAdapterFactory extends OutputEventAdapterFactory { + private ResourceBundle resourceBundle = + ResourceBundle.getBundle("org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.i18n.Resources", Locale.getDefault()); + + @Override + public String getType() { + return MQTTEventAdapterConstants.ADAPTER_TYPE_MQTT; + } + + @Override + public List getSupportedMessageFormats() { + List supportedMessageFormats = new ArrayList(); + supportedMessageFormats.add(MessageType.XML); + supportedMessageFormats.add(MessageType.JSON); + supportedMessageFormats.add(MessageType.TEXT); + return supportedMessageFormats; + } + + @Override + public List getStaticPropertyList() { + + List staticPropertyList = new ArrayList(); + //Broker Url + Property brokerUrl = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_URL); + brokerUrl.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_URL)); + brokerUrl.setRequired(true); + brokerUrl.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_URL_HINT)); + + //Broker Username + Property userName = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME); + userName.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME)); + userName.setRequired(true); + userName.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME_HINT)); + + //Broker dcr URL + Property dcrUrl = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL); + dcrUrl.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL)); + dcrUrl.setRequired(true); + dcrUrl.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_DCR_URL_HINT)); + + //Broker Connection Scopes + Property scopes = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES); + scopes.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES)); + scopes.setRequired(true); + scopes.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_SCOPES_HINT)); + + // set clientId + Property clientId = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_CLIENTID); + clientId.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CLIENTID)); + clientId.setRequired(false); + clientId.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CLIENTID_HINT)); + staticPropertyList.add(clientId); + + //Broker clear session + Property clearSession = new Property(MQTTEventAdapterConstants.ADAPTER_CONF_CLEAN_SESSION); + clearSession.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CLEAN_SESSION)); + clearSession.setRequired(false); + clearSession.setOptions(new String[]{"true", "false"}); + clearSession.setDefaultValue("true"); + clearSession.setHint(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CLEAN_SESSION_HINT)); + + // set Quality of Service + Property qos = new Property(MQTTEventAdapterConstants.ADAPTER_MESSAGE_QOS); + qos.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_MESSAGE_QOS)); + qos.setRequired(true); + qos.setOptions(new String[]{"0", "1", "2"}); + qos.setDefaultValue("1"); + + staticPropertyList.add(brokerUrl); + staticPropertyList.add(userName); + staticPropertyList.add(dcrUrl); + staticPropertyList.add(scopes); + staticPropertyList.add(clearSession); + staticPropertyList.add(qos); + return staticPropertyList; + } + + @Override + public List getDynamicPropertyList() { + List dynamicPropertyList = new ArrayList(); + // set topic + Property topicProperty = new Property(MQTTEventAdapterConstants.ADAPTER_MESSAGE_TOPIC); + topicProperty.setDisplayName(resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_MESSAGE_TOPIC)); + topicProperty.setRequired(true); + dynamicPropertyList.add(topicProperty); + return dynamicPropertyList; + } + + @Override + public String getUsageTips() { + return null; + } + + @Override + public OutputEventAdapter createEventAdapter(OutputEventAdapterConfiguration eventAdapterConfiguration, + Map globalProperties) { + return new MQTTEventAdapter(eventAdapterConfiguration, globalProperties); + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/internal/MQTTEventAdapterServiceComponent.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/internal/MQTTEventAdapterServiceComponent.java new file mode 100644 index 000000000..97a95f27c --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/internal/MQTTEventAdapterServiceComponent.java @@ -0,0 +1,51 @@ +/* +* 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.output.adapter.mqtt.internal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.service.component.ComponentContext; +import org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.MQTTEventAdapterFactory; +import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterFactory; + + +/** + * @scr.component component.name="output.Mqtt.AdapterService.component" immediate="true" + */ +public class MQTTEventAdapterServiceComponent { + + private static final Log log = LogFactory.getLog(MQTTEventAdapterServiceComponent.class); + + /** + * Deployment of the MQTT event adapter service will be done. + * @param context bundle context where service is registered + */ + protected void activate(ComponentContext context) { + try { + OutputEventAdapterFactory mqttEventAdapterFactory = new MQTTEventAdapterFactory(); + context.getBundleContext().registerService(OutputEventAdapterFactory.class.getName(), + mqttEventAdapterFactory, null); + if (log.isDebugEnabled()) { + log.debug("The MQTT publisher service has been deployed successfully"); + } + } catch (RuntimeException e) { + log.error("Exception occurred when deploying MQTT publisher service", e); + } + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/util/MQTTAdapterPublisher.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/util/MQTTAdapterPublisher.java new file mode 100644 index 000000000..dea1fc73f --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/util/MQTTAdapterPublisher.java @@ -0,0 +1,186 @@ +/* +* 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.output.adapter.mqtt.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttConnectOptions; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.event.output.adapter.core.exception.ConnectionUnavailableException; +import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException; +import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterRuntimeException; +import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; + +/** + * MQTT publisher related configuration initialization and publishing capabilties are implemented here. + */ +public class MQTTAdapterPublisher { + + private static final Log log = LogFactory.getLog(MQTTAdapterPublisher.class); + private MqttClient mqttClient; + private MQTTBrokerConnectionConfiguration mqttBrokerConnectionConfiguration; + String clientId; + + public MQTTAdapterPublisher(MQTTBrokerConnectionConfiguration mqttBrokerConnectionConfiguration, String clientId) { + if (clientId == null || clientId.trim().isEmpty()) { + this.clientId = MqttClient.generateClientId(); + } + this.mqttBrokerConnectionConfiguration = mqttBrokerConnectionConfiguration; + connect(); + } + + public void connect() { + if (clientId == null || clientId.trim().isEmpty()) { + clientId = MqttClient.generateClientId(); + } + boolean cleanSession = mqttBrokerConnectionConfiguration.isCleanSession(); + int keepAlive = mqttBrokerConnectionConfiguration.getKeepAlive(); + String temp_directory = System.getProperty(MQTTEventAdapterConstants.ADAPTER_TEMP_DIRECTORY_NAME); + MqttDefaultFilePersistence dataStore = new MqttDefaultFilePersistence(temp_directory); + try { + MqttConnectOptions connectionOptions = new MqttConnectOptions(); + connectionOptions.setCleanSession(cleanSession); + connectionOptions.setKeepAliveInterval(keepAlive); + if (mqttBrokerConnectionConfiguration.getBrokerUsername() != null) { + connectionOptions.setUserName(getToken(mqttBrokerConnectionConfiguration.getBrokerUsername(), + mqttBrokerConnectionConfiguration.getDcrUrl(), + mqttBrokerConnectionConfiguration.getScopes())); + connectionOptions.setPassword(MQTTEventAdapterConstants.DEFAULT_PASSWORD.toCharArray()); + } + // Construct an MQTT blocking mode client + mqttClient = new MqttClient(mqttBrokerConnectionConfiguration.getBrokerUrl(), clientId, dataStore); + mqttClient.connect(connectionOptions); + + } catch (MqttException e) { + log.error("Error occurred when constructing MQTT client for broker url : " + + mqttBrokerConnectionConfiguration.getBrokerUrl(), e); + handleException(e); + } + } + + public boolean isConnected() { + return mqttClient.isConnected(); + } + + public void publish(int qos, String payload, String topic) { + try { + // Create and configure a message + MqttMessage message = new MqttMessage(payload.getBytes()); + message.setQos(qos); + mqttClient.publish(topic, message); + } catch (MqttException e) { + log.error("Error occurred when publishing message for MQTT server : " + mqttClient.getServerURI(), e); + handleException(e); + } + } + + public void publish(String payload, String topic) { + try { + // Create and configure a message + MqttMessage message = new MqttMessage(payload.getBytes()); + mqttClient.publish(topic, message); + } catch (MqttException e) { + log.error("Error occurred when publishing message for MQTT server : " + mqttClient.getServerURI(), e); + handleException(e); + } + } + + public void close() throws OutputEventAdapterException { + try { + mqttClient.disconnect(1000); + mqttClient.close(); + } catch (MqttException e) { + throw new OutputEventAdapterException(e); + } + } + + private void handleException(MqttException e) { + //Check for Client not connected exception code and throw ConnectionUnavailableException + if (e.getReasonCode() == 32104) { + throw new ConnectionUnavailableException(e); + } else { + throw new OutputEventAdapterRuntimeException(e); + } + } + + private String getToken(String username, String dcrUrlString, String scopes) { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + if (dcrUrlString != null && !dcrUrlString.isEmpty()) { + try { + URL dcrUrl = new URL(dcrUrlString); + HttpClient httpClient = MQTTUtil.getHttpClient(dcrUrl.getProtocol()); + HttpPost postMethod = new HttpPost(dcrUrlString); + RegistrationProfile registrationProfile = new RegistrationProfile(); + registrationProfile.setCallbackUrl(MQTTEventAdapterConstants.DEFAULT_CALLBACK); + registrationProfile.setGrantType(MQTTEventAdapterConstants.GRANT_TYPE); + registrationProfile.setOwner(username); + registrationProfile.setTokenScope(MQTTEventAdapterConstants.TOKEN_SCOPE); + registrationProfile.setApplicationType(MQTTEventAdapterConstants.APPLICATION_TYPE); + registrationProfile.setClientName(username + "_" + tenantId); + String jsonString = registrationProfile.toJSON(); + StringEntity requestEntity = new StringEntity(jsonString, ContentType.APPLICATION_JSON); + postMethod.setEntity(requestEntity); + HttpResponse httpResponse = httpClient.execute(postMethod); + String response = MQTTUtil.getResponseString(httpResponse); + try { + JSONParser jsonParser = new JSONParser(); + JSONObject jsonPayload = (JSONObject) jsonParser.parse(response); + String clientId = (String) jsonPayload.get(MQTTEventAdapterConstants.CLIENT_ID); + String clientSecret = (String) jsonPayload.get(MQTTEventAdapterConstants.CLIENT_SECRET); + JWTClientManagerService jwtClientManagerService = MQTTUtil.getJWTClientManagerService(); + AccessTokenInfo accessTokenInfo = jwtClientManagerService.getJWTClient().getAccessToken( + clientId, clientSecret, username, scopes); + return accessTokenInfo.getAccessToken(); + } catch (ParseException e) { + String msg = "error occurred while parsing client credential payload"; + throw new OutputEventAdapterRuntimeException(msg, e); + } catch (JWTClientException e) { + String msg = "error occurred while parsing the response from JWT Client"; + throw new OutputEventAdapterRuntimeException(msg, e); + } + } catch (MalformedURLException e) { + throw new OutputEventAdapterRuntimeException("Invalid dcrUrl : " + dcrUrlString); + } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | IOException e) { + throw new OutputEventAdapterRuntimeException("Failed to create an https connection.", e); + } + } + throw new OutputEventAdapterRuntimeException("Invalid configuration for mqtt publisher"); + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/util/MQTTBrokerConnectionConfiguration.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/util/MQTTBrokerConnectionConfiguration.java new file mode 100644 index 000000000..cfee72579 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/util/MQTTBrokerConnectionConfiguration.java @@ -0,0 +1,65 @@ +/* +* 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.output.adapter.mqtt.util; + +public class MQTTBrokerConnectionConfiguration { + + private String brokerUsername; + private String dcrUrl; + private String scopes; + private String brokerUrl; + private boolean cleanSession = true; + private int keepAlive; + + public String getDcrUrl() { + return dcrUrl; + } + + public String getScopes() { + return scopes; + } + + public String getBrokerUsername() { + return brokerUsername; + } + + public boolean isCleanSession() { + return cleanSession; + } + + public String getBrokerUrl() { + return brokerUrl; + } + + public int getKeepAlive() { + return keepAlive; + } + + public MQTTBrokerConnectionConfiguration(String brokerUrl, String brokerUsername, + String dcrUrl, String scopes, int keepAlive, String cleanSession) { + this.brokerUsername = brokerUsername; + this.dcrUrl = dcrUrl; + this.scopes = scopes; + this.brokerUrl = brokerUrl; + this.keepAlive = keepAlive; + if (cleanSession != null) { + this.cleanSession = Boolean.parseBoolean(cleanSession); + } + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/util/MQTTEventAdapterConstants.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/util/MQTTEventAdapterConstants.java new file mode 100644 index 000000000..194a99f7b --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/util/MQTTEventAdapterConstants.java @@ -0,0 +1,61 @@ +/* +* 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.output.adapter.mqtt.util; + + +public final class MQTTEventAdapterConstants { + + private MQTTEventAdapterConstants() { + } + + public static final String ADAPTER_TYPE_MQTT = "oauth-mqtt"; + public static final String ADAPTER_CONF_URL = "url"; + public static final String ADAPTER_CONF_USERNAME = "username"; + public static final String ADAPTER_CONF_USERNAME_HINT = "username.hint"; + public static final String ADAPTER_CONF_DCR_URL = "dcrUrl"; + public static final String ADAPTER_CONF_DCR_URL_HINT = "dcrUrl.hint"; + public static final String ADAPTER_CONF_SCOPES = "scopes"; + public static final String ADAPTER_CONF_SCOPES_HINT = "scopes.hint"; + public static final String ADAPTER_CONF_URL_HINT = "url.hint"; + public static final String ADAPTER_MESSAGE_TOPIC = "topic"; + public static final String ADAPTER_MESSAGE_QOS = "qos"; + public static final String ADAPTER_CONF_CLEAN_SESSION = "cleanSession"; + public static final String ADAPTER_CONF_CLEAN_SESSION_HINT = "cleanSession.hint"; + public static final String CONNECTION_KEEP_ALIVE_INTERVAL = "connectionKeepAliveInterval"; + public static final int DEFAULT_CONNECTION_KEEP_ALIVE_INTERVAL = 60; + public static final String ADAPTER_TEMP_DIRECTORY_NAME = "java.io.tmpdir"; + public static final String ADAPTER_CONF_CLIENTID = "clientId"; + public static final String ADAPTER_CONF_CLIENTID_HINT = "clientId.hint"; + + public static final int DEFAULT_MIN_THREAD_POOL_SIZE = 8; + public static final int DEFAULT_MAX_THREAD_POOL_SIZE = 100; + public static final int DEFAULT_EXECUTOR_JOB_QUEUE_SIZE = 2000; + public static final long DEFAULT_KEEP_ALIVE_TIME_IN_MILLIS = 20000; + public static final String ADAPTER_MIN_THREAD_POOL_SIZE_NAME = "minThread"; + public static final String ADAPTER_MAX_THREAD_POOL_SIZE_NAME = "maxThread"; + public static final String ADAPTER_KEEP_ALIVE_TIME_NAME = "keepAliveTimeInMillis"; + public static final String ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME = "jobQueueSize"; + + public static final String DEFAULT_CALLBACK = ""; + public static final String DEFAULT_PASSWORD = ""; + public static final String GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer refresh_token"; + public static final String TOKEN_SCOPE = "production"; + public static final String APPLICATION_TYPE = "device"; + public static final String CLIENT_ID = "client_id"; + public static final String CLIENT_SECRET = "client_secret"; +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/util/MQTTUtil.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/util/MQTTUtil.java new file mode 100644 index 000000000..636c133ed --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/util/MQTTUtil.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLContextBuilder; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; + +/** + * This is the utility class that is used for MQTT input adapter. + */ +public class MQTTUtil { + private static final String HTTPS_PROTOCOL = "https"; + private static final Log log = LogFactory.getLog(MQTTUtil.class); + + /** + * Return a http client instance + * @param protocol- service endpoint protocol http/https + * @return + */ + public static HttpClient getHttpClient(String protocol) + throws IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException { + HttpClient httpclient; + if (HTTPS_PROTOCOL.equals(protocol)) { + SSLContextBuilder builder = new SSLContextBuilder(); + builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); + SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build()); + httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); + } else { + httpclient = HttpClients.createDefault(); + } + return httpclient; + } + + public static String getResponseString(HttpResponse httpResponse) throws IOException { + BufferedReader br = null; + try { + br = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent())); + String readLine; + String response = ""; + while (((readLine = br.readLine()) != null)) { + response += readLine; + } + return response; + } finally { + EntityUtils.consumeQuietly(httpResponse.getEntity()); + if (br != null) { + try { + br.close(); + } catch (IOException e) { + log.warn("Error while closing the connection! " + e.getMessage()); + } + } + } + } + + public static JWTClientManagerService getJWTClientManagerService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + JWTClientManagerService jwtClientManagerService = + (JWTClientManagerService) ctx.getOSGiService(JWTClientManagerService.class, null); + if (jwtClientManagerService == null) { + String msg = "JWT management service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return jwtClientManagerService; + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/util/RegistrationProfile.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/util/RegistrationProfile.java new file mode 100644 index 000000000..aca25c9a3 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/util/RegistrationProfile.java @@ -0,0 +1,73 @@ +package org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.util; + +/** + * This class represents the data that are required to register + * the oauth application. + */ +public class RegistrationProfile { + + private String callbackUrl; + private String clientName; + private String tokenScope; + private String owner; + private String grantType; + private String applicationType; + + private static final String TAG = RegistrationProfile.class.getSimpleName(); + + public String getCallbackUrl() { + return callbackUrl; + } + + public void setCallbackUrl(String callBackUrl) { + this.callbackUrl = callBackUrl; + } + + public String getClientName() { + return clientName; + } + + public void setClientName(String clientName) { + this.clientName = clientName; + } + + public String getTokenScope() { + return tokenScope; + } + + public void setTokenScope(String tokenScope) { + this.tokenScope = tokenScope; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public String getGrantType() { + return grantType; + } + + public void setGrantType(String grantType) { + this.grantType = grantType; + } + + public String getApplicationType() { + return applicationType; + } + + public void setApplicationType(String applicationType) { + this.applicationType = applicationType; + } + + public String toJSON() { + String jsonString = + "{\"callbackUrl\": \"" + callbackUrl + "\",\"clientName\": \"" + clientName + "\", \"tokenScope\": " + + "\"" + tokenScope + "\", \"owner\": \"" + owner + "\"," + "\"grantType\": \"" + grantType + + "\", \"saasApp\" :false }\n"; + return jsonString; + } +} \ No newline at end of file diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/resources/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/i18n/Resources.properties b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/resources/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/i18n/Resources.properties new file mode 100644 index 000000000..c73a259ef --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.mqtt/src/main/resources/org/wso2/carbon/device/mgt/iot/output/adapter/mqtt/i18n/Resources.properties @@ -0,0 +1,33 @@ +# +# 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. +# + +topic=Topic +url=Broker Url +username=Username +username.hint=Username of the broker +dcrUrl=dcrUrl +dcrUrl.hint=Dynamic Client Registration Url +scopes=scopes +scopes.hint=Scopes that required to connect with the broker. +url.hint=MQTT broker url +cleanSession=Clean Session +cleanSession.hint=Persist topic subscriptions and ack positions across client sessions +keepAlive=Keep Alive (In seconds) +qos=Quality of Service +clientId=Client Id +clientId.hint=client identifier is used by the server to identify a client when it reconnects, It used for durable subscriptions or reliable delivery of messages is required. diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/pom.xml b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/pom.xml new file mode 100644 index 000000000..e991fa1b6 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/pom.xml @@ -0,0 +1,107 @@ + + + + + iot-base-plugin + org.wso2.carbon.devicemgt-plugins + 2.1.0-SNAPSHOT + ../pom.xml + + 4.0.0 + org.wso2.carbon.device.mgt.iot.output.adapter.xmpp + + bundle + WSO2 Carbon - Device Mgt Output MQTT Adaptor Module + org.wso2.carbon.device.mgt.iot.output.adapter.xmpp provides the back-end functionality of xmpp adaptor + + http://wso2.org + + + + org.wso2.carbon.analytics-common + org.wso2.carbon.event.output.adapter.core + + + org.wso2.carbon + org.wso2.carbon.core + + + org.wso2.carbon + org.wso2.carbon.logging + + + org.igniterealtime.smack.wso2 + smack + + + org.igniterealtime.smack.wso2 + smackx + + + + + + org.apache.felix + maven-scr-plugin + + + generate-scr-descriptor + + scr + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.artifactId} + ${project.artifactId} + + org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.internal, + org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.internal.* + + + !org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.internal, + !org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.internal.*, + org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.*, + + + org.wso2.carbon.event.output.adapter.core, + org.wso2.carbon.event.output.adapter.core.*, + org.jivesoftware.smack.*, + org.apache.commons.logging, + org.osgi.framework, + org.osgi.service.component, + org.wso2.carbon.context + + + + + + + \ No newline at end of file diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/XMPPEventAdapter.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/XMPPEventAdapter.java new file mode 100644 index 000000000..d90c8e5c1 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/XMPPEventAdapter.java @@ -0,0 +1,200 @@ +/* +* 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.output.adapter.xmpp; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.util.XMPPEventAdapterConstants; +import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.util.XMPPAdapterPublisher; +import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.util.XMPPServerConnectionConfiguration; +import org.wso2.carbon.event.output.adapter.core.EventAdapterUtil; +import org.wso2.carbon.event.output.adapter.core.OutputEventAdapter; +import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration; +import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException; +import org.wso2.carbon.event.output.adapter.core.exception.TestConnectionNotSupportedException; + +import java.util.Map; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Output XMPPEventAdapter will be used to publish events with MQTT protocol to specified broker and topic. + */ +public class XMPPEventAdapter implements OutputEventAdapter { + + private OutputEventAdapterConfiguration eventAdapterConfiguration; + private Map globalProperties; + private XMPPAdapterPublisher xmppAdapterPublisher; + private static ThreadPoolExecutor threadPoolExecutor; + private static final Log log = LogFactory.getLog(XMPPEventAdapter.class); + private int tenantId; + + public XMPPEventAdapter(OutputEventAdapterConfiguration eventAdapterConfiguration, + Map globalProperties) { + this.eventAdapterConfiguration = eventAdapterConfiguration; + this.globalProperties = globalProperties; + } + + @Override + public void init() throws OutputEventAdapterException { + tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + //ThreadPoolExecutor will be assigned if it is null + if (threadPoolExecutor == null) { + int minThread; + int maxThread; + int jobQueSize; + long defaultKeepAliveTime; + //If global properties are available those will be assigned else constant values will be assigned + if (globalProperties.get(XMPPEventAdapterConstants.ADAPTER_MIN_THREAD_POOL_SIZE_NAME) != null) { + minThread = Integer.parseInt(globalProperties.get( + XMPPEventAdapterConstants.ADAPTER_MIN_THREAD_POOL_SIZE_NAME)); + } else { + minThread = XMPPEventAdapterConstants.DEFAULT_MIN_THREAD_POOL_SIZE; + } + + if (globalProperties.get(XMPPEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE_NAME) != null) { + maxThread = Integer.parseInt(globalProperties.get( + XMPPEventAdapterConstants.ADAPTER_MAX_THREAD_POOL_SIZE_NAME)); + } else { + maxThread = XMPPEventAdapterConstants.DEFAULT_MAX_THREAD_POOL_SIZE; + } + + if (globalProperties.get(XMPPEventAdapterConstants.ADAPTER_KEEP_ALIVE_TIME_NAME) != null) { + defaultKeepAliveTime = Integer.parseInt(globalProperties.get( + XMPPEventAdapterConstants.ADAPTER_KEEP_ALIVE_TIME_NAME)); + } else { + defaultKeepAliveTime = XMPPEventAdapterConstants.DEFAULT_KEEP_ALIVE_TIME_IN_MILLIS; + } + + if (globalProperties.get(XMPPEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME) != null) { + jobQueSize = Integer.parseInt(globalProperties.get( + XMPPEventAdapterConstants.ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME)); + } else { + jobQueSize = XMPPEventAdapterConstants.DEFAULT_EXECUTOR_JOB_QUEUE_SIZE; + } + + threadPoolExecutor = new ThreadPoolExecutor(minThread, maxThread, defaultKeepAliveTime, + TimeUnit.MILLISECONDS, new LinkedBlockingQueue( + jobQueSize)); + } + } + + @Override + public void testConnect() throws TestConnectionNotSupportedException { + throw new TestConnectionNotSupportedException("Test connection is not available"); + } + + @Override + public void connect() { + int xmppPort = XMPPEventAdapterConstants.DEFAULT_XMPP_PORT; + String xmppPortString = eventAdapterConfiguration.getStaticProperties() + .get(XMPPEventAdapterConstants.ADAPTER_CONF_PORT); + if (xmppPortString != null && !xmppPortString.trim().isEmpty()) { + xmppPort = Integer.parseInt(xmppPortString); + } + int timeoutInterval = XMPPEventAdapterConstants.DEFAULT_TIMEOUT_INTERVAL; + String timeoutIntervalString = eventAdapterConfiguration.getStaticProperties().get( + XMPPEventAdapterConstants.ADAPTER_CONF_TIMEOUT_INTERVAL); + if (timeoutIntervalString != null && !timeoutIntervalString.trim().isEmpty()) { + timeoutInterval = Integer.parseInt(timeoutIntervalString); + } + XMPPServerConnectionConfiguration xmppServerConnectionConfiguration = + new XMPPServerConnectionConfiguration(eventAdapterConfiguration.getStaticProperties() + .get(XMPPEventAdapterConstants.ADAPTER_CONF_HOST), + xmppPort, + eventAdapterConfiguration.getStaticProperties() + .get(XMPPEventAdapterConstants.ADAPTER_CONF_USERNAME), + eventAdapterConfiguration.getStaticProperties() + .get(XMPPEventAdapterConstants.ADAPTER_CONF_PASSWORD), + timeoutInterval, + eventAdapterConfiguration.getStaticProperties() + .get(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE) + ); + xmppAdapterPublisher = new XMPPAdapterPublisher(xmppServerConnectionConfiguration); + } + + @Override + public void publish(Object message, Map dynamicProperties) { + String jid = dynamicProperties.get(XMPPEventAdapterConstants.ADAPTER_CONF_JID); + String subject = dynamicProperties.get(XMPPEventAdapterConstants.ADAPTER_CONF_SUBJECT); + String messageType = dynamicProperties.get(XMPPEventAdapterConstants.ADAPTER_CONF_MESSAGETYPE); + try { + threadPoolExecutor.submit(new XMPPSender(jid, subject, (String)message, messageType)); + } catch (RejectedExecutionException e) { + EventAdapterUtil.logAndDrop(eventAdapterConfiguration.getName(), message, "Job queue is full", e, log, + tenantId); + } + } + + @Override + public void disconnect() { + try { + if (xmppAdapterPublisher != null) { + xmppAdapterPublisher.close(); + xmppAdapterPublisher = null; + } + } catch (OutputEventAdapterException e) { + log.error("Exception when closing the mqtt publisher connection on Output MQTT Adapter '" + + eventAdapterConfiguration.getName() + "'", e); + } + } + + @Override + public void destroy() { + //not required + } + + @Override + public boolean isPolled() { + return false; + } + + class XMPPSender implements Runnable { + + String jid; + String subject; + String message; + String messageType; + + XMPPSender(String jid, String subject, String message, String messageType) { + this.jid = jid; + this.message = message; + this.subject = subject; + this.messageType = messageType; + } + + @Override + public void run() { + try { + if (!xmppAdapterPublisher.isConnected()) { + synchronized (XMPPEventAdapter.class) { + if (!xmppAdapterPublisher.isConnected()) { + xmppAdapterPublisher.connect(); + } + } + } + xmppAdapterPublisher.publish(jid, subject, message, messageType); + } catch (Throwable t) { + EventAdapterUtil.logAndDrop(eventAdapterConfiguration.getName(), message, null, t, log, tenantId); + } + } + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/XMPPEventAdapterFactory.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/XMPPEventAdapterFactory.java new file mode 100644 index 000000000..8ffa169f2 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/XMPPEventAdapterFactory.java @@ -0,0 +1,132 @@ +/* +* 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.output.adapter.xmpp; + +import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.util.XMPPEventAdapterConstants; +import org.wso2.carbon.event.output.adapter.core.*; + +import java.util.*; + +/** + * The xmpp event adapter factory class to create a xmpp output adapter + */ +public class XMPPEventAdapterFactory extends OutputEventAdapterFactory { + private ResourceBundle resourceBundle = + ResourceBundle.getBundle("org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.Resources", Locale.getDefault()); + + @Override + public String getType() { + return XMPPEventAdapterConstants.ADAPTER_TYPE_XMPP; + } + + @Override + public List getSupportedMessageFormats() { + List supportedMessageFormats = new ArrayList(); + supportedMessageFormats.add(MessageType.XML); + supportedMessageFormats.add(MessageType.JSON); + supportedMessageFormats.add(MessageType.TEXT); + return supportedMessageFormats; + } + + @Override + public List getStaticPropertyList() { + + List staticPropertyList = new ArrayList(); + // Url + Property host = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_HOST); + host.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_HOST)); + host.setRequired(true); + host.setHint(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_HOST_HINT)); + + // Host Port + Property port = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_PORT); + port.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_PORT)); + port.setRequired(true); + port.setHint(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_PORT_HINT)); + + //Broker Username + Property userName = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_USERNAME); + userName.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_USERNAME)); + userName.setRequired(true); + userName.setHint(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_USERNAME_HINT)); + + //Broker Password + Property password = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_PASSWORD); + password.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_PASSWORD)); + password.setRequired(true); + password.setHint(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_PASSWORD_HINT)); + + //Timeout Interval + Property timooutInterval = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_TIMEOUT_INTERVAL); + timooutInterval.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_TIMEOUT_INTERVAL_HINT)); + timooutInterval.setRequired(false); + timooutInterval.setHint(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_TIMEOUT_INTERVAL_HINT)); + + //Resource + Property resource = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE); + resource.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE)); + resource.setRequired(false); + resource.setHint(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE_HINT)); + + staticPropertyList.add(host); + staticPropertyList.add(port); + staticPropertyList.add(userName); + staticPropertyList.add(password); + staticPropertyList.add(timooutInterval); + staticPropertyList.add(resource); + return staticPropertyList; + } + + @Override + public List getDynamicPropertyList() { + List dynamicPropertyList = new ArrayList(); + // set topic + Property jidProperty = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_JID); + jidProperty.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_JID_HINT)); + jidProperty.setRequired(true); + + Property subjectProperty = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_SUBJECT); + subjectProperty.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_SUBJECT_HINT)); + subjectProperty.setRequired(false); + + Property messageType = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_MESSAGETYPE); + messageType.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_MESSAGETYPE_HINT)); + messageType.setRequired(true); + messageType.setOptions( + new String[]{XMPPEventAdapterConstants.MessageType.CHAT, XMPPEventAdapterConstants.MessageType.ERROR, + XMPPEventAdapterConstants.MessageType.GROUP_CHAT, XMPPEventAdapterConstants.MessageType.NORMAL, + XMPPEventAdapterConstants.MessageType.HEADLINE}); + messageType.setDefaultValue(XMPPEventAdapterConstants.MessageType.NORMAL); + + dynamicPropertyList.add(jidProperty); + dynamicPropertyList.add(subjectProperty); + dynamicPropertyList.add(messageType); + return dynamicPropertyList; + } + + @Override + public String getUsageTips() { + return null; + } + + @Override + public OutputEventAdapter createEventAdapter(OutputEventAdapterConfiguration eventAdapterConfiguration, + Map globalProperties) { + return new XMPPEventAdapter(eventAdapterConfiguration, globalProperties); + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/internal/XMPPEventAdapterServiceComponent.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/internal/XMPPEventAdapterServiceComponent.java new file mode 100644 index 000000000..c8d1806ed --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/internal/XMPPEventAdapterServiceComponent.java @@ -0,0 +1,51 @@ +/* +* 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.output.adapter.xmpp.internal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.service.component.ComponentContext; +import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.XMPPEventAdapterFactory; +import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterFactory; + + +/** + * @scr.component component.name="output.XMPP.AdapterService.component" immediate="true" + */ +public class XMPPEventAdapterServiceComponent { + + private static final Log log = LogFactory.getLog(XMPPEventAdapterServiceComponent.class); + + /** + * Deployment of the XMPP event adapter service will be done. + * @param context bundle context where service is registered + */ + protected void activate(ComponentContext context) { + try { + OutputEventAdapterFactory xmppEventAdapterFactory = new XMPPEventAdapterFactory(); + context.getBundleContext().registerService(OutputEventAdapterFactory.class.getName(), + xmppEventAdapterFactory, null); + if (log.isDebugEnabled()) { + log.debug("The XMPP publisher service has been deployed successfully"); + } + } catch (RuntimeException e) { + log.error("Exception occurred when deploying XMPP publisher service", e); + } + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/util/XMPPAdapterPublisher.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/util/XMPPAdapterPublisher.java new file mode 100644 index 000000000..8ed9fcc3f --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/util/XMPPAdapterPublisher.java @@ -0,0 +1,106 @@ +/* +* 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.output.adapter.xmpp.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jivesoftware.smack.ConnectionConfiguration; +import org.jivesoftware.smack.SmackConfiguration; +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.packet.Message; +import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException; +import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterRuntimeException; + +/** + * XMPP publisher related configuration initialization and publishing capabilties are implemented here. + */ +public class XMPPAdapterPublisher { + + private static final Log log = LogFactory.getLog(XMPPAdapterPublisher.class); + private XMPPServerConnectionConfiguration xmppServerConnectionConfiguration; + XMPPConnection xmppConnection; + + public XMPPAdapterPublisher(XMPPServerConnectionConfiguration xmppServerConnectionConfiguration) { + this.xmppServerConnectionConfiguration = xmppServerConnectionConfiguration; + connect(); + } + + public void connect() { + SmackConfiguration.setPacketReplyTimeout(xmppServerConnectionConfiguration.getTimeoutInterval()); + ConnectionConfiguration config = new ConnectionConfiguration(xmppServerConnectionConfiguration.getHost(), + xmppServerConnectionConfiguration.getPort()); + config.setSASLAuthenticationEnabled(false); + config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled); + xmppConnection = new XMPPConnection(config); + String resource = xmppServerConnectionConfiguration.getResource(); + String username = xmppServerConnectionConfiguration.getUsername(); + String password = xmppServerConnectionConfiguration.getPassword(); + try { + xmppConnection.connect(); + if (resource == null || resource.trim().isEmpty()) { + xmppConnection.login(username, password); + } else { + xmppConnection.login(username, password, resource); + } + } catch (XMPPException e) { + String errorMsg = "Login attempt to the XMPP Server with username - " + username + " failed."; + log.info(errorMsg); + throw new OutputEventAdapterRuntimeException(errorMsg, e); + } + } + + public boolean isConnected() { + return xmppConnection.isConnected(); + } + + public void publish(String JID, String subject, String message, String messageType) { + Message xmppMessage = new Message(); + xmppMessage.setTo(JID); + xmppMessage.setSubject(subject); + xmppMessage.setBody(message); + if (messageType != null) { + switch (messageType) { + case XMPPEventAdapterConstants.MessageType.CHAT: + xmppMessage.setType(Message.Type.chat); + break; + case XMPPEventAdapterConstants.MessageType.GROUP_CHAT: + xmppMessage.setType(Message.Type.groupchat); + break; + case XMPPEventAdapterConstants.MessageType.ERROR: + xmppMessage.setType(Message.Type.error); + break; + case XMPPEventAdapterConstants.MessageType.HEADLINE: + xmppMessage.setType(Message.Type.headline); + break; + default: + xmppMessage.setType(Message.Type.normal); + } + } else { + xmppMessage.setType(Message.Type.normal); + } + xmppConnection.sendPacket(xmppMessage); + } + + public void close() throws OutputEventAdapterException { + if (xmppConnection != null && isConnected()) { + xmppConnection.disconnect(); + } + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/util/XMPPEventAdapterConstants.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/util/XMPPEventAdapterConstants.java new file mode 100644 index 000000000..9db36385c --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/util/XMPPEventAdapterConstants.java @@ -0,0 +1,71 @@ +/* +* 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.output.adapter.xmpp.util; + + +public final class XMPPEventAdapterConstants { + + private XMPPEventAdapterConstants() { + } + + public static final String ADAPTER_TYPE_XMPP = "xmpp"; + + //dynamic properties + public static final String ADAPTER_CONF_JID = "jid"; + public static final String ADAPTER_CONF_JID_HINT = "jid.hint"; + public static final String ADAPTER_CONF_SUBJECT = "subject"; + public static final String ADAPTER_CONF_SUBJECT_HINT = "subject.hint"; + public static final String ADAPTER_CONF_MESSAGETYPE = "messageType"; + public static final String ADAPTER_CONF_MESSAGETYPE_HINT = "messageType.hint"; + + //static properties + public static final String ADAPTER_CONF_HOST = "host"; + public static final String ADAPTER_CONF_HOST_HINT = "host.hint"; + public static final String ADAPTER_CONF_PORT = "port"; + public static final String ADAPTER_CONF_PORT_HINT = "port.hint"; + public static final String ADAPTER_CONF_USERNAME = "username"; + public static final String ADAPTER_CONF_USERNAME_HINT = "username.hint"; + public static final String ADAPTER_CONF_PASSWORD = "password"; + public static final String ADAPTER_CONF_PASSWORD_HINT = "password.hint"; + public static final String ADAPTER_CONF_RESOURCE = "resource"; + public static final String ADAPTER_CONF_RESOURCE_HINT = "resource.hint"; + public static final String ADAPTER_CONF_TIMEOUT_INTERVAL = "timeoutInterval"; + public static final String ADAPTER_CONF_TIMEOUT_INTERVAL_HINT = "timeoutInterval.hint"; + public static final int DEFAULT_XMPP_PORT = 5222; + public static final int DEFAULT_TIMEOUT_INTERVAL = 5000; + + //global properties + public static final int DEFAULT_MIN_THREAD_POOL_SIZE = 8; + public static final int DEFAULT_MAX_THREAD_POOL_SIZE = 100; + public static final int DEFAULT_EXECUTOR_JOB_QUEUE_SIZE = 2000; + public static final long DEFAULT_KEEP_ALIVE_TIME_IN_MILLIS = 20000; + public static final String ADAPTER_MIN_THREAD_POOL_SIZE_NAME = "minThread"; + public static final String ADAPTER_MAX_THREAD_POOL_SIZE_NAME = "maxThread"; + public static final String ADAPTER_KEEP_ALIVE_TIME_NAME = "keepAliveTimeInMillis"; + public static final String ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME = "jobQueueSize"; + + public static final class MessageType { + public static final String NORMAL = "normal"; + public static final String CHAT = "chat"; + public static final String GROUP_CHAT = "groupchat"; + public static final String HEADLINE = "headline"; + public static final String ERROR = "error"; + + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/util/XMPPServerConnectionConfiguration.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/util/XMPPServerConnectionConfiguration.java new file mode 100644 index 000000000..51e696e20 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/util/XMPPServerConnectionConfiguration.java @@ -0,0 +1,63 @@ +/* +* 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.output.adapter.xmpp.util; + +public class XMPPServerConnectionConfiguration { + + private String host; + private int port; + private String username; + private String password; + private int timeoutInterval; + private String resource; + + public String getHost() { + return host; + } + + public int getPort() { + return port; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public int getTimeoutInterval() { + return timeoutInterval; + } + + public String getResource() { + return resource; + } + + public XMPPServerConnectionConfiguration(String host, int port, String username, String password, + int timeoutInterval, String resource) { + this.host = host; + this.port = port; + this.username = username; + this.password = password; + this.timeoutInterval = timeoutInterval; + this.resource = resource; + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/resources/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/i18n/Resources.properties b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/resources/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/i18n/Resources.properties new file mode 100644 index 000000000..9b4b33d90 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.output.adapter.xmpp/src/main/resources/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/i18n/Resources.properties @@ -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. +# + +host=Server Url +host.hint=XMPP Server url +port=Server Port +port.hint=Server Port Number +username=Username +username.hint=Username of the broker +password=Password +password.hint=Password to connect to the server. +timeoutInterval=Time out Interval +timeoutInterval.hint=used by listeners to the server and for reconnection schedules. +resource=Resource +resource.hint=specific to the XMPP-Account to which the login is made to. +jid=JID +jid.hint=the JID (XMPP Account ID) to which the message is to be sent to. +subject=Subject +subject.hint=Subject of the message. +messageType=Message Type +messageType.hint=Type of the XMPP Message (chat, groupchat, error, headline, normal) diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.ui/src/main/resources/jaggeryapps/devicemgt/app/units/iot.unit.ui.header.logo/logo.json b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.ui/src/main/resources/jaggeryapps/devicemgt/app/units/iot.unit.ui.header.logo/logo.json index 4e30bc074..98b47e9b8 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.ui/src/main/resources/jaggeryapps/devicemgt/app/units/iot.unit.ui.header.logo/logo.json +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.ui/src/main/resources/jaggeryapps/devicemgt/app/units/iot.unit.ui.header.logo/logo.json @@ -1,5 +1,5 @@ { "version": "1.0.0", "index": 29, - "extends": "mdm.unit.ui.header.logo" + "extends": "cdmf.unit.ui.header.logo" } \ No newline at end of file diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/pom.xml b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/pom.xml index 76c09c753..f7fa1c235 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/pom.xml +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/pom.xml @@ -63,28 +63,15 @@ IoT Server Impl Bundle org.wso2.carbon.device.mgt.iot.internal - org.jivesoftware.smack.*, - javax.xml.namespace;resolution:=optional, - javax.xml.validation;resolution:=optional, - org.apache.commons.codec.binary, - org.apache.http.*, - org.apache.commons.io.*, - org.apache.commons.logging.*, - org.json;version="${commons-json.version}", org.wso2.carbon.base.*, org.osgi.framework, org.osgi.service.component, - javax.xml.bind.*;resolution:=optional, - javax.xml.parsers.*;resolution:=optional, - javax.crypto, - org.apache.tomcat.util.codec.binary, - org.w3c.dom;resolution:=optional, - org.wso2.carbon.core;version="${carbon.kernel.version.range}", - org.wso2.carbon.utils.*;version="${carbon.kernel.version.range}", - org.wso2.carbon.device.mgt.common.*, - org.eclipse.paho.client.mqttv3.*;version="${eclipse.paho.version}", - javax.xml;resolution:=optional, - javax.net.ssl;resolution:=optional + org.apache.axis2.context, + org.apache.commons.io, + org.apache.commons.logging, + org.wso2.carbon.core, + org.wso2.carbon.device.mgt.common, + org.wso2.carbon.utils !org.wso2.carbon.device.mgt.iot.internal, diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/config/server/DeviceManagementConfigurationManager.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/config/server/DeviceManagementConfigurationManager.java deleted file mode 100644 index 00774a3cf..000000000 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/config/server/DeviceManagementConfigurationManager.java +++ /dev/null @@ -1,118 +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.config.server; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.w3c.dom.Document; -import org.wso2.carbon.device.mgt.iot.config.server.datasource.ControlQueue; -import org.wso2.carbon.device.mgt.iot.config.server.datasource.DeviceManagementConfiguration; -import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException; -import org.wso2.carbon.device.mgt.iot.util.IotDeviceManagementUtil; -import org.wso2.carbon.utils.CarbonUtils; -import javax.xml.XMLConstants; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.ValidationEvent; -import javax.xml.bind.ValidationEventHandler; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import java.io.File; -import java.util.List; - -/** - * Class responsible for the iot device manager configuration initialization. - */ -public class DeviceManagementConfigurationManager { - - private static final Log log = LogFactory.getLog(DeviceManagementConfigurationManager.class); - private static final String DEVICE_MGT_CONFIG_XML_NAME = "devicemgt-config.xml"; - private static final String DEVICE_MGT_ROOT_DIRECTORY = "iot"; - private final String XMLCONFIGS_FILE_LOCATION = - CarbonUtils.getCarbonConfigDirPath() + File.separator + - DEVICE_MGT_ROOT_DIRECTORY + File.separator + DEVICE_MGT_CONFIG_XML_NAME; - private static final String IOT_DEVICE_CONFIG_XSD_NAME = "devicemgt-config.xsd"; - private final String XSDCONFIGS_FILE_LOCATION = - CarbonUtils.getCarbonConfigDirPath() + File.separator + - DEVICE_MGT_ROOT_DIRECTORY + File.separator + IOT_DEVICE_CONFIG_XSD_NAME; - private DeviceManagementConfiguration currentDeviceManagementConfiguration; - private static DeviceManagementConfigurationManager deviceConfigurationManager = - new DeviceManagementConfigurationManager(); - - private DeviceManagementConfigurationManager() { - } - - public static DeviceManagementConfigurationManager getInstance() { - return deviceConfigurationManager; - } - - public void initConfig() throws DeviceControllerException { - try { - SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - Schema schema = sf.newSchema(new File(XSDCONFIGS_FILE_LOCATION)); - - File deviceCloudMgtConfig = new File(XMLCONFIGS_FILE_LOCATION); - Document doc = IotDeviceManagementUtil.convertToDocument(deviceCloudMgtConfig); - JAXBContext deviceCloudContext = JAXBContext.newInstance(DeviceManagementConfiguration.class); - Unmarshaller unmarshaller = deviceCloudContext.createUnmarshaller(); - unmarshaller.setSchema(schema); - unmarshaller.setEventHandler(new IotConfigValidationEventHandler()); - this.currentDeviceManagementConfiguration = (DeviceManagementConfiguration) unmarshaller.unmarshal(doc); - } catch (Exception e) { - String error = "Error occurred while initializing DeviceController configurations"; - log.error(error); - throw new DeviceControllerException(error, e); - } - } - - public DeviceManagementConfiguration getDeviceCloudMgtConfig() { - return currentDeviceManagementConfiguration; - } - - public ControlQueue getControlQueue(String name) { - List controlQueues = currentDeviceManagementConfiguration.getControlQueues().getControlQueue(); - if (controlQueues != null) { - for (ControlQueue controlQueue : controlQueues) { - if (controlQueue.getName().equals(name)) { - return controlQueue; - } - } - } - return null; - } - - private class IotConfigValidationEventHandler implements ValidationEventHandler { - @Override - public boolean handleEvent(ValidationEvent event) { - String error = "\nEVENT" + "\nSEVERITY: " + event.getSeverity() - + "\n MESSAGE: " + event.getMessage() - + "\n LINKED EXCEPTION: " + event.getLinkedException() - + "\n LOCATOR" - + "\n LINE NUMBER: " + event.getLocator().getLineNumber() - + "\n COLUMN NUMBER: " + event.getLocator().getColumnNumber() - + "\n OFFSET: " + event.getLocator().getOffset() - + "\n OBJECT: " + event.getLocator().getObject() - + "\n NODE: " + event.getLocator().getNode() - + "\n URL: " + event.getLocator().getURL(); - log.error(error); - return true; - } - } - -} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/config/server/datasource/ControlQueue.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/config/server/datasource/ControlQueue.java deleted file mode 100644 index 145763bfa..000000000 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/config/server/datasource/ControlQueue.java +++ /dev/null @@ -1,229 +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.config.server.datasource; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - -/** - *

Java class for ControlQueue complex type. - *

- *

The following schema fragment specifies the expected content contained within this class. - *

- *

- * <complexType name="ControlQueue">
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element name="Name" type="{http://www.w3.org/2001/XMLSchema}string"/>
- *         <element name="Enabled" type="{http://www.w3.org/2001/XMLSchema}boolean"/>
- *         <element name="ControlClass" type="{http://www.w3.org/2001/XMLSchema}string"/>
- *         <element name="Protocol" type="{http://www.w3.org/2001/XMLSchema}string"/>
- *         <element name="ServerURL" type="{http://www.w3.org/2001/XMLSchema}string"/>
- *         <element name="Port" type="{http://www.w3.org/2001/XMLSchema}short"/>
- *         <element name="Username" type="{http://www.w3.org/2001/XMLSchema}string"/>
- *         <element name="Password" type="{http://www.w3.org/2001/XMLSchema}string"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "ControlQueue", propOrder = { - "name", - "enabled", - "controlClass", - "protocol", - "serverURL", - "port", - "username", - "password" -}) -public class ControlQueue { - - @XmlElement(name = "Name", required = true) - protected String name; - @XmlElement(name = "Enabled") - protected boolean enabled; - @XmlElement(name = "ControlClass", required = true) - protected String controlClass; - @XmlElement(name = "Protocol", required = true) - protected String protocol; - @XmlElement(name = "ServerURL", required = true) - protected String serverURL; - @XmlElement(name = "Port") - protected short port; - @XmlElement(name = "Username", required = true) - protected String username; - @XmlElement(name = "Password", required = true) - protected String password; - - /** - * Gets the value of the name property. - * - * @return possible object is - * {@link String } - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value allowed object is - * {@link String } - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the enabled property. - */ - public boolean isEnabled() { - return enabled; - } - - /** - * Sets the value of the enabled property. - */ - public void setEnabled(boolean value) { - this.enabled = value; - } - - /** - * Gets the value of the controlClass property. - * - * @return possible object is - * {@link String } - */ - public String getControlClass() { - return controlClass; - } - - /** - * Sets the value of the controlClass property. - * - * @param value allowed object is - * {@link String } - */ - public void setControlClass(String value) { - this.controlClass = value; - } - - /** - * Gets the value of the protocol property. - * - * @return possible object is - * {@link String } - */ - public String getProtocol() { - return protocol; - } - - /** - * Sets the value of the protocol property. - * - * @param value allowed object is - * {@link String } - */ - public void setProtocol(String value) { - this.protocol = value; - } - - /** - * Gets the value of the serverURL property. - * - * @return possible object is - * {@link String } - */ - public String getServerURL() { - return serverURL; - } - - /** - * Sets the value of the serverURL property. - * - * @param value allowed object is - * {@link String } - */ - public void setServerURL(String value) { - this.serverURL = value; - } - - /** - * Gets the value of the port property. - */ - public short getPort() { - return port; - } - - /** - * Sets the value of the port property. - */ - public void setPort(short value) { - this.port = value; - } - - /** - * Gets the value of the username property. - * - * @return possible object is - * {@link String } - */ - public String getUsername() { - return username; - } - - /** - * Sets the value of the username property. - * - * @param value allowed object is - * {@link String } - */ - public void setUsername(String value) { - this.username = value; - } - - /** - * Gets the value of the password property. - * - * @return possible object is - * {@link String } - */ - public String getPassword() { - return password; - } - - /** - * Sets the value of the password property. - * - * @param value allowed object is - * {@link String } - */ - public void setPassword(String value) { - this.password = value; - } - -} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/config/server/datasource/ControlQueuesConfig.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/config/server/datasource/ControlQueuesConfig.java deleted file mode 100644 index e7b82ce0b..000000000 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/config/server/datasource/ControlQueuesConfig.java +++ /dev/null @@ -1,82 +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.config.server.datasource; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - -/** - *

Java class for ControlQueuesConfig complex type. - *

- *

The following schema fragment specifies the expected content contained within this class. - *

- *

- * <complexType name="ControlQueuesConfig">
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element name="ControlQueue" type="{}ControlQueue" maxOccurs="unbounded" minOccurs="0"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "ControlQueuesConfig", propOrder = { - "controlQueue" -}) -public class ControlQueuesConfig { - - @XmlElement(name = "ControlQueue") - protected List controlQueue; - - /** - * Gets the value of the controlQueue property. - *

- *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the controlQueue property. - *

- *

- * For example, to add a new item, do as follows: - *

-     *    getControlQueue().add(newItem);
-     * 
- *

- *

- *

- * Objects of the following type(s) are allowed in the list - * {@link ControlQueue } - */ - public List getControlQueue() { - if (controlQueue == null) { - controlQueue = new ArrayList(); - } - return this.controlQueue; - } - -} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/config/server/datasource/DeviceManagementConfiguration.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/config/server/datasource/DeviceManagementConfiguration.java deleted file mode 100644 index 6194049c4..000000000 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/config/server/datasource/DeviceManagementConfiguration.java +++ /dev/null @@ -1,74 +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.config.server.datasource; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - -/** - *

Java class for DeviceCloudConfig complex type. - *

- *

The following schema fragment specifies the expected content contained within this class. - *

- *

- * <complexType name="DeviceManagementConfigurations">
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element name="ControlQueues" type="{}ControlQueuesConfig"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "DeviceManagementConfigurations", propOrder = { - "controlQueues" -}) - -@XmlRootElement(name = "DeviceManagementConfigurations") -public class DeviceManagementConfiguration { - @XmlElement(name = "ControlQueues", required = true) - protected ControlQueuesConfig controlQueues; - - /** - * Gets the value of the controlQueues property. - * - * @return possible object is - * {@link ControlQueuesConfig } - */ - public ControlQueuesConfig getControlQueues() { - return controlQueues; - } - - /** - * Sets the value of the controlQueues property. - * - * @param value allowed object is - * {@link ControlQueuesConfig } - */ - public void setControlQueues(ControlQueuesConfig value) { - this.controlQueues = value; - } -} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/config/server/datasource/ObjectFactory.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/config/server/datasource/ObjectFactory.java deleted file mode 100644 index 9bc313579..000000000 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/config/server/datasource/ObjectFactory.java +++ /dev/null @@ -1,69 +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.config.server.datasource; - -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlElementDecl; -import javax.xml.bind.annotation.XmlRegistry; -import javax.xml.namespace.QName; - -/** - * This object contains factory methods for each - * Java content interface and Java element interface - * generated in the org.wso2.carbon.device.mgt.iot.common.config.server.configs package. - *

An ObjectFactory allows you to programatically - * construct new instances of the Java representation - * for XML content. The Java representation of XML - * content can consist of schema derived interfaces - * and classes representing the binding of schema - * type definitions, element declarations and model - * groups. Factory methods for each of these are - * provided in this class. - */ -@XmlRegistry -public class ObjectFactory { - - private final static QName _DeviceCloudConfiguration_QNAME = new QName("", "DeviceManagementConfigurations"); - - /** - * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: - * org.wso2.carbon.device.mgt.iot.common.config.server.configs - */ - public ObjectFactory() { - } - - /** - * Create an instance of {@link DeviceManagementConfiguration } - */ - public DeviceManagementConfiguration createDeviceCloudConfig() { - return new DeviceManagementConfiguration(); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link DeviceManagementConfiguration }{@code >}} - */ - @XmlElementDecl(namespace = "", name = "DeviceManagementConfigurations") - public JAXBElement createDeviceCloudConfiguration( - DeviceManagementConfiguration value) { - return new JAXBElement(_DeviceCloudConfiguration_QNAME, - DeviceManagementConfiguration.class, null, value); - } - -} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/controlqueue/mqtt/MqttConfig.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/controlqueue/mqtt/MqttConfig.java deleted file mode 100644 index 26abefe49..000000000 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/controlqueue/mqtt/MqttConfig.java +++ /dev/null @@ -1,81 +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.controlqueue.mqtt; - -import org.wso2.carbon.device.mgt.iot.config.server.DeviceManagementConfigurationManager; -import org.wso2.carbon.device.mgt.iot.config.server.datasource.ControlQueue; - -public class MqttConfig { - private String mqttQueueEndpoint; - private String mqttQueueUsername; - private String mqttQueuePassword; - private boolean isEnabled; - private static final String MQTT_QUEUE_CONFIG_NAME = "MQTT"; - private static final String LOCALHOST = "localhost"; - private static final String PORT_OFFSET_PROPERTY = "portOffset"; - private ControlQueue mqttControlQueue; - private static MqttConfig mqttConfig = new MqttConfig(); - - public String getMqttQueueEndpoint() { - return mqttQueueEndpoint; - } - - public String getMqttQueueUsername() { - return mqttQueueUsername; - } - - public String getMqttQueuePassword() { - return mqttQueuePassword; - } - - public ControlQueue getMqttControlQueue() { - return mqttControlQueue; - } - - public boolean isEnabled() { - return isEnabled; - } - - public static String getMqttQueueConfigName() { - return MQTT_QUEUE_CONFIG_NAME; - } - - private MqttConfig() { - - mqttControlQueue = DeviceManagementConfigurationManager.getInstance().getControlQueue(MQTT_QUEUE_CONFIG_NAME); - int portOffset = Integer.parseInt(System.getProperty(PORT_OFFSET_PROPERTY)); - String brokerURL = mqttControlQueue.getServerURL(); - - if (portOffset != 0 && brokerURL.contains(LOCALHOST)) { - // if using the internal MB (meaning URL is localhost and there is a portOffset) - // then increment port accordingly - int mqttPort = mqttControlQueue.getPort(); - mqttPort = mqttPort + portOffset; - mqttQueueEndpoint = mqttControlQueue.getServerURL() + ":" + mqttPort; - } else { - mqttQueueEndpoint = mqttControlQueue.getServerURL() + ":" + mqttControlQueue.getPort(); - } - mqttQueueUsername = mqttControlQueue.getUsername(); - mqttQueuePassword = mqttControlQueue.getPassword(); - isEnabled = mqttControlQueue.isEnabled(); - } - public static MqttConfig getInstance() { - return mqttConfig; - } -} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/controlqueue/xmpp/XmppConfig.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/controlqueue/xmpp/XmppConfig.java deleted file mode 100644 index e06ee66f0..000000000 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/controlqueue/xmpp/XmppConfig.java +++ /dev/null @@ -1,93 +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.controlqueue.xmpp; - -import org.wso2.carbon.device.mgt.iot.config.server.DeviceManagementConfigurationManager; -import org.wso2.carbon.device.mgt.iot.config.server.datasource.ControlQueue; - -public class XmppConfig { - - private String xmppServerIP; - private int xmppServerPort; - private String xmppEndpoint; - private String xmppUsername; - private String xmppPassword; - private boolean isEnabled; - private static final String XMPP_QUEUE_CONFIG_NAME = "XMPP"; - private final int SERVER_CONNECTION_PORT = 5222; - private ControlQueue xmppControlQueue; - private static XmppConfig xmppConfig = new XmppConfig(); - - public String getXmppServerIP() { - return xmppServerIP; - } - - public int getXmppServerPort() { - return xmppServerPort; - } - - public String getXmppEndpoint() { - return xmppEndpoint; - } - - public String getXmppUsername() { - return xmppUsername; - } - - public String getXmppPassword() { - return xmppPassword; - } - - public ControlQueue getXmppControlQueue() { - return xmppControlQueue; - } - - public boolean isEnabled() { - return isEnabled; - } - - public static String getXmppQueueConfigName() { - return XMPP_QUEUE_CONFIG_NAME; - } - - private XmppConfig() { - xmppControlQueue = DeviceManagementConfigurationManager.getInstance().getControlQueue( - XMPP_QUEUE_CONFIG_NAME); - xmppServerIP = xmppControlQueue.getServerURL(); - int indexOfChar = xmppServerIP.lastIndexOf('/'); - - if (indexOfChar != -1) { - xmppServerIP = xmppServerIP.substring((indexOfChar + 1), xmppServerIP.length()); - } - - xmppServerPort = xmppControlQueue.getPort(); - xmppEndpoint = xmppControlQueue.getServerURL() + ":" + xmppServerPort; - xmppUsername = xmppControlQueue.getUsername(); - xmppPassword = xmppControlQueue.getPassword(); - isEnabled = xmppControlQueue.isEnabled(); - } - - public static XmppConfig getInstance() { - return xmppConfig; - } - - public int getSERVER_CONNECTION_PORT() { - return SERVER_CONNECTION_PORT; - } -} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/controlqueue/xmpp/XmppServerClient.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/controlqueue/xmpp/XmppServerClient.java deleted file mode 100644 index e415803b6..000000000 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/controlqueue/xmpp/XmppServerClient.java +++ /dev/null @@ -1,352 +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.controlqueue.xmpp; - -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.http.HttpHeaders; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpDelete; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.util.EntityUtils; -import org.json.JSONArray; -import org.json.JSONObject; -import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException; -import org.wso2.carbon.device.mgt.iot.util.IoTUtil; - - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.MalformedURLException; -import java.net.URL; -import java.nio.charset.StandardCharsets; - -public class XmppServerClient { - - private static final Log log = LogFactory.getLog(XmppServerClient.class); - private static final String XMPP_SERVER_API_CONTEXT = "/plugins/restapi/v1"; - private static final String XMPP_USERS_API = "/users"; - private static final String XMPP_SESSIONS_API = "/sessions"; - @SuppressWarnings("unused") - private static final String XMPP_GROUPS_API = "/groups"; - @SuppressWarnings("unused") - private static final String APPLICATION_JSON_MT = "application/json"; - private static final String DEVICEMGT_CONFIG_FILE = "devicemgt-config.xml"; - private static final String APPLICATION_JSON = "application/json"; - private String xmppEndpoint; - private String xmppUsername; - private String xmppPassword; - private boolean xmppEnabled = false; - - public XmppServerClient() { - } - - public void initControlQueue() { - xmppEndpoint = XmppConfig.getInstance().getXmppEndpoint(); - xmppUsername = XmppConfig.getInstance().getXmppUsername(); - xmppPassword = XmppConfig.getInstance().getXmppPassword(); - xmppEnabled = XmppConfig.getInstance().isEnabled(); - } - - public boolean createXMPPAccount(XmppAccount newUserAccount) throws DeviceControllerException { - if (xmppEnabled) { - String xmppUsersAPIEndpoint = xmppEndpoint + XMPP_SERVER_API_CONTEXT + XMPP_USERS_API; - if (log.isDebugEnabled()) { - log.debug("The Create-UserAccount Endpoint URL of the XMPP Server is set to: " + xmppUsersAPIEndpoint); - } - - String encodedString = xmppUsername + ":" + xmppPassword; - encodedString = new String(Base64.encodeBase64(encodedString.getBytes(StandardCharsets.UTF_8))); - String authorizationHeader = "Basic " + encodedString; - String jsonRequest = "{\n" + - " \"username\": \"" + newUserAccount.getUsername() + "\"," + - " \"password\": \"" + newUserAccount.getPassword() + "\"," + - " \"name\": \"" + newUserAccount.getAccountName() + "\"," + - " \"email\": \"" + newUserAccount.getEmail() + "\"," + - " \"properties\": {" + - " \"property\": [" + - " {" + - " \"@key\": \"console.rows_per_page\"," + - " \"@value\": \"user-summary=8\"" + - " }," + - " {" + - " \"@key\": \"console.order\"," + - " \"@value\": \"session-summary=1\"" + - " }" + - " ]" + - " }" + - "}"; - - StringEntity requestEntity; - try { - requestEntity = new StringEntity(jsonRequest, APPLICATION_JSON, - StandardCharsets.UTF_8.toString()); - } catch (UnsupportedEncodingException e) { - return false; - } - - URL xmppUserApiUrl; - try { - xmppUserApiUrl = new URL(xmppUsersAPIEndpoint); - } catch (MalformedURLException e) { - String errMsg = "Malformed XMPP URL + " + xmppUsersAPIEndpoint; - log.error(errMsg); - throw new DeviceControllerException(errMsg); - } - HttpClient httpClient; - try { - httpClient = IoTUtil.getHttpClient(xmppUserApiUrl.getPort(), xmppUserApiUrl.getProtocol()); - } catch (Exception e) { - log.error("Error on getting a http client for port :" + xmppUserApiUrl.getPort() + " protocol :" - + xmppUserApiUrl.getProtocol()); - return false; - } - - HttpPost httpPost = new HttpPost(xmppUsersAPIEndpoint); - httpPost.addHeader(HttpHeaders.AUTHORIZATION, authorizationHeader); - httpPost.setEntity(requestEntity); - - try { - HttpResponse httpResponse = httpClient.execute(httpPost); - - if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) { - String response = IoTUtil.getResponseString(httpResponse); - String errorMsg = "XMPP Server returned status: '" + httpResponse.getStatusLine().getStatusCode() + - "' for account creation with error:\n" + response; - log.error(errorMsg); - throw new DeviceControllerException(errorMsg); - } else { - EntityUtils.consume(httpResponse.getEntity()); - return true; - } - } catch (IOException e) { - String errorMsg = "Error occured whilst trying a 'POST' at : " + xmppUsersAPIEndpoint; - log.error(errorMsg); - throw new DeviceControllerException(errorMsg, e); - } - - } else { - log.warn(String.format("XMPP set to false in [%s]", DEVICEMGT_CONFIG_FILE)); - return false; - } - } - - public boolean doesXMPPUserAccountExist(String username) throws DeviceControllerException { - if (xmppEnabled) { - String xmppCheckUserAPIEndpoint = xmppEndpoint + XMPP_SERVER_API_CONTEXT + XMPP_USERS_API + "/" + username; - if (log.isDebugEnabled()) { - log.debug("The Check-User-Account Endpoint URL of the XMPP Server is set to: " + - xmppCheckUserAPIEndpoint); - } - - String encodedString = xmppUsername + ":" + xmppPassword; - encodedString = new String(Base64.encodeBase64(encodedString.getBytes(StandardCharsets.UTF_8))); - String authorizationHeader = "Basic " + encodedString; - - URL xmppUserApiUrl; - try { - xmppUserApiUrl = new URL(xmppCheckUserAPIEndpoint); - } catch (MalformedURLException e) { - String errMsg = "Malformed XMPP URL + " + xmppCheckUserAPIEndpoint; - log.error(errMsg); - throw new DeviceControllerException(errMsg, e); - } - - HttpClient httpClient; - try { - httpClient = IoTUtil.getHttpClient(xmppUserApiUrl.getPort(), xmppUserApiUrl.getProtocol()); - } catch (Exception e) { - String errorMsg = "Error on getting a http client for port :" + xmppUserApiUrl.getPort() + - " protocol :" + xmppUserApiUrl.getProtocol(); - log.error(errorMsg); - throw new DeviceControllerException(errorMsg, e); - } - - HttpGet httpGet = new HttpGet(xmppCheckUserAPIEndpoint); - httpGet.addHeader(HttpHeaders.AUTHORIZATION, authorizationHeader); - - try { - HttpResponse httpResponse = httpClient.execute(httpGet); - - if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { - String response = IoTUtil.getResponseString(httpResponse); - if (log.isDebugEnabled()) { - log.debug("XMPP Server returned status: '" + httpResponse.getStatusLine().getStatusCode() + - "' for checking existence of account [" + username + "] with message:\n" + - response + "\nProbably, an account with this username does not exist."); - } - return false; - } - - } catch (IOException e) { - String errorMsg = "Error occured whilst trying a 'GET' at : " + xmppCheckUserAPIEndpoint; - log.error(errorMsg); - throw new DeviceControllerException(errorMsg, e); - } - - if (log.isDebugEnabled()) { - log.debug("XMPP Server already has an account for the username - [" + username + "]."); - } - return true; - } else { - String warnMsg = String.format("XMPP set to false in [%s]", DEVICEMGT_CONFIG_FILE); - log.warn(warnMsg); - throw new DeviceControllerException(warnMsg); - } - } - - public JSONArray getAllCurrentUserSessions() throws DeviceControllerException { - if (xmppEnabled) { - JSONArray xmppSessions; - String xmppSessionsAPIEndpoint = xmppEndpoint + XMPP_SERVER_API_CONTEXT + XMPP_SESSIONS_API; - - if (log.isDebugEnabled()) { - log.debug("The Get-Sessions Endpoint URL of the XMPP Server is set to: " + xmppSessionsAPIEndpoint); - } - - String encodedString = xmppUsername + ":" + xmppPassword; - encodedString = new String(Base64.encodeBase64(encodedString.getBytes(StandardCharsets.UTF_8))); - String authorizationHeader = "Basic " + encodedString; - - URL xmppUserApiUrl; - try { - xmppUserApiUrl = new URL(xmppSessionsAPIEndpoint); - } catch (MalformedURLException e) { - String errMsg = "Malformed XMPP URL + " + xmppSessionsAPIEndpoint; - log.error(errMsg); - throw new DeviceControllerException(errMsg, e); - } - - HttpClient httpClient; - try { - httpClient = IoTUtil.getHttpClient(xmppUserApiUrl.getPort(), xmppUserApiUrl.getProtocol()); - } catch (Exception e) { - String errorMsg = "Error on getting a http client for port :" + xmppUserApiUrl.getPort() + - " protocol :" + xmppUserApiUrl.getProtocol(); - log.error(errorMsg); - throw new DeviceControllerException(errorMsg, e); - } - - HttpGet httpGet = new HttpGet(xmppSessionsAPIEndpoint); - httpGet.addHeader(HttpHeaders.AUTHORIZATION, authorizationHeader); - httpGet.addHeader(HttpHeaders.ACCEPT, APPLICATION_JSON); - - try { - HttpResponse httpResponse = httpClient.execute(httpGet); - - if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { - String errorMsg = "XMPP Server returned status: '" + httpResponse.getStatusLine().getStatusCode() + - "' for checking current XMPP Sessions."; - log.error(errorMsg); - throw new DeviceControllerException(errorMsg); - } - - String response = IoTUtil.getResponseString(httpResponse); - xmppSessions = new JSONObject(response).getJSONArray("session"); - return xmppSessions; - - } catch (IOException e) { - String errorMsg = "Error occured whilst trying a 'GET' at : " + xmppSessionsAPIEndpoint; - log.error(errorMsg); - throw new DeviceControllerException(errorMsg, e); - } - - } else { - String warnMsg = String.format("XMPP set to false in [%s]", DEVICEMGT_CONFIG_FILE); - log.warn(warnMsg); - throw new DeviceControllerException(warnMsg); - } - } - - public void deleteCurrentXmppSessions() throws DeviceControllerException { - JSONArray xmppSessionsArray; - try { - xmppSessionsArray = getAllCurrentUserSessions(); - } catch (DeviceControllerException e) { - if (e.getMessage().contains(DEVICEMGT_CONFIG_FILE)) { - log.warn(String.format("XMPP set to false in [%s]", DEVICEMGT_CONFIG_FILE)); - return; - } else { - throw e; - } - } - - if (xmppSessionsArray.length() != 0) { - String xmppSessionsAPIEndpoint = xmppEndpoint + XMPP_SERVER_API_CONTEXT + XMPP_SESSIONS_API; - String encodedString = xmppUsername + ":" + xmppPassword; - encodedString = new String(Base64.encodeBase64(encodedString.getBytes(StandardCharsets.UTF_8))); - String authorizationHeader = "Basic " + encodedString; - - if (log.isDebugEnabled()) { - log.debug("The Get-Sessions Endpoint URL of the XMPP Server is set to: " + xmppSessionsAPIEndpoint); - } - - URL xmppUserApiUrl; - try { - xmppUserApiUrl = new URL(xmppSessionsAPIEndpoint); - } catch (MalformedURLException e) { - String errMsg = "Malformed XMPP URL + " + xmppSessionsAPIEndpoint; - log.error(errMsg); - throw new DeviceControllerException(errMsg, e); - } - - HttpClient httpClient; - try { - httpClient = IoTUtil.getHttpClient(xmppUserApiUrl.getPort(), xmppUserApiUrl.getProtocol()); - } catch (Exception e) { - String errorMsg = "Error on getting a http client for port :" + xmppUserApiUrl.getPort() + - " protocol :" + xmppUserApiUrl.getProtocol(); - log.error(errorMsg); - throw new DeviceControllerException(errorMsg, e); - } - - for (int i = 0; i < xmppSessionsArray.length(); i++) { - - String sessionName = xmppSessionsArray.getJSONObject(i).getString("username"); - String xmppUserSessionsAPIEndpoint = xmppSessionsAPIEndpoint + "/" + sessionName; - - HttpDelete httpDelete = new HttpDelete(xmppUserSessionsAPIEndpoint); - httpDelete.addHeader(HttpHeaders.AUTHORIZATION, authorizationHeader); - - try { - HttpResponse httpResponse = httpClient.execute(httpDelete); - - if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { - String errorMsg = - "XMPP Server returned status: '" + httpResponse.getStatusLine().getStatusCode() + - "' for checking current XMPP Sessions."; - log.error(errorMsg); - throw new DeviceControllerException(errorMsg); - } - - } catch (IOException e) { - String errorMsg = "Error occured whilst trying a 'DELETE' user-session [" + sessionName + "] " + - "at : " + xmppUserSessionsAPIEndpoint; - log.error(errorMsg); - throw new DeviceControllerException(errorMsg, e); - } - } - } - } -} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/exception/DeviceControllerException.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/exception/DeviceControllerException.java deleted file mode 100644 index c3bce4848..000000000 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/exception/DeviceControllerException.java +++ /dev/null @@ -1,42 +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.exception; - -public class DeviceControllerException extends Exception { - - public DeviceControllerException(String message, Throwable cause, boolean enableSuppression, - boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } - - public DeviceControllerException(Throwable cause) { - super(cause); - } - - public DeviceControllerException(String message, Throwable cause) { - super(message, cause); - } - - public DeviceControllerException(String message) { - super(message); - } - - public DeviceControllerException() { - } -} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/exception/NotImplementedException.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/exception/NotImplementedException.java deleted file mode 100644 index 7ce9b3f80..000000000 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/exception/NotImplementedException.java +++ /dev/null @@ -1,43 +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.exception; - -public class NotImplementedException extends RuntimeException { - - public NotImplementedException() { - super(); - } - - public NotImplementedException(String message) { - super(message); - } - - public NotImplementedException(String message, Throwable cause) { - super(message, cause); - } - - public NotImplementedException(Throwable cause) { - super(cause); - } - - protected NotImplementedException(String message, Throwable cause, boolean enableSuppression, - boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } -} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/exception/UnauthorizedException.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/exception/UnauthorizedException.java deleted file mode 100644 index 1af199b17..000000000 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/exception/UnauthorizedException.java +++ /dev/null @@ -1,39 +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.exception; - -public class UnauthorizedException extends Exception { - - public UnauthorizedException(String message) { - super(message); - } - - public UnauthorizedException(String message, Throwable cause) { - super(message, cause); - } - - public UnauthorizedException(Throwable cause) { - super(cause); - } - - public UnauthorizedException(String message, Throwable cause, boolean enableSuppression, - boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } -} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/internal/IoTDeviceManagementDataHolder.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/internal/IoTDeviceManagementDataHolder.java new file mode 100644 index 000000000..76edfc41c --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/internal/IoTDeviceManagementDataHolder.java @@ -0,0 +1,42 @@ +/* + * 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.internal; + +import org.wso2.carbon.utils.ConfigurationContextService; + +public class IoTDeviceManagementDataHolder { + + private ConfigurationContextService configurationContextService; + private static IoTDeviceManagementDataHolder thisInstance = new IoTDeviceManagementDataHolder(); + + private IoTDeviceManagementDataHolder() {} + + public static IoTDeviceManagementDataHolder getInstance() { + return thisInstance; + } + + public ConfigurationContextService getConfigurationContextService() { + return configurationContextService; + } + + public void setConfigurationContextService(ConfigurationContextService configurationContextService) { + this.configurationContextService = configurationContextService; + } + +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/internal/IotDeviceManagementServiceComponent.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/internal/IotDeviceManagementServiceComponent.java index 76e045c5c..77bb7b70b 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/internal/IotDeviceManagementServiceComponent.java +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/internal/IotDeviceManagementServiceComponent.java @@ -23,11 +23,7 @@ import org.apache.commons.logging.LogFactory; import org.osgi.framework.BundleContext; import org.osgi.service.component.ComponentContext; import org.wso2.carbon.core.ServerStartupObserver; -import org.wso2.carbon.device.mgt.iot.config.server.DeviceManagementConfigurationManager; -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.DeviceControllerException; -import org.wso2.carbon.device.mgt.iot.service.IoTServerStartupListener; +import org.wso2.carbon.device.mgt.iot.url.printer.URLPrinterStartupHandler; import org.wso2.carbon.utils.ConfigurationContextService; /** @@ -43,7 +39,6 @@ import org.wso2.carbon.utils.ConfigurationContextService; public class IotDeviceManagementServiceComponent { private static final Log log = LogFactory.getLog(IotDeviceManagementServiceComponent.class); - public static ConfigurationContextService configurationContextService; protected void activate(ComponentContext ctx) { if (log.isDebugEnabled()) { @@ -51,9 +46,7 @@ public class IotDeviceManagementServiceComponent { } try { BundleContext bundleContext = ctx.getBundleContext(); - /* Initialize the data source configuration */ - DeviceManagementConfigurationManager.getInstance().initConfig(); - bundleContext.registerService(ServerStartupObserver.class.getName(), new IoTServerStartupListener(), null); + bundleContext.registerService(ServerStartupObserver.class.getName(), new URLPrinterStartupHandler(), null); if (log.isDebugEnabled()) { log.debug("Iot Device Management Service Component has been successfully activated"); } @@ -63,19 +56,6 @@ public class IotDeviceManagementServiceComponent { } protected void deactivate(ComponentContext ctx) { - XmppConfig xmppConfig = XmppConfig.getInstance(); - try { - if (xmppConfig.isEnabled()) { - XmppServerClient xmppServerClient = new XmppServerClient(); - xmppServerClient.initControlQueue(); - xmppServerClient.deleteCurrentXmppSessions(); - } - } catch (DeviceControllerException e) { - String errorMsg = "An error occurred whilst trying to delete all existing XMPP login sessions at " + - "[" + xmppConfig.getXmppEndpoint() + "]."; - log.error(errorMsg, e); - } - if (log.isDebugEnabled()) { log.debug("De-activating Iot Device Management Service Component"); } @@ -86,7 +66,7 @@ public class IotDeviceManagementServiceComponent { log.debug("Setting ConfigurationContextService"); } - IotDeviceManagementServiceComponent.configurationContextService = configurationContextService; + IoTDeviceManagementDataHolder.getInstance().setConfigurationContextService(configurationContextService); } @@ -94,6 +74,6 @@ public class IotDeviceManagementServiceComponent { if (log.isDebugEnabled()) { log.debug("Un-setting ConfigurationContextService"); } - IotDeviceManagementServiceComponent.configurationContextService = null; + IoTDeviceManagementDataHolder.getInstance().setConfigurationContextService(null); } } diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/mqtt/PolicyPush.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/mqtt/PolicyPush.java deleted file mode 100644 index 9fc4fddd9..000000000 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/mqtt/PolicyPush.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.wso2.carbon.device.mgt.iot.mqtt; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.eclipse.paho.client.mqttv3.MqttClient; -import org.eclipse.paho.client.mqttv3.MqttConnectOptions; -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttMessage; -import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; - -public class PolicyPush { - - private static final Log log = LogFactory.getLog(PolicyPush.class); - - public boolean pushToMQTT(String topic, String content, String broker, String clientId) { - - byte qos = 2; - MemoryPersistence persistence = new MemoryPersistence(); - - try { - MqttClient me = new MqttClient(broker, clientId, persistence); - MqttConnectOptions connOpts = new MqttConnectOptions(); - connOpts.setCleanSession(true); - if (log.isDebugEnabled()) { - log.debug("Connecting to broker: " + broker); - } - me.connect(connOpts); - if (log.isDebugEnabled()) { - log.debug("Connected"); - log.debug("Publishing message: " + content); - } - MqttMessage message = new MqttMessage(content.getBytes()); - message.setQos(qos); - me.publish(topic, message); - if (log.isDebugEnabled()) { - log.debug("Message published"); - } - me.disconnect(); - if (log.isDebugEnabled()) { - log.debug("Disconnected"); - } - return true; - } catch (MqttException ex) { - log.error("Error occurred when trying to publish to MQTT Queue", ex); - return false; - } - } -} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/CommunicationUtils.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/CommunicationUtils.java deleted file mode 100644 index 59cd7813d..000000000 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/CommunicationUtils.java +++ /dev/null @@ -1,219 +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.transport; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.tomcat.util.codec.binary.Base64; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import java.nio.charset.StandardCharsets; -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.Signature; -import java.security.SignatureException; - -/** - * This is a utility class which contains methods common to the communication process of a client and the server. The - * methods include encryption/decryption of payloads and signing/verification of payloads received and to be sent. - */ -public class CommunicationUtils { - private static final Log log = LogFactory.getLog(TransportUtils.class); - // The Signature Algorithm used. - private static final String SIGNATURE_ALG = "SHA1withRSA"; - // The Encryption Algorithm and the Padding used. - private static final String CIPHER_PADDING = "RSA/ECB/PKCS1Padding"; - - /** - * Encrypts the message with the key that's passed in. - * - * @param message the message to be encrypted. - * @param encryptionKey the key to use for the encryption of the message. - * @return the encrypted message in String format. - * @throws TransportHandlerException if an error occurs with the encryption flow which can be due to Padding - * issues, encryption key being invalid or the algorithm used is unrecognizable. - */ - public static String encryptMessage(String message, Key encryptionKey) throws TransportHandlerException { - Cipher encrypter; - byte[] cipherData; - - try { - encrypter = Cipher.getInstance(CIPHER_PADDING); - encrypter.init(Cipher.ENCRYPT_MODE, encryptionKey); - cipherData = encrypter.doFinal(message.getBytes(StandardCharsets.UTF_8)); - - } catch (NoSuchAlgorithmException e) { - String errorMsg = "Algorithm not found exception occurred for Cipher instance of [" + CIPHER_PADDING + "]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, e); - } catch (NoSuchPaddingException e) { - String errorMsg = "No Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, e); - } catch (InvalidKeyException e) { - String errorMsg = "InvalidKey exception occurred for encryptionKey \n[\n" + encryptionKey + "\n]\n"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, e); - } catch (BadPaddingException e) { - String errorMsg = "Bad Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, e); - } catch (IllegalBlockSizeException e) { - String errorMsg = "Illegal blockSize error occurred for Cipher instance of [" + CIPHER_PADDING + "]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, e); - } - - return Base64.encodeBase64String(cipherData); - } - -///TODO:: Exception needs to change according to the common package - - /** - * Signed a given message using the PrivateKey that's passes in. - * - * @param message the message to be signed. Ideally some encrypted payload. - * @param signatureKey the PrivateKey with which the message is to be signed. - * @return the Base64Encoded String of the signed payload. - * @throws TransportHandlerException if some error occurs with the signing process which may be related to the - * signature algorithm used or the key used for signing. - */ - public static String signMessage(String message, PrivateKey signatureKey) throws TransportHandlerException { - - Signature signature; - String signedEncodedString; - - try { - signature = Signature.getInstance(SIGNATURE_ALG); - signature.initSign(signatureKey); - signature.update(Base64.decodeBase64(message)); - - byte[] signatureBytes = signature.sign(); - signedEncodedString = Base64.encodeBase64String(signatureBytes); - - } catch (NoSuchAlgorithmException e) { - String errorMsg = - "Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, e); - } catch (SignatureException e) { - String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, e); - } catch (InvalidKeyException e) { - String errorMsg = "InvalidKey exception occurred for signatureKey \n[\n" + signatureKey + "\n]\n"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, e); - } - return signedEncodedString; - } - - /** - * Verifies some signed-data against the a Public-Key to ensure that it was produced by the holder of the - * corresponding Private Key. - * - * @param data the actual payoad which was signed by some Private Key. - * @param signedData the signed data produced by signing the payload using a Private Key. - * @param verificationKey the corresponding Public Key which is an exact pair of the Private-Key with we expect - * the data to be signed by. - * @return true if the signed data verifies to be signed by the corresponding Private Key. - * @throws TransportHandlerException if some error occurs with the verification process which may be related to - * the signature algorithm used or the key used for signing. - */ - public static boolean verifySignature(String data, String signedData, PublicKey verificationKey) - throws TransportHandlerException { - - Signature signature; - boolean verified; - - try { - signature = Signature.getInstance(SIGNATURE_ALG); - signature.initVerify(verificationKey); - signature.update(Base64.decodeBase64(data)); - - verified = signature.verify(Base64.decodeBase64(signedData)); - - } catch (NoSuchAlgorithmException e) { - String errorMsg = - "Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, e); - } catch (SignatureException e) { - String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, e); - } catch (InvalidKeyException e) { - String errorMsg = "InvalidKey exception occurred for signatureKey \n[\n" + verificationKey + "\n]\n"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, e); - } - return verified; - } - - /** - * Encrypts the message with the key that's passed in. - * - * @param encryptedMessage the encrypted message that is supposed to be decrypted. - * @param decryptKey the key to use in the decryption process. - * @return the decrypted message in String format. - * @throws TransportHandlerException if an error occurs with the encryption flow which can be due to Padding - * issues, encryption key being invalid or the algorithm used is unrecognizable. - */ - public static String decryptMessage(String encryptedMessage, Key decryptKey) throws TransportHandlerException { - - Cipher decrypter; - String decryptedMessage; - - try { - - decrypter = Cipher.getInstance(CIPHER_PADDING); - decrypter.init(Cipher.DECRYPT_MODE, decryptKey); - decryptedMessage = new String(decrypter.doFinal(Base64.decodeBase64(encryptedMessage)), - StandardCharsets.UTF_8); - - } catch (NoSuchAlgorithmException e) { - String errorMsg = "Algorithm not found exception occurred for Cipher instance of [" + CIPHER_PADDING + "]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, e); - } catch (NoSuchPaddingException e) { - String errorMsg = "No Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, e); - } catch (InvalidKeyException e) { - String errorMsg = "InvalidKey exception occurred for encryptionKey \n[\n" + decryptKey + "\n]\n"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, e); - } catch (BadPaddingException e) { - String errorMsg = "Bad Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, e); - } catch (IllegalBlockSizeException e) { - String errorMsg = "Illegal blockSize error occurred for Cipher instance of [" + CIPHER_PADDING + "]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, e); - } - return decryptedMessage; - } -} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/TransportHandler.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/TransportHandler.java deleted file mode 100644 index b81bdba4f..000000000 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/TransportHandler.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.wso2.carbon.device.mgt.iot.transport; - -/** - * This interface consists of the core functionality related to the transport between any device and the server. The - * interface is an abstraction, regardless of the underlying protocol used for the transport. Implementation of this - * interface by any class that caters a specific protocol (ex: HTTP, XMPP, MQTT, CoAP) would ideally have methods - * specific to the protocol used for communication and other methods that implement the logic related to the devices - * using the protocol. The methods of the interface are identified as generic ones for implementing transport - * protocols for device communication. The implementation can utilize the appropriate method signatures applicable for - * intended protocol. - * - * @param an object of the message type specific to the protocol implemented. To be set to 'String' if there - * isn't anything specific. - */ -public interface TransportHandler { - // a default timeout interval to be used for the protocol specific connections - int DEFAULT_TIMEOUT_INTERVAL = 5000; // millis ~ 5 sec - - /** - * Implements the underlying connect mechanism specific to the protocol enabled by the interface. An object of a - * class that implements this interface would call this method before any communication is started via the - * intended protocol. - */ - void connect(); - - /** - * Used to check whether a connection (via the implemented protocol) to the external-endpoint exists. Ideally - * used to verify that the connection persists and to spawn a reconnection attempt if not. - * - * @return 'true' if connection is already made & exists, else 'false'. - */ - boolean isConnected(); - - /** - * @throws TransportHandlerException in the event of any exceptions that occur whilst processing the message. - * @see TransportHandler#processIncomingMessage(Object, String...) - */ - void processIncomingMessage() throws TransportHandlerException; - - /** - * @param message the message (of the type specific to the protocol) received from the device. - * @throws TransportHandlerException - * @see TransportHandler#processIncomingMessage(Object, String...) - */ - void processIncomingMessage(T message) throws TransportHandlerException; - - /** - * This is an overloaded method with three different method-signatures. This method is used to process any - * incoming messages via the implemented protocol. It would ideally be invoked at a point where a message - * received event is activated (Ex: `MessageArrived` callback in Eclipse-Paho-MQTT Client & `PacketListener`(s) - * in XMPP). - *

- * - * @param message the message (of the type specific to the protocol) received from the device. - * @param messageParams one or more other parameters received as part-of & relevant-to the message (Ex: MQTT Topic). - * @throws TransportHandlerException in the event of any exceptions that occur whilst processing the message. - */ - void processIncomingMessage(T message, String... messageParams) throws TransportHandlerException; - - /** - * @throws TransportHandlerException in the event of any exceptions that occur whilst sending the message. - * @see TransportHandler#publishDeviceData(String...) - */ - void publishDeviceData() throws TransportHandlerException; - - /** - * @param publishData the message (of the type specific to the protocol) to be sent to the device. - * @throws TransportHandlerException in the event of any exceptions that occur whilst sending the message. - * @see TransportHandler#publishDeviceData(String...) - */ - void publishDeviceData(T publishData) throws TransportHandlerException; - - /** - * This is an overloaded method with three different method-signatures. This method is used to publish messages - * to an external-endpoint/device via the implemented protocol. It could in itself call the (communicating) - * external-endpoint or invoke any method provided by the protocol specific library. - *

- * - * @param publishData one or more parameters specific to the message and the data to be sent. - * @throws TransportHandlerException in the event of any exceptions that occur whilst sending the message. - */ - void publishDeviceData(String... publishData) throws TransportHandlerException; - - /** - * Implements the underlying disconnect mechanism specific to the protocol enabled by the interface. An object of a - * class that implements this interface would call this method upon completion of all communication. In the case of - * the IoT-Server invoking this would only be required if the server shuts-down. - */ - void disconnect(); -} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/TransportHandlerException.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/TransportHandlerException.java deleted file mode 100644 index c862e56d8..000000000 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/TransportHandlerException.java +++ /dev/null @@ -1,56 +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.transport; - -public class TransportHandlerException 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 TransportHandlerException(String msg, Exception nestedEx) { - super(msg, nestedEx); - setErrorMessage(msg); - } - - public TransportHandlerException(String message, Throwable cause) { - super(message, cause); - setErrorMessage(message); - } - - public TransportHandlerException(String msg) { - super(msg); - setErrorMessage(msg); - } - - public TransportHandlerException() { - super(); - } - - public TransportHandlerException(Throwable cause) { - super(cause); - } -} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/TransportUtils.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/TransportUtils.java deleted file mode 100644 index b6f32778b..000000000 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/TransportUtils.java +++ /dev/null @@ -1,296 +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.transport; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.DatagramSocket; -import java.net.HttpURLConnection; -import java.net.InetAddress; -import java.net.MalformedURLException; -import java.net.NetworkInterface; -import java.net.ServerSocket; -import java.net.SocketException; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; -import java.util.Random; - -public class TransportUtils { - private static final Log log = LogFactory.getLog(TransportUtils.class); - - public static final int MIN_PORT_NUMBER = 9000; - public static final int MAX_PORT_NUMBER = 11000; - - /** - * Given a server endpoint as a String, this method splits it into Protocol, Host and Port - * - * @param ipString a network endpoint in the format - '://:' - * @return a map with keys "Protocol", "Host" & "Port" for the related values from the ipString - * @throws TransportHandlerException - */ - public static Map getHostAndPort(String ipString) - throws TransportHandlerException { - Map ipPortMap = new HashMap(); - String[] ipPortArray = ipString.split(":"); - - if (ipPortArray.length != 3) { - String errorMsg = - "The IP String - '" + ipString + - "' is invalid. It needs to be in format '://:'."; - log.info(errorMsg); - throw new TransportHandlerException(errorMsg); - } - - ipPortMap.put("Protocol", ipPortArray[0]); - ipPortMap.put("Host", ipPortArray[1].replace(File.separator, "")); - ipPortMap.put("Port", ipPortArray[2]); - return ipPortMap; - } - - /** - * This method validates whether a specific IP Address is of IPv4 type - * - * @param ipAddress the IP Address which needs to be validated - * @return true if it is of IPv4 type and false otherwise - */ - public static boolean validateIPv4(String ipAddress) { - try { - if (ipAddress == null || ipAddress.isEmpty()) { - return false; - } - - String[] parts = ipAddress.split("\\."); - if (parts.length != 4) { - return false; - } - - for (String s : parts) { - int i = Integer.parseInt(s); - if ((i < 0) || (i > 255)) { - return false; - } - } - return !ipAddress.endsWith("."); - - } catch (NumberFormatException nfe) { - log.warn("The IP Address: " + ipAddress + " could not " + - "be validated against IPv4-style"); - return false; - } - } - - public static Map getInterfaceIPMap() throws TransportHandlerException { - - Map interfaceToIPMap = new HashMap(); - Enumeration networkInterfaces; - String networkInterfaceName = ""; - String ipAddress; - - try { - networkInterfaces = NetworkInterface.getNetworkInterfaces(); - } catch (SocketException exception) { - String errorMsg = - "Error encountered whilst trying to get the list of network-interfaces"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, exception); - } - - try { - for (; networkInterfaces.hasMoreElements(); ) { - networkInterfaceName = networkInterfaces.nextElement().getName(); - - if (log.isDebugEnabled()) { - log.debug("Network Interface: " + networkInterfaceName); - log.debug("------------------------------------------"); - } - - Enumeration interfaceIPAddresses = NetworkInterface.getByName( - networkInterfaceName).getInetAddresses(); - - for (; interfaceIPAddresses.hasMoreElements(); ) { - ipAddress = interfaceIPAddresses.nextElement().getHostAddress(); - - if (log.isDebugEnabled()) { - log.debug("IP Address: " + ipAddress); - } - - if (TransportUtils.validateIPv4(ipAddress)) { - interfaceToIPMap.put(networkInterfaceName, ipAddress); - } - } - - if (log.isDebugEnabled()) { - log.debug("------------------------------------------"); - } - } - } catch (SocketException exception) { - String errorMsg = - "Error encountered whilst trying to get the IP Addresses of the network " + - "interface: " + networkInterfaceName; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, exception); - } - - return interfaceToIPMap; - } - - /** - * Attempts to find a free port between the MIN_PORT_NUMBER(9000) and MAX_PORT_NUMBER(11000). - * Tries 'RANDOMLY picked' port numbers between this range up-until "randomAttempts" number of - * times. If still fails, then tries each port in descending order from the MAX_PORT_NUMBER - * whilst skipping already attempted ones via random selection. - * - * @param randomAttempts no of times to TEST port numbers picked randomly over the given range - * @return an available/free port - */ - public static synchronized int getAvailablePort(int randomAttempts) { - ArrayList failedPorts = new ArrayList(randomAttempts); - - Random randomNum = new Random(); - int randomPort = MAX_PORT_NUMBER; - - while (randomAttempts > 0) { - randomPort = randomNum.nextInt(MAX_PORT_NUMBER - MIN_PORT_NUMBER) + MIN_PORT_NUMBER; - - if (checkIfPortAvailable(randomPort)) { - return randomPort; - } - failedPorts.add(randomPort); - randomAttempts--; - } - - randomPort = MAX_PORT_NUMBER; - - while (true) { - if (!failedPorts.contains(randomPort) && checkIfPortAvailable(randomPort)) { - return randomPort; - } - randomPort--; - } - } - - private static boolean checkIfPortAvailable(int port) { - ServerSocket tcpSocket = null; - DatagramSocket udpSocket = null; - - try { - tcpSocket = new ServerSocket(port); - tcpSocket.setReuseAddress(true); - - udpSocket = new DatagramSocket(port); - udpSocket.setReuseAddress(true); - return true; - } catch (IOException ex) { - // denotes the port is in use - } finally { - if (tcpSocket != null) { - try { - tcpSocket.close(); - } catch (IOException e) { - /* not to be thrown */ - } - } - - if (udpSocket != null) { - udpSocket.close(); - } - } - - return false; - } - - /** - * This is a utility method that creates and returns a HTTP connection object. - * - * @param urlString the URL pattern to which the connection needs to be created - * @return an HTTPConnection object which cn be used to send HTTP requests - * @throws TransportHandlerException if errors occur when creating the HTTP connection with - * the given URL string - */ - public static HttpURLConnection getHttpConnection(String urlString) throws - TransportHandlerException { - URL connectionUrl; - 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 TransportHandlerException(errorMsg, e); - } catch (IOException exception) { - String errorMsg = "Error occured whilst trying to open a connection to: " + urlString; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, exception); - } - return httpConnection; - } - - /** - * This is a utility method that reads and returns the response from a HTTP connection - * - * @param httpConnection the connection from which a response is expected - * @return the response (as a string) from the given HTTP connection - * @throws TransportHandlerException if any errors occur whilst reading the response from - * the connection stream - */ - public static String readResponseFromHttpRequest(HttpURLConnection httpConnection) - throws TransportHandlerException { - BufferedReader bufferedReader; - try { - bufferedReader = new BufferedReader(new InputStreamReader( - httpConnection.getInputStream(), StandardCharsets.UTF_8)); - } catch (IOException exception) { - String errorMsg = "There is an issue with connecting the reader to the input stream at: " + - httpConnection.getURL(); - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, exception); - } - - String responseLine; - StringBuilder completeResponse = new StringBuilder(); - - try { - while ((responseLine = bufferedReader.readLine()) != null) { - completeResponse.append(responseLine); - } - } catch (IOException exception) { - String errorMsg = "Error occured whilst trying read from the connection stream at: " + - httpConnection.getURL(); - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, exception); - } - try { - bufferedReader.close(); - } catch (IOException exception) { - log.error("Could not succesfully close the bufferedReader to the connection at: " + httpConnection.getURL()); - } - return completeResponse.toString(); - } -} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/mqtt/MQTTTransportHandler.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/mqtt/MQTTTransportHandler.java deleted file mode 100644 index e161e34c9..000000000 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/mqtt/MQTTTransportHandler.java +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.wso2.carbon.device.mgt.iot.transport.mqtt; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; -import org.eclipse.paho.client.mqttv3.MqttCallback; -import org.eclipse.paho.client.mqttv3.MqttClient; -import org.eclipse.paho.client.mqttv3.MqttConnectOptions; -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttMessage; -import org.wso2.carbon.device.mgt.iot.transport.TransportHandler; -import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException; - -import java.io.File; -import java.nio.charset.StandardCharsets; - -/** - * This is an abstract class that implements the "TransportHandler" interface. The interface is an abstraction for - * the core functionality with regards to device-server communication regardless of the Transport protocol. This - * specific class contains the MQTT-Transport specific implementations. The class implements utility methods for the - * case of a MQTT communication. However, this "abstract class", even-though it implements the "TransportHandler" - * interface, does not contain the logic relevant to the interface methods. The specific functionality of the - * interface methods are intended to be implemented by the concrete class that extends this abstract class and - * utilizes the MQTT specific functionality (ideally a device API writer who would like to communicate to the device - * via MQTT Protocol). - *

- * This class contains the Device-Management 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 upon receiving a MQTT message. Makes use of the 'Paho-MQTT' - * library provided by Eclipse Org. - */ -public abstract class MQTTTransportHandler implements MqttCallback, TransportHandler { - - private static final Log log = LogFactory.getLog(MQTTTransportHandler.class); - private MqttClient client; - private String clientId; - private MqttConnectOptions options; // options to be set to the client-connection. - // topic to which a will-message is automatically published by the broker upon the device losing its connection. - private String clientWillTopic; - protected String mqttBrokerEndPoint; - protected int timeoutInterval; // interval to use for reconnection attempts etc. - protected String subscribeTopic; - // Quality of Service Levels for MQTT Subscription and Publishing. - public static final int QoS_0 = 0; // At-Most Once - @SuppressWarnings("unused") - public static final int QoS_1 = 1; // At-Least Once - public static final int QoS_2 = 2; // Exactly Once - public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = QoS_0; - // Prefix to the Will-Topic to which a message is published if client loses its connection. - private static final String DISCONNECTION_WILL_TOPIC_PREFIX = "Disconnection/"; - // Will-Message of the client to be published if connection is lost. - private static final String DISCONNECTION_WILL_MSG = "Lost-Connection"; - - /** - * Constructor for the MQTTTransportHandler 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 MQTTTransportHandler(String deviceOwner, String deviceType, - String mqttBrokerEndPoint, String subscribeTopic) { - this.clientId = deviceOwner + ":" + deviceType; - this.subscribeTopic = subscribeTopic; - this.clientWillTopic = DISCONNECTION_WILL_TOPIC_PREFIX + deviceType; - this.mqttBrokerEndPoint = mqttBrokerEndPoint; - this.timeoutInterval = DEFAULT_TIMEOUT_INTERVAL; - this.initMQTTClient(); - } - - /** - * Constructor for the MQTTTransportHandler 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 attempts to connect to the broker. - */ - protected MQTTTransportHandler(String deviceOwner, String deviceType, - String mqttBrokerEndPoint, String subscribeTopic, int intervalInMillis) { - this.clientId = deviceOwner + ":" + deviceType; - this.subscribeTopic = subscribeTopic; - this.clientWillTopic = DISCONNECTION_WILL_TOPIC_PREFIX + deviceType; - this.mqttBrokerEndPoint = mqttBrokerEndPoint; - this.timeoutInterval = intervalInMillis; - this.initMQTTClient(); - } - - /** - * 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 callback to this current class. - */ - private void initMQTTClient() { - try { - client = new MqttClient(this.mqttBrokerEndPoint, clientId, null); - log.info("MQTT client was created with ClientID : " + clientId); - } catch (MqttException ex) { - String errorMsg = "Initializing the MQTT Client failed."; - log.error(errorMsg, ex); - //TODO:: Throw the error out - } - options = new MqttConnectOptions(); - options.setKeepAliveInterval(120); // set the keep alive interval to 120 seconds by default. - options.setCleanSession(true); // sets clean session to true by default. - setDisconnectionWillForClient(QoS_2, true); // sets default will-topic & msg with QoS 2 and retained true. - client.setCallback(this); // callback for MQTT events are set to `this` object. - } - - /** - * @param qos the Quality of Service at which the last-will-message is to be published. - * @param isRetained indicate whether to retain the last-will-message. - * @see MQTTTransportHandler#setDisconnectionWillForClient(String, String, int, boolean). Uses the default values - * for Will-Topic and Will-Message. - */ - protected void setDisconnectionWillForClient(int qos, boolean isRetained) { - this.setDisconnectionWillForClient(clientWillTopic, DISCONNECTION_WILL_MSG, qos, isRetained); - } - - /** - * Sets the [Will] option in the default options-set of the MQTT Client. A will-topic, will-message is parsed - * along with the QoS and the retained flag. When the client loses its connection to the broker, the broker - * publishes the will-message to the will-topic, to itself. - * - * @param willTopic the topic to which the last will message is to be published when client exists ungracefully. - * @param willMsg the message to be published upon client's ungraceful exit from the broker. - * @param qos the Quality of Service at which the last-will-message is to be published. - * @param isRetained indicate whether to retain the last-will-message. - */ - protected void setDisconnectionWillForClient(String willTopic, String willMsg, int qos, boolean isRetained) { - this.options.setWill(willTopic, willMsg.getBytes(StandardCharsets.UTF_8), qos, isRetained); - } - - /** - * Sets the [Clean-Session] option in the default options-set of the MQTT Client. It is set to `true` by default. - * - * @param setCleanSession `true` indicates that the session details can be cleared/cleaned upon disconnection, - * `false` indicates that the session details are to be persisted if the client disconnects. - */ - @SuppressWarnings("unused") - protected void setClientCleanSession(boolean setCleanSession) { - this.options.setCleanSession(setCleanSession); - } - - /** - * Sets the [Username] & [Password] options in the default options-set of the MQTT Client. By default these - * values are not set. - * - * @param username the username to be used by the client to connect to the broker. - * @param password the password to be used by the client to connect to the broker. - */ - @SuppressWarnings("unused") - protected void setUsernameAndPassword(String username, String password) { - this.options.setUserName(username); - this.options.setPassword(password.toCharArray()); - } - - /** - * Connects to the MQTT-Broker at the endpoint specified in the constructor to this class using default the - * MQTT-options. - * - * @throws TransportHandlerException in the event of 'Connecting to' the MQTT broker fails. - */ - protected void connectToQueue() throws TransportHandlerException { - this.connectToQueue(options); - } - - /** - * Connects to the MQTT-Broker at the endpoint specified in the constructor to this class using the MQTT-Options - * passed. - * - * @param options options to be used by the client for this connection. (username, password, clean-session, etc) - * @throws TransportHandlerException in the event of 'Connecting to' the MQTT broker fails. - */ - protected void connectToQueue(MqttConnectOptions options) throws TransportHandlerException { - try { - client.connect(options); - if (log.isDebugEnabled()) { - log.debug("MQTT Client connected to queue at: " + this.mqttBrokerEndPoint); - } - } catch (MqttException ex) { - String errorMsg = "MQTT Exception occured whilst connecting to queue at [" + this.mqttBrokerEndPoint + "]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, ex); - } - } - - /** - * @throws TransportHandlerException in the event of 'Subscribing to' the MQTT broker fails. - * @see MQTTTransportHandler#subscribeToQueue(int). Uses default QoS of 1. - */ - protected void subscribeToQueue() throws TransportHandlerException { - this.subscribeToQueue(QoS_0); - } - - /** - * Subscribes to the MQTT-Topic specified in the constructor to this class. - * - * @throws TransportHandlerException in the event of 'Subscribing to' the MQTT broker fails. - */ - protected void subscribeToQueue(int qos) throws TransportHandlerException { - try { - client.subscribe(subscribeTopic, qos); - if (log.isDebugEnabled()) { - log.debug("Client [" + clientId + "] subscribed to topic: " + subscribeTopic); - } - } catch (MqttException ex) { - String errorMsg = "MQTT Exception occurred whilst client [" + clientId + "] tried to subscribe to " + - "topic: [" + subscribeTopic + "]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, ex); - } - } - - /** - * @param topic the topic to which the message is to be published. - * @param payLoad the message (payload) of the MQTT publish action. - * @see MQTTTransportHandler#publishToQueue(String, String, int, boolean) - */ - @SuppressWarnings("unused") - protected void publishToQueue(String topic, String payLoad) throws TransportHandlerException { - publishToQueue(topic, payLoad, DEFAULT_MQTT_QUALITY_OF_SERVICE, false); - } - - /** - * @param topic the topic to which the message is to be published. - * @param message the message (payload) of the MQTT publish action as a `MQTTMessage`. - * @throws TransportHandlerException if any error occurs whilst trying to publish to the MQTT Queue. - * @see MQTTTransportHandler#publishToQueue(String, String, int, boolean) - */ - protected void publishToQueue(String topic, MqttMessage message) throws TransportHandlerException { - if (!isConnected()) { - connectToQueue(); - } - 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 whilst client [" + clientId + "] tried to publish to queue at " + - "[" + mqttBrokerEndPoint + "] under topic [" + topic + "]"; - log.info(errorMsg); - throw new TransportHandlerException(errorMsg, ex); - } - } - - - /** - * This method is used to publish messages to the MQTT-Endpoint to which this client is connected to. It is via - * publishing to this broker that the messages are communicated to the device. This is an overloaded method with - * different parameter combinations. This method invokes the publish method provided by the MQTT-Client library. - * - * @param topic the topic to which the message is to be published. - * @param payLoad the 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) - * @param retained indicate whether to retain the publish-message in the event of no subscribers. - * @throws TransportHandlerException if any error occurs whilst trying to publish to the MQTT Queue. - */ - protected void publishToQueue(String topic, String payLoad, int qos, boolean retained) - throws TransportHandlerException { - 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 whilst client [" + clientId + "] tried to publish to queue at " + - "[" + mqttBrokerEndPoint + "] under topic [" + topic + "]"; - log.info(errorMsg); - throw new TransportHandlerException(errorMsg, ex); - } - } - - /** - * Checks whether the connection to the MQTT-Broker exists. - * - * @return `true` if the client is connected to the MQTT-Broker, else `false`. - */ - @Override - public boolean isConnected() { - return client.isConnected(); - } - - /** - * 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) { - if (log.isDebugEnabled()) { - log.warn("Connection for client: " + this.clientId + " to " + this.mqttBrokerEndPoint + " was lost." + - "\nThis was due to - " + throwable.getMessage()); - } - - Thread reconnectThread = new Thread() { - public void run() { - while(isConnected()) { - connect(); - } - } - }; - 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 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.debug("Got an MQTT message '" + mqttMessage.toString() + "' for topic '" + topic + "'."); - } - - Thread messageProcessorThread = new Thread() { - public void run() { - try { - processIncomingMessage(mqttMessage, topic); - } catch (TransportHandlerException e) { - log.error("An error occurred when trying to process received MQTT message [" + mqttMessage + "] " + - "for topic [" + topic + "].", e); - } - } - }; - 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 topic = iMqttDeliveryToken.getTopics()[0]; - String client = iMqttDeliveryToken.getClient().getClientId(); - - try { - if (iMqttDeliveryToken.isComplete()) { - if (log.isDebugEnabled()) { - if (iMqttDeliveryToken.getMessage() != null) { - String message = iMqttDeliveryToken.getMessage().toString(); - log.debug("Message to client [" + client + "] under topic (" + topic + - ") was delivered successfully with the delivery message: '" + message + "'"); - } else { - log.debug("Message to client [" + client + "] under topic (" + topic + - ") was delivered successfully."); - } - } - } else { - log.warn("FAILED: Delivery of MQTT message to [" + client + "] under topic [" + topic + "] failed."); - } - } catch (MqttException e) { - log.warn("Error occurred whilst trying to read the message from the MQTT delivery token."); - } - } - - /** - * Closes the connection to the MQTT Broker. - */ - public void closeConnection() throws MqttException { - if (client != null && isConnected()) { - client.disconnect(); - } - } - - /** - * Fetches the default options set for the MQTT Client - * - * @return the options that are currently set for the client. - */ - public MqttConnectOptions getOptions() { - return options; - } -} - diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/xmpp/XMPPTransportHandler.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/xmpp/XMPPTransportHandler.java deleted file mode 100644 index 3c9a2b419..000000000 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/xmpp/XMPPTransportHandler.java +++ /dev/null @@ -1,373 +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.transport.xmpp; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jivesoftware.smack.ConnectionConfiguration; -import org.jivesoftware.smack.PacketListener; -import org.jivesoftware.smack.SmackConfiguration; -import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; -import org.jivesoftware.smack.filter.AndFilter; -import org.jivesoftware.smack.filter.FromContainsFilter; -import org.jivesoftware.smack.filter.OrFilter; -import org.jivesoftware.smack.filter.PacketFilter; -import org.jivesoftware.smack.filter.PacketTypeFilter; -import org.jivesoftware.smack.filter.ToContainsFilter; -import org.jivesoftware.smack.packet.Message; -import org.jivesoftware.smack.packet.Packet; -import org.wso2.carbon.device.mgt.iot.transport.TransportHandler; -import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException; - -/** - * This is an abstract class that implements the "TransportHandler" interface. The interface is an abstraction for - * the core functionality with regards to device-server communication regardless of the Transport protocol. This - * specific class contains the HTTP-Transport specific implementations. The class implements utility methods for the - * case of a HTTP communication. However, this "abstract class", even-though it implements the "TransportHandler" - * interface, does not contain the logic relevant to the interface methods. The specific functionality of the - * interface methods are intended to be implemented by the concrete class that extends this abstract class and - * utilizes the HTTP specific functionality (ideally a device API writer who would like to communicate to the device - * via HTTP Protocol). - *

- * This class contains the IoT-Server specific implementation for all the XMPP functionality. This includes - * connecting to a XMPP Server & Login-In using the device's/server's XMPP-Account, Setting listeners and filters on - * incoming XMPP messages and Sending XMPP replies for messages received. Makes use of the 'Smack-XMPP' library - * provided by jivesoftware/igniterealtime. - */ -public abstract class XMPPTransportHandler implements TransportHandler { - - private static final Log log = LogFactory.getLog(XMPPTransportHandler.class); - protected String server; - protected int timeoutInterval; // millis - //TODO:: Shouldnt be hard-coded. Need to be read from configs - private static final int DEFAULT_XMPP_PORT = 5222; - private XMPPConnection connection; - private int port; - private PacketFilter filter; - private PacketListener listener; - - /** - * Constructor for XMPPTransportHandler passing only the server-IP. - * - * @param server the IP of the XMPP server. - */ - @SuppressWarnings("unused") - protected XMPPTransportHandler(String server) { - this.server = server; - this.port = DEFAULT_XMPP_PORT; - this.timeoutInterval = DEFAULT_TIMEOUT_INTERVAL; - initXMPPClient(); - } - - /** - * Constructor for XMPPTransportHandler passing server-IP and the XMPP-port. - * - * @param server the IP of the XMPP server. - * @param port the XMPP server's port to connect to. (default - 5222) - */ - protected XMPPTransportHandler(String server, int port) { - this.server = server; - this.port = port; - this.timeoutInterval = DEFAULT_TIMEOUT_INTERVAL; - initXMPPClient(); - } - - /** - * Constructor for XMPPTransportHandler passing server-IP, the XMPP-port and the - * timeoutInterval used by listeners to the server and for reconnection schedules. - * - * @param server the IP of the XMPP server. - * @param port the XMPP server's port to connect to. (default - 5222) - * @param timeoutInterval the timeout interval to use for the connection and reconnection - */ - @SuppressWarnings("unused") - protected XMPPTransportHandler(String server, int port, int timeoutInterval) { - this.server = server; - this.port = port; - this.timeoutInterval = timeoutInterval; - initXMPPClient(); - } - - /** - * Sets the client's time-out-limit whilst waiting for XMPP-replies from server. - * - * @param millis the time in millis to be set as the time-out-limit whilst waiting for a - * XMPP-reply. - */ - @SuppressWarnings("unused") - public void setTimeoutInterval(int millis) { - this.timeoutInterval = millis; - } - - /** - * Checks whether the connection to the XMPP-Server persists. - * - * @return true if the client is connected to the XMPP-Server, else false. - */ - @Override - public boolean isConnected() { - return connection.isConnected(); - } - - /** - * Initializes the XMPP Client. Sets the time-out-limit whilst waiting for XMPP-replies from - * server. Sets the XMPP configurations to connect to the server and creates the - * XMPPConnection object used for connecting and Logging-In. - */ - private void initXMPPClient() { - log.info(String.format("Initializing connection to XMPP Server at %1$s via port " + - "%2$d.", server, port)); - SmackConfiguration.setPacketReplyTimeout(timeoutInterval); - ConnectionConfiguration config = new ConnectionConfiguration(server, port); -// TODO:: Need to enable SASL-Authentication appropriately - config.setSASLAuthenticationEnabled(false); - config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled); - connection = new XMPPConnection(config); - } - -//TODO:: Re-check all exception handling - - /** - * Connects to the XMPP-Server and if attempt unsuccessful, then throws exception. - * - * @throws TransportHandlerException in the event of 'Connecting to' the XMPP server fails. - */ - protected void connectToServer() throws TransportHandlerException { - try { - connection.connect(); - log.info(String.format( - "Connection to XMPP Server at %1$s established successfully......", server)); - - } catch (XMPPException xmppExcepion) { - String errorMsg = - "Connection attempt to the XMPP Server at " + server + " via port " + port + - " failed."; - log.info(errorMsg); - throw new TransportHandlerException(errorMsg, xmppExcepion); - } - } - - /** - * If successfully established connection, then tries to Log in using the device's XMPP - * Account credentials. - * - * @param username the username of the device's XMPP-Account. - * @param password the password of the device's XMPP-Account. - * @param resource the resource the resource, specific to the XMPP-Account to which the login - * is made to - * @throws TransportHandlerException in the event of 'Logging into' the XMPP server fails. - */ - protected void loginToServer(String username, String password, String resource) - throws TransportHandlerException { - if (isConnected()) { - try { - if (resource == null) { - connection.login(username, password); - log.info(String.format("Logged into XMPP Server at %1$s as user %2$s......", - server, username)); - } else { - connection.login(username, password, resource); - log.info(String.format( - "Logged into XMPP Server at %1$s as user %2$s on resource %3$s......", - server, username, resource)); - } - } catch (XMPPException xmppException) { - String errorMsg = - "Login attempt to the XMPP Server at " + server + " with username - " + - username + " failed."; - log.info(errorMsg); - throw new TransportHandlerException(errorMsg, xmppException); - } - } else {//TODO:: Log not required - String errorMsg = - "Not connected to XMPP-Server to attempt Login. Please 'connectToServer' " + - "before Login"; - if (log.isDebugEnabled()) { - log.debug(errorMsg); - } - throw new TransportHandlerException(errorMsg); - } - } - - /** - * Sets a filter for all the incoming XMPP-Messages on the Sender's JID (XMPP-Account ID). - * Also creates a listener for the incoming messages and connects the listener to the - * XMPPConnection alongside the set filter. - * - * @param senderJID the JID (XMPP-Account ID of the sender) to which the filter is to be set. - */ - @SuppressWarnings("unused") - protected void setFilterOnSender(String senderJID) { - filter = new AndFilter(new PacketTypeFilter(Message.class), new FromContainsFilter( - senderJID)); - listener = new PacketListener() { - @Override - public void processPacket(Packet packet) { - if (packet instanceof Message) { - final Message xmppMessage = (Message) packet; - Thread msgProcessThread = new Thread() { - public void run() { - try { - processIncomingMessage(xmppMessage); - } catch (TransportHandlerException e) { - log.error("An error occurred when trying to process received XMPP message " + - "[" + xmppMessage.getBody() + "].", e); - } - } - }; - msgProcessThread.start(); - } - } - }; - connection.addPacketListener(listener, filter); - } - - /** - * Sets a filter for all the incoming XMPP-Messages on the Receiver's JID (XMPP-Account ID). - * Also creates a listener for the incoming messages and connects the listener to the - * XMPPConnection alongside the set filter. - * - * @param receiverJID the JID (XMPP-Account ID of the receiver) to which the filter is to be - * set. - */ - protected void setFilterOnReceiver(String receiverJID) { - filter = new AndFilter(new PacketTypeFilter(Message.class), new ToContainsFilter( - receiverJID)); - listener = new PacketListener() { - @Override - public void processPacket(Packet packet) { - if (packet instanceof Message) { - final Message xmppMessage = (Message) packet; - Thread msgProcessThread = new Thread() { - public void run() { - try { - processIncomingMessage(xmppMessage); - } catch (TransportHandlerException e) { - log.error("An error occurred when trying to process received XMPP message " + - "[" + xmppMessage.getBody() + "].", e); - } - } - }; - msgProcessThread.start(); - } - } - }; - connection.addPacketListener(listener, filter); - } - - /** - * Sets a filter for all the incoming XMPP-Messages on the From-JID & To-JID (XMPP-Account IDs) - * passed in. Also creates a listener for the incoming messages and connects the listener to - * the XMPPConnection alongside the set filter. - * - * @param senderJID the From-JID (XMPP-Account ID) to which the filter is to be set. - * @param receiverJID the To-JID (XMPP-Account ID) to which the filter is to be set. - * @param andCondition if true: then filter is set with 'AND' operator (senderJID && - * receiverJID), - * if false: then the filter is set with 'OR' operator (senderJID | - * receiverJID) - */ - @SuppressWarnings("unused") - protected void setMessageFilterAndListener(String senderJID, String receiverJID, boolean - andCondition) { - PacketFilter jidFilter; - - if (andCondition) { - jidFilter = new AndFilter(new FromContainsFilter(senderJID), new ToContainsFilter( - receiverJID)); - } else { - jidFilter = new OrFilter(new FromContainsFilter(senderJID), new ToContainsFilter( - receiverJID)); - } - - filter = new AndFilter(new PacketTypeFilter(Message.class), jidFilter); - listener = new PacketListener() { - @Override - public void processPacket(Packet packet) { - if (packet instanceof Message) { - final Message xmppMessage = (Message) packet; - Thread msgProcessThread = new Thread() { - public void run() { - try { - processIncomingMessage(xmppMessage); - } catch (TransportHandlerException e) { - log.error("An error occurred when trying to process received XMPP message " + - "[" + xmppMessage.getBody() + "].", e); - } - } - }; - msgProcessThread.start(); - } - } - }; - connection.addPacketListener(listener, filter); - } - - /** - * Sends an XMPP message. Calls the overloaded method with Subject set to "Reply-From-Device" - * - * @param JID the JID (XMPP Account ID) to which the message is to be sent to. - * @param message the XMPP-Message that is to be sent. - */ - @SuppressWarnings("unused") - protected void sendXMPPMessage(String JID, String message) { - sendXMPPMessage(JID, message, "XMPP-Message"); - } - - /** - * Overloaded method to send an XMPP message. Includes the subject to be mentioned in the - * message that is sent. - * - * @param JID the JID (XMPP Account ID) to which the message is to be sent to. - * @param message the XMPP-Message that is to be sent. - * @param subject the subject that the XMPP-Message would carry. - */ - protected void sendXMPPMessage(String JID, String message, String subject) { - Message xmppMessage = new Message(); - xmppMessage.setTo(JID); - xmppMessage.setSubject(subject); - xmppMessage.setBody(message); - xmppMessage.setType(Message.Type.chat); - sendXMPPMessage(JID, xmppMessage); - } - - /** - * Sends an XMPP message. - * - * @param JID the JID (XMPP Account ID) to which the message is to be sent to. - * @param xmppMessage the XMPP-Message that is to be sent. - */ - protected void sendXMPPMessage(String JID, Message xmppMessage) { - connection.sendPacket(xmppMessage); - if (log.isDebugEnabled()) { - log.debug("Message: '" + xmppMessage.getBody() + "' sent to XMPP JID [" + JID + "] sent successfully."); - } - } - - /** - * Closes the connection to the XMPP Server. - */ - public void closeConnection() { - if (connection != null && isConnected()) { - connection.disconnect(); - } - } - -} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/url/printer/URLPrinterStartupHandler.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/url/printer/URLPrinterStartupHandler.java new file mode 100644 index 000000000..d9cbc4ae7 --- /dev/null +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/url/printer/URLPrinterStartupHandler.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.iot.url.printer; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.core.ServerStartupObserver; +import org.wso2.carbon.device.mgt.iot.internal.IoTDeviceManagementDataHolder; +import org.wso2.carbon.utils.CarbonUtils; +import org.wso2.carbon.utils.ConfigurationContextService; +import org.wso2.carbon.utils.NetworkUtils; + +public class URLPrinterStartupHandler implements ServerStartupObserver { + private static final Log log = LogFactory.getLog(URLPrinterStartupHandler.class); + + @Override + public void completingServerStartup() { + } + + @Override + public void completedServerStartup() { + log.info("IoT Console URL : " + this.getIoTUrl()); + } + + private String getIoTUrl() { + // Hostname + String hostName = "localhost"; + try { + hostName = NetworkUtils.getMgtHostName(); + } catch (Exception ignored) { + } + // HTTPS port + String mgtConsoleTransport = CarbonUtils.getManagementTransport(); + ConfigurationContextService configContextService = + IoTDeviceManagementDataHolder.getInstance().getConfigurationContextService(); + int port = CarbonUtils.getTransportPort(configContextService, mgtConsoleTransport); + int httpsProxyPort = + CarbonUtils.getTransportProxyPort(configContextService.getServerConfigContext(), mgtConsoleTransport); + if (httpsProxyPort > 0) { + port = httpsProxyPort; + } + return "https://" + hostName + ":" + port + "/devicemgt"; + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/util/IoTUtil.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/util/IoTUtil.java index 8cc76e938..e9b4ed4f4 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/util/IoTUtil.java +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/util/IoTUtil.java @@ -18,73 +18,15 @@ package org.wso2.carbon.device.mgt.iot.util; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.SSLContextBuilder; -import org.apache.http.conn.ssl.TrustSelfSignedStrategy; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.util.EntityUtils; import org.wso2.carbon.base.ServerConfiguration; import org.wso2.carbon.device.mgt.iot.exception.IoTException; import org.wso2.carbon.utils.NetworkUtils; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; import java.net.SocketException; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; public class IoTUtil { public static final String HOST_NAME = "HostName"; - private static final Log log = LogFactory.getLog(IoTUtil.class); - private static final String HTTPS_PROTOCOL = "https"; - - /** - * Return a http client instance - * @param protocol- service endpoint protocol http/https - * @return - */ - public static HttpClient getHttpClient(int port, String protocol) - throws IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException { - HttpClient httpclient; - if (HTTPS_PROTOCOL.equals(protocol)) { - SSLContextBuilder builder = new SSLContextBuilder(); - builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); - SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build()); - httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); - } else { - httpclient = HttpClients.createDefault(); - } - return httpclient; - } - - public static String getResponseString(HttpResponse httpResponse) throws IOException { - BufferedReader br = null; - try { - br = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent())); - String readLine; - String response = ""; - while (((readLine = br.readLine()) != null)) { - response += readLine; - } - return response; - } finally { - EntityUtils.consumeQuietly(httpResponse.getEntity()); - if (br != null) { - try { - br.close(); - } catch (IOException e) { - log.warn("Error while closing the connection! " + e.getMessage()); - } - } - } - } public static String getHostName() throws IoTException { String hostName = ServerConfiguration.getInstance().getFirstProperty(HOST_NAME); diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/util/IotDeviceManagementUtil.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/util/IotDeviceManagementUtil.java index f1d14ff76..649f3acd9 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/util/IotDeviceManagementUtil.java +++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/util/IotDeviceManagementUtil.java @@ -22,13 +22,8 @@ import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.w3c.dom.Document; -import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.utils.CarbonUtils; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; import java.io.*; import java.nio.charset.StandardCharsets; import java.util.*; @@ -42,28 +37,6 @@ public class IotDeviceManagementUtil { private static final Log log = LogFactory.getLog(IotDeviceManagementUtil.class.getName()); - public static Document convertToDocument(File file) throws DeviceManagementException { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - try { - DocumentBuilder docBuilder = factory.newDocumentBuilder(); - return docBuilder.parse(file); - } catch (Exception e) { - throw new DeviceManagementException("Error occurred while parsing file, while converting " + - "to a org.w3c.dom.Document : " + e.getMessage(), e); - } - } - - private static Device.Property getProperty(String property, String value) { - if (property != null) { - Device.Property prop = new Device.Property(); - prop.setName(property); - prop.setValue(value); - return prop; - } - return null; - } - public static ZipArchive getSketchArchive(String archivesPath, String templateSketchPath, Map contextParams) throws DeviceManagementException, IOException { diff --git a/components/iot-plugins/iot-base-plugin/pom.xml b/components/iot-plugins/iot-base-plugin/pom.xml index 6c491e480..2c566887c 100644 --- a/components/iot-plugins/iot-base-plugin/pom.xml +++ b/components/iot-plugins/iot-base-plugin/pom.xml @@ -35,6 +35,12 @@ org.wso2.carbon.device.mgt.iot org.wso2.carbon.device.mgt.iot.ui + org.wso2.carbon.device.mgt.iot.output.adapter.mqtt + org.wso2.carbon.device.mgt.iot.output.adapter.xmpp + org.wso2.carbon.device.mgt.iot.input.adapter.extension + org.wso2.carbon.device.mgt.iot.input.adapter.http + org.wso2.carbon.device.mgt.iot.input.adapter.mqtt + org.wso2.carbon.device.mgt.iot.input.adapter.xmpp diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiControllerServiceImpl.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiControllerServiceImpl.java index 0756caaac..d4a8f747c 100644 --- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiControllerServiceImpl.java +++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiControllerServiceImpl.java @@ -26,13 +26,9 @@ import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants; -import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig; import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.dto.SensorRecord; -import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.transport.RaspberryPiMQTTConnector; import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util.APIUtil; import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants; -import org.wso2.carbon.device.mgt.iot.service.IoTServerStartupListener; -import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -43,14 +39,13 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; -import java.util.concurrent.ConcurrentHashMap; +import java.util.Map; public class RaspberryPiControllerServiceImpl implements RaspberryPiControllerService { private static Log log = LogFactory.getLog(RaspberryPiControllerServiceImpl.class); - private ConcurrentHashMap deviceToIpMap = new ConcurrentHashMap<>(); - private RaspberryPiMQTTConnector raspberryPiMQTTConnector; @Path("device/{deviceId}/bulb") @POST @@ -66,12 +61,14 @@ public class RaspberryPiControllerServiceImpl implements RaspberryPiControllerSe log.error("The requested state change shoud be either - 'ON' or 'OFF'"); return Response.status(Response.Status.BAD_REQUEST.getStatusCode()).build(); } - String mqttResource = RaspberrypiConstants.BULB_CONTEXT.replace("/", ""); - raspberryPiMQTTConnector.publishDeviceData(deviceId, mqttResource, switchToState); + String actualMessage = RaspberrypiConstants.BULB_CONTEXT + ":" + state; + Map dynamicProperties = new HashMap<>(); + String publishTopic = APIUtil.getTenantDomainOftheUser() + "/" + + RaspberrypiConstants.DEVICE_TYPE + "/" + deviceId; + dynamicProperties.put(RaspberrypiConstants.ADAPTER_TOPIC_PROPERTY, publishTopic); + APIUtil.getOutputEventAdapterService().publish(RaspberrypiConstants.MQTT_ADAPTER_NAME, + dynamicProperties, actualMessage); return Response.ok().build(); - } catch (TransportHandlerException e) { - log.error("Failed to send switch-bulb request to device [" + deviceId + "]"); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } catch (DeviceAccessAuthorizationException e) { log.error(e.getErrorMessage(), e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); @@ -109,44 +106,4 @@ public class RaspberryPiControllerServiceImpl implements RaspberryPiControllerSe } } - private boolean waitForServerStartup() { - while (!IoTServerStartupListener.isServerReady()) { - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - return true; - } - } - return false; - } - - public RaspberryPiMQTTConnector getRaspberryPiMQTTConnector() { - return raspberryPiMQTTConnector; - } - - public void setRaspberryPiMQTTConnector( - final RaspberryPiMQTTConnector raspberryPiMQTTConnector) { - Runnable connector = new Runnable() { - public void run() { - if (waitForServerStartup()) { - return; - } - //The delay is added for the server to starts up. - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - RaspberryPiControllerServiceImpl.this.raspberryPiMQTTConnector = raspberryPiMQTTConnector; - if (MqttConfig.getInstance().isEnabled()) { - raspberryPiMQTTConnector.connect(); - } else { - log.warn("MQTT disabled in 'devicemgt-config.xml'. Hence, RaspberryPiMQTTConnector not started."); - } - } - }; - Thread connectorThread = new Thread(connector); - connectorThread.start(); - } - } diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiManagerServiceImpl.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiManagerServiceImpl.java index d0c90e9f8..6dc2f3984 100644 --- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiManagerServiceImpl.java +++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiManagerServiceImpl.java @@ -29,10 +29,6 @@ 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.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.DeviceControllerException; import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants; import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util.APIUtil; import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util.ZipUtil; @@ -178,9 +174,6 @@ public class RaspberryPiManagerServiceImpl implements RaspberryPiManagerService } catch (APIManagerException ex) { log.error(ex.getMessage(), ex); return Response.status(500).entity(ex.getMessage()).build(); - } catch (DeviceControllerException ex) { - log.error(ex.getMessage(), ex); - return Response.status(500).entity(ex.getMessage()).build(); } catch (IOException ex) { log.error(ex.getMessage(), ex); return Response.status(500).entity(ex.getMessage()).build(); @@ -216,13 +209,13 @@ public class RaspberryPiManagerServiceImpl implements RaspberryPiManagerService } private ZipArchive createDownloadFile(String owner, String deviceName, String sketchType) - throws DeviceManagementException, JWTClientException, APIManagerException, DeviceControllerException, + throws DeviceManagementException, JWTClientException, APIManagerException, UserStoreException { //create new device id String deviceId = shortUUID(); if (apiApplicationKey == null) { - String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm().getRealmConfiguration() - .getAdminUserName(); + String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminUserName(); APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService(); String[] tags = {RaspberrypiConstants.DEVICE_TYPE}; apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys( @@ -235,27 +228,7 @@ public class RaspberryPiManagerServiceImpl implements RaspberryPiManagerService //create token String accessToken = accessTokenInfo.getAccessToken(); String refreshToken = accessTokenInfo.getRefreshToken(); - //adding registering data - XmppAccount newXmppAccount = new XmppAccount(); - newXmppAccount.setAccountName(owner + "_" + deviceId); - newXmppAccount.setUsername(deviceId); - newXmppAccount.setPassword(accessToken); - newXmppAccount.setEmail(deviceId + "@wso2.com"); - XmppServerClient xmppServerClient = new XmppServerClient(); - xmppServerClient.initControlQueue(); - boolean status; - if (XmppConfig.getInstance().isEnabled()) { - status = xmppServerClient.createXMPPAccount(newXmppAccount); - if (!status) { - String msg = "XMPP Account was not created for device - " + deviceId + " of owner - " + owner + - ".XMPP might have been disabled in org.wso2.carbon.device.mgt.iot.common.config" + - ".server.configs"; - log.warn(msg); - throw new DeviceManagementException(msg); - } - } - //Register the device with CDMF - status = register(deviceId, deviceName); + boolean status = register(deviceId, deviceName); if (!status) { String msg = "Error occurred while registering the device with " + "id: " + deviceId + " owner:" + owner; throw new DeviceManagementException(msg); diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/transport/RaspberryPiMQTTConnector.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/transport/RaspberryPiMQTTConnector.java deleted file mode 100644 index 48c874fc4..000000000 --- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/transport/RaspberryPiMQTTConnector.java +++ /dev/null @@ -1,189 +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.raspberrypi.service.impl.transport; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttMessage; -import org.json.JSONObject; -import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService; -import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey; -import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException; -import org.wso2.carbon.context.PrivilegedCarbonContext; -import org.wso2.carbon.device.mgt.common.Device; -import org.wso2.carbon.device.mgt.common.DeviceIdentifier; -import org.wso2.carbon.device.mgt.common.DeviceManagementException; -import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; -import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig; -import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.exception.RaspberrypiException; -import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util.APIUtil; -import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants; -import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException; -import org.wso2.carbon.device.mgt.iot.transport.mqtt.MQTTTransportHandler; -import org.wso2.carbon.identity.jwt.client.extension.JWTClient; -import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; -import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; -import org.wso2.carbon.user.api.UserStoreException; - -import java.nio.charset.StandardCharsets; -import java.security.PublicKey; -import java.util.UUID; - -public class RaspberryPiMQTTConnector extends MQTTTransportHandler { - private static Log log = LogFactory.getLog(RaspberryPiMQTTConnector.class); -// subscribeTopic is not used for the RaspberryPi sample since the DAS device directly publishes to DAS MQTT receiver - private static final String subscribeTopic = "wso2/+/"+ RaspberrypiConstants.DEVICE_TYPE + "/+/publisher"; - private static final String KEY_TYPE = "PRODUCTION"; - private static final String EMPTY_STRING = ""; - - private static final String iotServerSubscriber = UUID.randomUUID().toString().substring(0, 5); - - private RaspberryPiMQTTConnector() { - super(iotServerSubscriber, RaspberrypiConstants.DEVICE_TYPE, - MqttConfig.getInstance().getMqttQueueEndpoint(), subscribeTopic); - } - - @Override - public void connect() { - Runnable connector = new Runnable() { - public void run() { - while (!isConnected()) { - PrivilegedCarbonContext.startTenantFlow(); - PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain( - RaspberrypiConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true); - try { - String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() - .getRealmConfiguration().getAdminUserName(); - PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(applicationUsername); - APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService(); - String[] tags = {RaspberrypiConstants.DEVICE_TYPE}; - ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys( - RaspberrypiConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true); - JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient(); - String scopes = "device_type_" + RaspberrypiConstants.DEVICE_TYPE + " device_mqtt_connector"; - AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(), - apiApplicationKey.getConsumerSecret(), applicationUsername, scopes); - //create token - String accessToken = accessTokenInfo.getAccessToken(); - setUsernameAndPassword(accessToken, EMPTY_STRING); - connectToQueue(); - } catch (TransportHandlerException e) { - log.error("Connection/Subscription to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e); - try { - Thread.sleep(timeoutInterval); - } catch (InterruptedException ex) { - log.error("MQTT-Connector: Thread Sleep Interrupt Exception.", ex); - } - } catch (JWTClientException e) { - log.error("Failed to retrieve token from JWT Client.", e); - return; - } catch (UserStoreException e) { - log.error("Failed to retrieve the user.", e); - return; - } catch (APIManagerException e) { - log.error("Failed to create an application and generate keys.", e); - return; - } finally { - PrivilegedCarbonContext.endTenantFlow(); - } - } - } - }; - - Thread connectorThread = new Thread(connector); - connectorThread.start(); - } - - @Override - public void publishDeviceData(String... publishData) throws TransportHandlerException { - if (publishData.length != 3) { - String errorMsg = "Incorrect number of arguments received to SEND-MQTT Message. " + - "Need to be [owner, deviceId, resource{BULB/TEMP}, state{ON/OFF or null}]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg); - } - - String deviceId = publishData[0]; - String resource = publishData[1]; - String state = publishData[2]; - - MqttMessage pushMessage = new MqttMessage(); - String publishTopic = "wso2/" + APIUtil.getTenantDomainOftheUser() + "/" - + RaspberrypiConstants.DEVICE_TYPE + "/" + deviceId; - String actualMessage = resource + ":" + state; - pushMessage.setPayload(actualMessage.getBytes(StandardCharsets.UTF_8)); - pushMessage.setQos(DEFAULT_MQTT_QUALITY_OF_SERVICE); - pushMessage.setRetained(false); - publishToQueue(publishTopic, pushMessage); - } - - @Override - public void disconnect() { - Runnable stopConnection = new Runnable() { - public void run() { - while (isConnected()) { - try { - closeConnection(); - } catch (MqttException e) { - if (log.isDebugEnabled()) { - log.warn("Unable to 'STOP' MQTT connection at broker at: " + mqttBrokerEndPoint - + " for device-type - " + RaspberrypiConstants.DEVICE_TYPE, e); - } - - try { - Thread.sleep(timeoutInterval); - } catch (InterruptedException e1) { - log.error("MQTT-Terminator: Thread Sleep Interrupt Exception at device-type - " + - RaspberrypiConstants.DEVICE_TYPE, e1); - } - } - } - } - }; - - Thread terminatorThread = new Thread(stopConnection); - terminatorThread.start(); - } - - @Override - public void processIncomingMessage(MqttMessage mqttMessage, String... messageParams) throws TransportHandlerException { - } - - @Override - public void processIncomingMessage() throws TransportHandlerException { - - } - - @Override - public void processIncomingMessage(MqttMessage message) throws TransportHandlerException { - - } - - @Override - public void publishDeviceData() throws TransportHandlerException { - - } - - @Override - public void publishDeviceData(MqttMessage publishData) throws TransportHandlerException { - - } -} - diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/APIUtil.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/APIUtil.java index 5f10bcb5b..01e8281ec 100644 --- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/APIUtil.java +++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/APIUtil.java @@ -16,6 +16,7 @@ import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.dto.SensorRecord; +import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService; import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; import java.util.ArrayList; @@ -168,5 +169,16 @@ public class APIUtil { return deviceAccessAuthorizationService; } + public static OutputEventAdapterService getOutputEventAdapterService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + OutputEventAdapterService outputEventAdapterService = + (OutputEventAdapterService) ctx.getOSGiService(OutputEventAdapterService.class, null); + if (outputEventAdapterService == null) { + String msg = "Device Authorization service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return outputEventAdapterService; + } } diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipUtil.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipUtil.java index daff8d058..d8e1e4124 100644 --- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipUtil.java +++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipUtil.java @@ -19,9 +19,8 @@ package org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util; import org.wso2.carbon.device.mgt.common.DeviceManagementException; -import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig; -import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig; import org.wso2.carbon.device.mgt.iot.exception.IoTException; +import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.mqtt.MqttConfig; import org.wso2.carbon.device.mgt.iot.util.IoTUtil; import org.wso2.carbon.device.mgt.iot.util.IotDeviceManagementUtil; import org.wso2.carbon.device.mgt.iot.util.ZipArchive; @@ -61,19 +60,13 @@ public class ZipUtil { String httpsServerEP = HTTPS_PROTOCOL_APPENDER + iotServerIP + ":" + httpsServerPort; String httpServerEP = HTTP_PROTOCOL_APPENDER + iotServerIP + ":" + httpServerPort; String apimEndpoint = httpsServerEP; - String mqttEndpoint = MqttConfig.getInstance().getMqttQueueEndpoint(); + String mqttEndpoint = MqttConfig.getInstance().getBrokerEndpoint(); if (mqttEndpoint.contains(LOCALHOST)) { mqttEndpoint = mqttEndpoint.replace(LOCALHOST, iotServerIP); } - String xmppEndpoint = XmppConfig.getInstance().getXmppEndpoint(); - int indexOfChar = xmppEndpoint.lastIndexOf(":"); - if (indexOfChar != -1) { - xmppEndpoint = xmppEndpoint.substring(0, indexOfChar); - } - xmppEndpoint = xmppEndpoint + ":" + XmppConfig.getInstance().getSERVER_CONNECTION_PORT(); Map contextParams = new HashMap<>(); - contextParams.put("SERVER_NAME", "wso2/" + APIUtil.getTenantDomainOftheUser()); + contextParams.put("SERVER_NAME", APIUtil.getTenantDomainOftheUser()); contextParams.put("DEVICE_OWNER", owner); contextParams.put("DEVICE_ID", deviceId); contextParams.put("DEVICE_NAME", deviceName); @@ -81,7 +74,6 @@ public class ZipUtil { contextParams.put("HTTP_EP", httpServerEP); contextParams.put("APIM_EP", apimEndpoint); contextParams.put("MQTT_EP", mqttEndpoint); - contextParams.put("XMPP_EP", xmppEndpoint); contextParams.put("DEVICE_TOKEN", token); contextParams.put("DEVICE_REFRESH_TOKEN", refreshToken); diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/webapp/WEB-INF/cxf-servlet.xml index ab4f105d7..727225322 100644 --- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/webapp/WEB-INF/cxf-servlet.xml +++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -29,7 +29,6 @@ - @@ -39,9 +38,4 @@ - - - - diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/pom.xml b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/pom.xml index bd822b57a..1c0e351ee 100644 --- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/pom.xml +++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/pom.xml @@ -71,7 +71,13 @@ org.wso2.carbon.device.mgt.common, org.wso2.carbon.device.mgt.iot.*, org.wso2.carbon.device.mgt.extensions.feature.mgt.*, - org.wso2.carbon.utils.* + org.wso2.carbon.utils.*, + org.wso2.carbon.base, + org.wso2.carbon.context, + org.wso2.carbon.core, + org.wso2.carbon.core.util, + org.wso2.carbon.event.output.adapter.core, + org.wso2.carbon.event.output.adapter.core.exception !org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.internal, @@ -112,5 +118,9 @@ org.wso2.carbon org.wso2.carbon.utils + + org.wso2.carbon.analytics-common + org.wso2.carbon.event.output.adapter.core + \ No newline at end of file diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/constants/RaspberrypiConstants.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/constants/RaspberrypiConstants.java index a301ac6fb..0a99f61cc 100644 --- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/constants/RaspberrypiConstants.java +++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/constants/RaspberrypiConstants.java @@ -18,6 +18,10 @@ package org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants; +import org.wso2.carbon.utils.CarbonUtils; + +import java.io.File; + public class RaspberrypiConstants { public final static String DEVICE_TYPE = "raspberrypi"; @@ -27,7 +31,7 @@ public class RaspberrypiConstants { public final static String STATE_OFF = "OFF"; public static final String URL_PREFIX = "http://"; - public static final String BULB_CONTEXT = "/BULB/"; + public static final String BULB_CONTEXT = "BULB"; public static final String TEMPERATURE_CONTEXT = "/TEMPERATURE/"; //type of the sensor @@ -37,4 +41,27 @@ public class RaspberrypiConstants { public static final String DATA_SOURCE_NAME = "jdbc/RaspberryPiDM_DB"; public final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super"; + //mqtt tranport related constants + public static final String MQTT_ADAPTER_NAME = "raspberrypi_mqtt"; + public static final String MQTT_ADAPTER_TYPE = "oauth-mqtt"; + public static final String ADAPTER_TOPIC_PROPERTY = "topic"; + public static final String MQTT_PORT = "\\$\\{mqtt.broker.port\\}"; + public static final String MQTT_BROKER_HOST = "\\$\\{mqtt.broker.host\\}"; + public static final String CARBON_CONFIG_PORT_OFFSET = "Ports.Offset"; + public static final String DEFAULT_CARBON_LOCAL_IP_PROPERTY = "carbon.local.ip"; + public static final int CARBON_DEFAULT_PORT_OFFSET = 0; + public static final int DEFAULT_MQTT_PORT = 1883; + + public static final String USERNAME_PROPERTY_KEY = "username"; + public static final String DCR_PROPERTY_KEY = "dcrUrl"; + public static final String BROKER_URL_PROPERTY_KEY = "url"; + public static final String SCOPES_PROPERTY_KEY = "scopes"; + public static final String QOS_PROPERTY_KEY = "qos"; + public static final String CLIENT_ID_PROPERTY_KEY = "qos"; + public static final String CLEAR_SESSION_PROPERTY_KEY = "clearSession"; + public static final String TOPIC = "topic"; + + public static final String MQTT_CONFIG_LOCATION = CarbonUtils.getEtcCarbonConfigDirPath() + File.separator + + "mqtt.properties"; + } diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/RaspberrypiManagerService.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/RaspberrypiManagerService.java index 07b69c6c9..f180226c7 100644 --- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/RaspberrypiManagerService.java +++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/RaspberrypiManagerService.java @@ -52,7 +52,7 @@ public class RaspberrypiManagerService implements DeviceManagementService { @Override public ProvisioningConfig getProvisioningConfig() { - return new ProvisioningConfig(RaspberrypiConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true); + return new ProvisioningConfig(RaspberrypiConstants.DEVICE_TYPE_PROVIDER_DOMAIN, false); } @Override diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/service/IoTServerStartupListener.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/util/RaspberrypiStartupListener.java similarity index 57% rename from components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/service/IoTServerStartupListener.java rename to components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/util/RaspberrypiStartupListener.java index 22fd657cc..3a5abac45 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/service/IoTServerStartupListener.java +++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/util/RaspberrypiStartupListener.java @@ -16,26 +16,31 @@ * under the License. */ -package org.wso2.carbon.device.mgt.iot.service; +package org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl.util; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.wso2.carbon.core.ServerStartupObserver; -public class IoTServerStartupListener implements ServerStartupObserver { - private static volatile boolean serverReady = false; +import java.io.IOException; + +/** + * Startup listener to create an output adapter after server starts up. + */ +public class RaspberrypiStartupListener implements ServerStartupObserver { + private static final Log log = LogFactory.getLog(RaspberrypiStartupListener.class); + @Override public void completingServerStartup() { } @Override public void completedServerStartup() { - IoTServerStartupListener.setServerReady(true); + try { + RaspberrypiUtils.setupMqttOutputAdapter(); + } catch (IOException e) { + log.error("Failed to intilaize the virtual firealarm output adapter", e); + } } - public static boolean isServerReady() { - return IoTServerStartupListener.serverReady; - } - - public static void setServerReady(boolean serverReady) { - IoTServerStartupListener.serverReady = serverReady; - } } diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/util/RaspberrypiUtils.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/util/RaspberrypiUtils.java index bd0858141..791f1db03 100644 --- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/util/RaspberrypiUtils.java +++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/util/RaspberrypiUtils.java @@ -20,20 +20,30 @@ package org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl.util; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.base.ServerConfiguration; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.core.util.Utils; import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants; import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.exception.RaspberrypiDeviceMgtPluginException; +import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.internal.RaspberrypiManagementDataHolder; +import org.wso2.carbon.event.output.adapter.core.MessageType; +import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration; +import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.List; +import java.util.HashMap; import java.util.Map; +import java.util.Properties; /** * Contains utility methods used by Raspberrypi plugin. @@ -42,26 +52,6 @@ public class RaspberrypiUtils { private static Log log = LogFactory.getLog(RaspberrypiUtils.class); - public static String getDeviceProperty(List deviceProperties, String propertyKey) { - String deviceProperty = ""; - for(Device.Property property :deviceProperties){ - if(propertyKey.equals(property.getName())){ - deviceProperty = property.getValue(); - } - } - return deviceProperty; - } - - public static Device.Property getProperty(String property, String value) { - if (property != null) { - Device.Property prop = new Device.Property(); - prop.setName(property); - prop.setValue(value); - return prop; - } - return null; - } - public static void cleanupResources(Connection conn, PreparedStatement stmt, ResultSet rs) { if (rs != null) { try { @@ -108,4 +98,84 @@ public class RaspberrypiUtils { "Management database schema", e); } } + + public static void setupMqttOutputAdapter() throws IOException { + OutputEventAdapterConfiguration outputEventAdapterConfiguration = + createMqttOutputEventAdapterConfiguration(RaspberrypiConstants.MQTT_ADAPTER_NAME, + RaspberrypiConstants.MQTT_ADAPTER_TYPE, MessageType.TEXT); + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain( + RaspberrypiConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true); + RaspberrypiManagementDataHolder.getInstance().getOutputEventAdapterService() + .create(outputEventAdapterConfiguration); + } catch (OutputEventAdapterException e) { + log.error("Unable to create Output Event Adapter : " + RaspberrypiConstants.MQTT_ADAPTER_NAME, e); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } + + /** + * Create Output Event Adapter Configuration for given configuration. + * + * @param name Output Event Adapter name + * @param type Output Event Adapter type + * @param msgFormat Output Event Adapter message format + * @return OutputEventAdapterConfiguration instance for given configuration + */ + private static OutputEventAdapterConfiguration createMqttOutputEventAdapterConfiguration(String name, String type, + String msgFormat) throws IOException { + OutputEventAdapterConfiguration outputEventAdapterConfiguration = new OutputEventAdapterConfiguration(); + outputEventAdapterConfiguration.setName(name); + outputEventAdapterConfiguration.setType(type); + outputEventAdapterConfiguration.setMessageFormat(msgFormat); + File configFile = new File(RaspberrypiConstants.MQTT_CONFIG_LOCATION); + if (configFile.exists()) { + Map mqttAdapterProperties = new HashMap<>(); + InputStream propertyStream = configFile.toURI().toURL().openStream(); + Properties properties = new Properties(); + properties.load(propertyStream); + mqttAdapterProperties.put(RaspberrypiConstants.USERNAME_PROPERTY_KEY, properties.getProperty( + RaspberrypiConstants.USERNAME_PROPERTY_KEY)); + mqttAdapterProperties.put(RaspberrypiConstants.DCR_PROPERTY_KEY, Utils.replaceSystemProperty( + properties.getProperty(RaspberrypiConstants.DCR_PROPERTY_KEY))); + mqttAdapterProperties.put(RaspberrypiConstants.BROKER_URL_PROPERTY_KEY, replaceMqttProperty( + properties.getProperty(RaspberrypiConstants.BROKER_URL_PROPERTY_KEY))); + mqttAdapterProperties.put(RaspberrypiConstants.SCOPES_PROPERTY_KEY, properties.getProperty( + RaspberrypiConstants.SCOPES_PROPERTY_KEY)); + mqttAdapterProperties.put(RaspberrypiConstants.CLEAR_SESSION_PROPERTY_KEY, properties.getProperty( + RaspberrypiConstants.CLEAR_SESSION_PROPERTY_KEY)); + mqttAdapterProperties.put(RaspberrypiConstants.QOS_PROPERTY_KEY, properties.getProperty( + RaspberrypiConstants.QOS_PROPERTY_KEY)); + mqttAdapterProperties.put(RaspberrypiConstants.CLIENT_ID_PROPERTY_KEY, ""); + outputEventAdapterConfiguration.setStaticProperties(mqttAdapterProperties); + } + return outputEventAdapterConfiguration; + } + + public static String replaceMqttProperty(String urlWithPlaceholders) { + urlWithPlaceholders = Utils.replaceSystemProperty(urlWithPlaceholders); + urlWithPlaceholders = urlWithPlaceholders.replaceAll(RaspberrypiConstants.MQTT_PORT, "" + + (RaspberrypiConstants.DEFAULT_MQTT_PORT + getPortOffset())); + urlWithPlaceholders = urlWithPlaceholders.replaceAll(RaspberrypiConstants.MQTT_BROKER_HOST, + System.getProperty(RaspberrypiConstants.DEFAULT_CARBON_LOCAL_IP_PROPERTY, "localhost")); + return urlWithPlaceholders; + } + + private static int getPortOffset() { + ServerConfiguration carbonConfig = ServerConfiguration.getInstance(); + String portOffset = System.getProperty("portOffset", carbonConfig.getFirstProperty( + RaspberrypiConstants.CARBON_CONFIG_PORT_OFFSET)); + try { + if ((portOffset != null)) { + return Integer.parseInt(portOffset.trim()); + } else { + return RaspberrypiConstants.CARBON_DEFAULT_PORT_OFFSET; + } + } catch (NumberFormatException e) { + return RaspberrypiConstants.CARBON_DEFAULT_PORT_OFFSET; + } + } + } diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/internal/RaspberrypiManagementDataHolder.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/internal/RaspberrypiManagementDataHolder.java new file mode 100644 index 000000000..0680c88bf --- /dev/null +++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/internal/RaspberrypiManagementDataHolder.java @@ -0,0 +1,48 @@ +/* + * 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.plugin.internal; + +import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService; + +/** + * DataHolder class of plugins component. + */ +public class RaspberrypiManagementDataHolder { + + private OutputEventAdapterService outputEventAdapterService; + + private static RaspberrypiManagementDataHolder thisInstance = new RaspberrypiManagementDataHolder(); + + private RaspberrypiManagementDataHolder() { + } + + public static RaspberrypiManagementDataHolder getInstance() { + return thisInstance; + } + + public OutputEventAdapterService getOutputEventAdapterService() { + return outputEventAdapterService; + } + + public void setOutputEventAdapterService( + OutputEventAdapterService outputEventAdapterService) { + this.outputEventAdapterService = outputEventAdapterService; + } + +} diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/internal/RaspberrypiManagementServiceComponent.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/internal/RaspberrypiManagementServiceComponent.java index 0b78f2d85..5068ae3d3 100644 --- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/internal/RaspberrypiManagementServiceComponent.java +++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/internal/RaspberrypiManagementServiceComponent.java @@ -23,14 +23,23 @@ import org.apache.commons.logging.LogFactory; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.osgi.service.component.ComponentContext; +import org.wso2.carbon.core.ServerStartupObserver; import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService; import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.exception.RaspberrypiDeviceMgtPluginException; import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl.RaspberrypiManagerService; +import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl.util.RaspberrypiStartupListener; import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl.util.RaspberrypiUtils; +import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService; /** * @scr.component name="org.wso2.carbon.device.mgt.iot.raspberrypi.internal.RaspberrypiManagementServiceComponent" * immediate="true" + * @scr.reference name="event.output.adapter.service" + * interface="org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService" + * cardinality="1..1" + * policy="dynamic" + * bind="setOutputEventAdapterService" + * unbind="unsetOutputEventAdapterService" */ public class RaspberrypiManagementServiceComponent { @@ -46,6 +55,8 @@ public class RaspberrypiManagementServiceComponent { raspberrypiServiceRegRef = bundleContext.registerService(DeviceManagementService.class.getName(), new RaspberrypiManagerService(), null); + bundleContext.registerService(ServerStartupObserver.class.getName(), new RaspberrypiStartupListener(), + null); String setupOption = System.getProperty("setup"); if (setupOption != null) { if (log.isDebugEnabled()) { @@ -82,4 +93,21 @@ public class RaspberrypiManagementServiceComponent { log.error("Error occurred while de-activating Raspberrypi Device Management bundle", e); } } + + /** + * Initialize the Output EventAdapter Service dependency + * + * @param outputEventAdapterService Output EventAdapter Service reference + */ + protected void setOutputEventAdapterService(OutputEventAdapterService outputEventAdapterService) { + RaspberrypiManagementDataHolder.getInstance().setOutputEventAdapterService(outputEventAdapterService); + } + + /** + * De-reference the Output EventAdapter Service dependency. + */ + protected void unsetOutputEventAdapterService(OutputEventAdapterService outputEventAdapterService) { + RaspberrypiManagementDataHolder.getInstance().setOutputEventAdapterService(null); + } + } diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/mqtt/MqttConfig.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/mqtt/MqttConfig.java new file mode 100644 index 000000000..e2e78bdb0 --- /dev/null +++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/mqtt/MqttConfig.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.mqtt; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants; +import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl.util.RaspberrypiUtils; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +public class MqttConfig { + + private static String brokerEndpoint; + + private static MqttConfig mqttConfig = new MqttConfig(); + private static final Log log = LogFactory.getLog(MqttConfig.class); + + private MqttConfig() { + File configFile = new File(RaspberrypiConstants.MQTT_CONFIG_LOCATION); + if (configFile.exists()) { + try { + InputStream propertyStream = configFile.toURI().toURL().openStream(); + Properties properties = new Properties(); + properties.load(propertyStream); + brokerEndpoint = RaspberrypiUtils.replaceMqttProperty( + properties.getProperty(RaspberrypiConstants.BROKER_URL_PROPERTY_KEY)); + } catch (IOException e) { + log.error("Failed to read the mqtt.properties file" + e); + } + } + } + + public static MqttConfig getInstance() { + return mqttConfig; + } + + public String getBrokerEndpoint() { + return brokerEndpoint; + } +} diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/advanced/communication/xmpp/FireAlarmXMPPCommunicator.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/advanced/communication/xmpp/FireAlarmXMPPCommunicator.java index a037ecd9e..f1fe40bd9 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/advanced/communication/xmpp/FireAlarmXMPPCommunicator.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/advanced/communication/xmpp/FireAlarmXMPPCommunicator.java @@ -196,7 +196,7 @@ public class FireAlarmXMPPCommunicator extends XMPPTransportHandler { String payLoad = AgentUtilOperations.prepareSecurePayLoad(message); xmppMessage.setTo(xmppAdminJID); - xmppMessage.setSubject("PUBLISHER"); + xmppMessage.setSubject(agentManager.getAgentConfigs().getTenantDomain()); xmppMessage.setBody(payLoad); xmppMessage.setType(Message.Type.chat); diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/advanced/core/AgentConstants.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/advanced/core/AgentConstants.java index b20161884..09975cde4 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/advanced/core/AgentConstants.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/advanced/core/AgentConstants.java @@ -57,8 +57,8 @@ public class AgentConstants { --------------------------------------------------------------------------------------- */ public static final int DEFAULT_MQTT_RECONNECTION_INTERVAL = 2; // time in seconds public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0; - public static final String MQTT_SUBSCRIBE_TOPIC = "wso2/%s/" + DEVICE_TYPE + "/%s"; - public static final String MQTT_PUBLISH_TOPIC = "wso2/%s/" + DEVICE_TYPE + "/%s/publisher"; + public static final String MQTT_SUBSCRIBE_TOPIC = "%s/" + DEVICE_TYPE + "/%s"; + public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/publisher"; /* --------------------------------------------------------------------------------------- XMPP Connection specific information --------------------------------------------------------------------------------------- */ diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/advanced/transport/TransportUtils.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/advanced/transport/TransportUtils.java index a9b6676a3..5045e4313 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/advanced/transport/TransportUtils.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/advanced/transport/TransportUtils.java @@ -67,7 +67,7 @@ public class TransportUtils { } ipPortMap.put("Protocol", ipPortArray[0]); - ipPortMap.put("Host", ipPortArray[1].replace(File.separator, "")); + ipPortMap.put("Host", ipPortArray[1].replace("/", "")); ipPortMap.put("Port", ipPortArray[2]); return ipPortMap; } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/communication/xmpp/FireAlarmXMPPCommunicator.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/communication/xmpp/FireAlarmXMPPCommunicator.java index 0267f8d6b..b29cd492e 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/communication/xmpp/FireAlarmXMPPCommunicator.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/communication/xmpp/FireAlarmXMPPCommunicator.java @@ -196,7 +196,7 @@ public class FireAlarmXMPPCommunicator extends XMPPTransportHandler { String payLoad = AgentUtilOperations.prepareSecurePayLoad(message); xmppMessage.setTo(xmppAdminJID); - xmppMessage.setSubject("PUBLISHER"); + xmppMessage.setSubject(agentManager.getAgentConfigs().getTenantDomain()); xmppMessage.setBody(payLoad); xmppMessage.setType(Message.Type.chat); diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConstants.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConstants.java index ae3548811..1a9771b8e 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConstants.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConstants.java @@ -56,8 +56,8 @@ public class AgentConstants { --------------------------------------------------------------------------------------- */ public static final int DEFAULT_MQTT_RECONNECTION_INTERVAL = 2; // time in seconds public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0; - public static final String MQTT_SUBSCRIBE_TOPIC = "wso2/%s/" + DEVICE_TYPE + "/%s"; - public static final String MQTT_PUBLISH_TOPIC = "wso2/%s/" + DEVICE_TYPE + "/%s/publisher"; + public static final String MQTT_SUBSCRIBE_TOPIC = "%s/" + DEVICE_TYPE + "/%s"; + public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/publisher"; /* --------------------------------------------------------------------------------------- XMPP Connection specific information --------------------------------------------------------------------------------------- */ diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/transport/TransportUtils.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/transport/TransportUtils.java index a5c20bbf0..050b8a578 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/transport/TransportUtils.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/transport/TransportUtils.java @@ -68,7 +68,7 @@ public class TransportUtils { } ipPortMap.put("Protocol", ipPortArray[0]); - ipPortMap.put("Host", ipPortArray[1].replace(File.separator, "")); + ipPortMap.put("Host", ipPortArray[1].replace("/", "")); ipPortMap.put("Port", ipPortArray[2]); return ipPortMap; } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmControllerService.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmControllerService.java index 63b193889..3bbbe3ad4 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmControllerService.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmControllerService.java @@ -22,12 +22,8 @@ import org.wso2.carbon.apimgt.annotations.api.API; import org.wso2.carbon.apimgt.annotations.api.Permission; import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.DeviceType; import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.Feature; -import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.DeviceData; -import javax.servlet.http.HttpServletRequest; import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; /** @@ -41,27 +37,6 @@ import javax.ws.rs.core.Response; @DeviceType(value = "virtual_firealarm") public interface VirtualFireAlarmControllerService { - /** - * This is an API used/called by the device. It registers the IP of a VirtualFirealarm device against its DeviceID - * when the device connects with the server for the first time. This DeviceID to IP mapping is necessary only for - * cases where HTTP communication is to be used. At such instances, this mapping is used by the server to - * identify the IP of the device to which it has some message to be sent. This method becomes useful only in - * scenarios where HTTP communication is used in a setup where the IoT-Server and the devices communicating with it - * are in the same IP network. - * - * @param deviceId the ID of the VirtualFirealarm device from which this register-IP call was initiated. - * @param deviceIP the IP of the VirtualFirealarm device which has sent this register-IP request. - * @param devicePort the PORT on the VirtualFirealarm device (on this IP) that's open for HTTP communication. - * @param request the HTTP servlet request object received by default as part of the HTTP call to this API. - * @return a custom message indicating whether the DeviceID to IP mapping was successful. - */ - @POST - @Path("device/register/{deviceId}/{ip}/{port}") - @Permission(scope = "virtual_firealarm_admin", permissions = {"device-mgt/virtual_firealarm/admin"}) - Response registerDeviceIP(@PathParam("deviceId") String deviceId, @PathParam("ip") String deviceIP, - @PathParam("port") String devicePort, @Context HttpServletRequest request); - - /** * This is an API called/used from within the Server(Front-End) or by a device Owner. It sends a control command to * the VirtualFirealarm device to switch `ON` or `OFF` its buzzer. The method also takes in the protocol to be used @@ -79,19 +54,6 @@ public interface VirtualFireAlarmControllerService { description = "Switch on/off Virtual Fire Alarm Buzzer. (On / Off)") Response switchBuzzer(@PathParam("deviceId") String deviceId, @QueryParam("protocol") String protocol, @FormParam("state") String state); - - /** - * This is an API called/used by the VirtualFirealarm device to publish its temperature to the IoT-Server. The - * received data from the device is stored in a 'DeviceRecord' under the device's ID in the 'SensorDataManager' - * of the Server. - * - * @param dataMsg the temperature data received from the device in JSON format complying to type 'DeviceData'. - */ - @POST - @Path("device/temperature") - @Permission(scope = "virtual_firealarm_admin", permissions = {"device-mgt/virtual_firealarm/admin"}) - @Consumes(MediaType.APPLICATION_JSON) - Response pushTemperatureData(final DeviceData dataMsg); /** diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmControllerServiceImpl.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmControllerServiceImpl.java index e7c6a93dd..213cb3fbc 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmControllerServiceImpl.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmControllerServiceImpl.java @@ -1,20 +1,20 @@ /* - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl; @@ -23,25 +23,16 @@ import org.apache.commons.logging.LogFactory; import org.wso2.carbon.analytics.dataservice.commons.SORT; import org.wso2.carbon.analytics.dataservice.commons.SortByField; import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException; -import org.wso2.carbon.apimgt.annotations.api.Permission; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; -import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants; -import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig; -import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig; -import org.wso2.carbon.device.mgt.iot.service.IoTServerStartupListener; -import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants; -import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.DeviceData; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util.VirtualFirealarmSecurityManager; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.SensorRecord; -import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.transport.VirtualFireAlarmMQTTConnector; -import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.transport.VirtualFireAlarmXMPPConnector; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.APIUtil; -import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.SecurityManager; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.VirtualFireAlarmServiceUtils; -import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; import javax.ws.rs.FormParam; import javax.ws.rs.GET; @@ -51,46 +42,17 @@ 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.security.PrivateKey; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; -import java.util.concurrent.ConcurrentHashMap; +import java.util.Map; -@SuppressWarnings("Non-Annoted WebService") public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmControllerService { private static final String XMPP_PROTOCOL = "XMPP"; - private static final String HTTP_PROTOCOL = "HTTP"; - private static final String MQTT_PROTOCOL = "MQTT"; private static Log log = LogFactory.getLog(VirtualFireAlarmControllerServiceImpl.class); - // consists of utility methods related to encrypting and decrypting messages - private org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.SecurityManager securityManager; - // connects to the given MQTT broker and handles MQTT communication - private VirtualFireAlarmMQTTConnector virtualFireAlarmMQTTConnector; - // connects to the given XMPP server and handles XMPP communication - private VirtualFireAlarmXMPPConnector virtualFireAlarmXMPPConnector; - // holds a mapping of the IP addresses to Device-IDs for HTTP communication - private ConcurrentHashMap deviceToIpMap = new ConcurrentHashMap<>(); - - @Permission(scope = "virtual_firealarm_user", permissions = { "device-mgt/virtual_firealarm/user" }) - @POST - @Path("device/register/{deviceId}/{ip}/{port}") - public Response registerDeviceIP(@PathParam("deviceId") String deviceId, @PathParam("ip") String deviceIP, - @PathParam("port") String devicePort, @Context HttpServletRequest request) { - - if (log.isDebugEnabled()) { - log.debug("Got register call from IP: " + deviceIP + " for Device ID: " + deviceId); - } - String deviceHttpEndpoint = deviceIP + ":" + devicePort; - deviceToIpMap.put(deviceId, deviceHttpEndpoint); - String result = "Device-IP Registered"; - if (log.isDebugEnabled()) { - log.debug(result); - } - return Response.ok().entity(result).build(); - } @POST @Path("device/{deviceId}/buzz") @@ -103,10 +65,9 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo return Response.status(Response.Status.BAD_REQUEST).build(); } String protocolString = protocol.toUpperCase(); - String callUrlPattern = VirtualFireAlarmConstants.BULB_CONTEXT + switchToState; if (log.isDebugEnabled()) { log.debug("Sending request to switch-bulb of device [" + deviceId + "] via " + - protocolString); + protocolString); } try { if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized( @@ -114,30 +75,38 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo DeviceGroupConstants.Permissions.DEFAULT_OPERATOR_PERMISSIONS)) { return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); } + String resource = VirtualFireAlarmConstants.BULB_CONTEXT.replace("/", ""); + PrivateKey serverPrivateKey = VirtualFirealarmSecurityManager.getServerPrivateKey(); + String actualMessage = resource + ":" + switchToState; + String encryptedMsg = VirtualFireAlarmServiceUtils.prepareSecurePayLoad(actualMessage, + serverPrivateKey); + Map dynamicProperties = new HashMap<>(); switch (protocolString) { - case HTTP_PROTOCOL: - String deviceHTTPEndpoint = deviceToIpMap.get(deviceId); - if (deviceHTTPEndpoint == null) { - return Response.status(Response.Status.PRECONDITION_FAILED).build(); - } - VirtualFireAlarmServiceUtils.sendCommandViaHTTP(deviceHTTPEndpoint, callUrlPattern, true); - break; case XMPP_PROTOCOL: - String xmppResource = VirtualFireAlarmConstants.BULB_CONTEXT.replace("/", ""); - virtualFireAlarmXMPPConnector.publishDeviceData(deviceId, xmppResource, switchToState); + dynamicProperties.put(VirtualFireAlarmConstants.JID_PROPERTY_KEY, deviceId); + dynamicProperties.put(VirtualFireAlarmConstants.SUBJECT_PROPERTY_KEY, "CONTROL-REQUEST"); + dynamicProperties.put(VirtualFireAlarmConstants.MESSAGE_TYPE_PROPERTY_KEY, + VirtualFireAlarmConstants.CHAT_PROPERTY_KEY); + APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.XMPP_ADAPTER_NAME, + dynamicProperties, encryptedMsg); break; default: - String mqttResource = VirtualFireAlarmConstants.BULB_CONTEXT.replace("/", ""); - virtualFireAlarmMQTTConnector.publishDeviceData(deviceId, mqttResource, switchToState); + + String publishTopic = APIUtil.getTenantDomainOftheUser() + "/" + + VirtualFireAlarmConstants.DEVICE_TYPE + "/" + deviceId; + dynamicProperties.put(VirtualFireAlarmConstants.ADAPTER_TOPIC_PROPERTY, publishTopic); + APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.MQTT_ADAPTER_NAME, + dynamicProperties, encryptedMsg); break; } return Response.ok().build(); - } catch (DeviceManagementException | TransportHandlerException e) { - log.error("Failed to send switch-bulb request to device [" + deviceId + "] via " + protocolString); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } catch (DeviceAccessAuthorizationException e) { log.error(e.getErrorMessage(), e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (VirtualFireAlarmException e) { + String errorMsg = "Preparing Secure payload failed for device - [" + deviceId + "]"; + log.error(errorMsg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } } @@ -147,8 +116,7 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo @FormParam("policy") String policy) { String protocolString = protocol.toUpperCase(); if (log.isDebugEnabled()) { - log.debug("Sending request to update-policy of device [" + deviceId + "] via " + - protocolString); + log.debug("Sending request to update-policy of device [" + deviceId + "] via " + protocolString); } try { if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized( @@ -156,59 +124,39 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo DeviceGroupConstants.Permissions.DEFAULT_MANAGE_POLICIES_PERMISSIONS)) { return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); } + PrivateKey serverPrivateKey = VirtualFirealarmSecurityManager.getServerPrivateKey(); + String actualMessage = VirtualFireAlarmConstants.POLICY_CONTEXT + ":" + policy; + String encryptedMsg = VirtualFireAlarmServiceUtils.prepareSecurePayLoad(actualMessage, + serverPrivateKey); + Map dynamicProperties = new HashMap<>(); switch (protocolString) { - case HTTP_PROTOCOL: - throw new UnsupportedOperationException( - "Sending request to update-policy via HTTP protocol not supported."); - case XMPP_PROTOCOL: - String xmppResource = VirtualFireAlarmConstants.POLICY_CONTEXT.replace("/", ""); - virtualFireAlarmXMPPConnector.publishDeviceData(deviceId, xmppResource, policy); - break; - default: - String mqttResource = VirtualFireAlarmConstants.POLICY_CONTEXT.replace("/", ""); - virtualFireAlarmMQTTConnector.publishDeviceData(deviceId, mqttResource, policy); - break; + case XMPP_PROTOCOL: + dynamicProperties.put(VirtualFireAlarmConstants.JID_PROPERTY_KEY, deviceId); + dynamicProperties.put(VirtualFireAlarmConstants.SUBJECT_PROPERTY_KEY, "POLICTY-REQUEST"); + dynamicProperties.put(VirtualFireAlarmConstants.MESSAGE_TYPE_PROPERTY_KEY, + VirtualFireAlarmConstants.CHAT_PROPERTY_KEY); + APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.XMPP_ADAPTER_NAME, + dynamicProperties, encryptedMsg); + break; + default: + + String publishTopic = APIUtil.getTenantDomainOftheUser() + "/" + + VirtualFireAlarmConstants.DEVICE_TYPE + "/" + deviceId; + dynamicProperties.put(VirtualFireAlarmConstants.ADAPTER_TOPIC_PROPERTY, publishTopic); + APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.MQTT_ADAPTER_NAME, + dynamicProperties, encryptedMsg); + break; } return Response.ok().build(); - } catch (TransportHandlerException e) { - log.error("Failed to send update-policy request to device [" + deviceId + "] via " + protocolString); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } catch (DeviceAccessAuthorizationException e) { log.error(e.getErrorMessage(), e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (VirtualFireAlarmException e) { + log.error(e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } } - @POST - @Path("device/temperature") - @Consumes(MediaType.APPLICATION_JSON) - public Response pushTemperatureData(final DeviceData dataMsg) { - String deviceId = dataMsg.deviceId; - String deviceIp = dataMsg.reply; - 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); - return Response.status(Response.Status.PRECONDITION_FAILED).build(); - } 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"); - return Response.status(Response.Status.CONFLICT).build(); - } - try { - if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized( - new DeviceIdentifier(deviceId, VirtualFireAlarmConstants.DEVICE_TYPE))) { - return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); - } - if (!VirtualFireAlarmServiceUtils.publishToDAS(dataMsg.deviceId, dataMsg.value)) { - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); - } - return Response.ok().build(); - } catch (DeviceAccessAuthorizationException e) { - log.error(e.getErrorMessage(), e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); - } - } @Path("device/stats/{deviceId}") @GET @@ -227,13 +175,11 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) { return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); } - if (sensorTableName != null) { - List sortByFields = new ArrayList<>(); - SortByField sortByField = new SortByField("time", SORT.ASC, false); - sortByFields.add(sortByField); - List sensorRecords = APIUtil.getAllEventsForDevice(sensorTableName, query, sortByFields); - return Response.status(Response.Status.OK.getStatusCode()).entity(sensorRecords).build(); - } + List sortByFields = new ArrayList<>(); + SortByField sortByField = new SortByField("time", SORT.ASC, false); + sortByFields.add(sortByField); + List sensorRecords = APIUtil.getAllEventsForDevice(sensorTableName, query, sortByFields); + return Response.status(Response.Status.OK.getStatusCode()).entity(sensorRecords).build(); } catch (AnalyticsException e) { String errorMsg = "Error on retrieving stats on table " + sensorTableName + " with query " + query; log.error(errorMsg); @@ -242,130 +188,6 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo log.error(e.getErrorMessage(), e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } - return Response.status(Response.Status.BAD_REQUEST).build(); } - private boolean waitForServerStartup() { - while (!IoTServerStartupListener.isServerReady()) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - return true; - } - } - return false; - } - - /** - * Fetches the `SecurityManager` specific to this VirtualFirealarm controller service. - * - * @return the 'SecurityManager' instance bound to the 'securityManager' variable of this service. - */ - @SuppressWarnings("Unused") - public SecurityManager getSecurityManager() { - return securityManager; - } - - /** - * Sets the `securityManager` variable of this VirtualFirealarm controller service. - * - * @param securityManager a 'SecurityManager' object that handles the encryption, decryption, signing and validation - * of incoming messages from VirtualFirealarm device-types. - */ - @SuppressWarnings("Unused") - public void setSecurityManager(SecurityManager securityManager) { - this.securityManager = securityManager; - securityManager.initVerificationManager(); - } - - /** - * Fetches the `VirtualFireAlarmXMPPConnector` specific to this VirtualFirealarm controller service. - * - * @return the 'VirtualFireAlarmXMPPConnector' instance bound to the 'virtualFireAlarmXMPPConnector' variable of - * this service. - */ - @SuppressWarnings("Unused") - public VirtualFireAlarmXMPPConnector getVirtualFireAlarmXMPPConnector() { - return virtualFireAlarmXMPPConnector; - } - - /** - * Sets the `virtualFireAlarmXMPPConnector` variable of this VirtualFirealarm controller service. - * - * @param virtualFireAlarmXMPPConnector a 'VirtualFireAlarmXMPPConnector' object that handles all XMPP related - * communications of any connected VirtualFirealarm device-type - */ - @SuppressWarnings("Unused") - public void setVirtualFireAlarmXMPPConnector( - final VirtualFireAlarmXMPPConnector virtualFireAlarmXMPPConnector) { - Runnable connector = new Runnable() { - public void run() { - if (waitForServerStartup()) { - return; - } - VirtualFireAlarmControllerServiceImpl.this.virtualFireAlarmXMPPConnector = virtualFireAlarmXMPPConnector; - - if (XmppConfig.getInstance().isEnabled()) { - Runnable xmppStarter = new Runnable() { - @Override - public void run() { - virtualFireAlarmXMPPConnector.initConnector(); - virtualFireAlarmXMPPConnector.connect(); - } - }; - - Thread xmppStarterThread = new Thread(xmppStarter); - xmppStarterThread.setDaemon(true); - xmppStarterThread.start(); - } else { - log.warn("XMPP disabled in 'devicemgt-config.xml'. Hence, VirtualFireAlarmXMPPConnector not started."); - } - } - }; - Thread connectorThread = new Thread(connector); - connectorThread.start(); - } - - /** - * Fetches the `VirtualFireAlarmMQTTConnector` specific to this VirtualFirealarm controller service. - * - * @return the 'VirtualFireAlarmMQTTConnector' instance bound to the 'virtualFireAlarmMQTTConnector' variable of - * this service. - */ - @SuppressWarnings("Unused") - public VirtualFireAlarmMQTTConnector getVirtualFireAlarmMQTTConnector() { - return virtualFireAlarmMQTTConnector; - } - - /** - * Sets the `virtualFireAlarmMQTTConnector` variable of this VirtualFirealarm controller service. - * - * @param virtualFireAlarmMQTTConnector a 'VirtualFireAlarmMQTTConnector' object that handles all MQTT related - * communications of any connected VirtualFirealarm device-type - */ - @SuppressWarnings("Unused") - public void setVirtualFireAlarmMQTTConnector( - final VirtualFireAlarmMQTTConnector virtualFireAlarmMQTTConnector) { - Runnable connector = new Runnable() { - public void run() { - if (waitForServerStartup()) { - return; - } - //The delay is added for the server to starts up. - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - VirtualFireAlarmControllerServiceImpl.this.virtualFireAlarmMQTTConnector = virtualFireAlarmMQTTConnector; - if (MqttConfig.getInstance().isEnabled()) { - virtualFireAlarmMQTTConnector.connect(); - } else { - log.warn("MQTT disabled in 'devicemgt-config.xml'. Hence, VirtualFireAlarmMQTTConnector not started."); - } - } - }; - Thread connectorThread = new Thread(connector); - connectorThread.start(); - } } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmManagerServiceImpl.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmManagerServiceImpl.java index d5af4821b..6762033f8 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmManagerServiceImpl.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmManagerServiceImpl.java @@ -31,12 +31,12 @@ import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants; -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.DeviceControllerException; import org.wso2.carbon.device.mgt.iot.util.ZipArchive; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppAccount; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppConfig; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppServerClient; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.APIUtil; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.ZipUtil; import org.wso2.carbon.identity.jwt.client.extension.JWTClient; @@ -198,15 +198,15 @@ public class VirtualFireAlarmManagerServiceImpl implements VirtualFireAlarmManag } catch (APIManagerException ex) { log.error(ex.getMessage(), ex); return Response.status(500).entity(ex.getMessage()).build(); - } catch (DeviceControllerException ex) { - log.error(ex.getMessage(), ex); - return Response.status(500).entity(ex.getMessage()).build(); } catch (IOException ex) { log.error(ex.getMessage(), ex); return Response.status(500).entity(ex.getMessage()).build(); } catch (UserStoreException ex) { log.error(ex.getMessage(), ex); return Response.status(500).entity(ex.getMessage()).build(); + } catch (VirtualFirealarmDeviceMgtPluginException ex) { + log.error(ex.getMessage(), ex); + return Response.status(500).entity(ex.getMessage()).build(); } } @@ -237,8 +237,8 @@ public class VirtualFireAlarmManagerServiceImpl implements VirtualFireAlarmManag } private ZipArchive createDownloadFile(String owner, String deviceName, String sketchType) - throws DeviceManagementException, APIManagerException, JWTClientException, DeviceControllerException, - UserStoreException { + throws DeviceManagementException, APIManagerException, JWTClientException, + UserStoreException, VirtualFirealarmDeviceMgtPluginException { //create new device id String deviceId = shortUUID(); if (apiApplicationKey == null) { @@ -259,18 +259,16 @@ public class VirtualFireAlarmManagerServiceImpl implements VirtualFireAlarmManag String refreshToken = accessTokenInfo.getRefreshToken(); //adding registering data XmppAccount newXmppAccount = new XmppAccount(); - newXmppAccount.setAccountName(owner + "_" + deviceId); + newXmppAccount.setAccountName(deviceId); newXmppAccount.setUsername(deviceId); newXmppAccount.setPassword(accessToken); newXmppAccount.setEmail(deviceId + "@" + APIUtil.getTenantDomainOftheUser()); XmppServerClient xmppServerClient = new XmppServerClient(); - xmppServerClient.initControlQueue(); boolean status; if (XmppConfig.getInstance().isEnabled()) { - status = xmppServerClient.createXMPPAccount(newXmppAccount); + status = xmppServerClient.createAccount(newXmppAccount); if (!status) { - String msg = - "XMPP Account was not created for device - " + deviceId + " of owner - " + owner + + String msg = "XMPP Account was not created for device - " + deviceId + " of owner - " + owner + ".XMPP might have been disabled in org.wso2.carbon.device.mgt.iot" + ".common.config.server.configs"; throw new DeviceManagementException(msg); diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/dto/DeviceData.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/dto/DeviceData.java deleted file mode 100644 index 45c62020f..000000000 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/dto/DeviceData.java +++ /dev/null @@ -1,36 +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.virtualfirealarm.service.impl.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 DeviceData { - @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/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/exception/VirtualFireAlarmException.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/exception/VirtualFireAlarmException.java index c0e848f14..4305ec7c0 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/exception/VirtualFireAlarmException.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/exception/VirtualFireAlarmException.java @@ -28,4 +28,8 @@ public class VirtualFireAlarmException extends Exception { public VirtualFireAlarmException(String errorMessage, Throwable throwable) { super(errorMessage, throwable); } + + public VirtualFireAlarmException(Throwable cause) { + super(cause); + } } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/transport/VirtualFireAlarmMQTTConnector.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/transport/VirtualFireAlarmMQTTConnector.java deleted file mode 100644 index 23c3aec02..000000000 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/transport/VirtualFireAlarmMQTTConnector.java +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.transport; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttMessage; -import org.json.JSONObject; -import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService; -import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey; -import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException; -import org.wso2.carbon.context.PrivilegedCarbonContext; -import org.wso2.carbon.device.mgt.common.Device; -import org.wso2.carbon.device.mgt.common.DeviceIdentifier; -import org.wso2.carbon.device.mgt.common.DeviceManagementException; -import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; -import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig; -import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException; -import org.wso2.carbon.device.mgt.iot.transport.mqtt.MQTTTransportHandler; -import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.SecurityManager; -import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException; -import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.APIUtil; -import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.VirtualFireAlarmServiceUtils; -import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants; -import org.wso2.carbon.identity.jwt.client.extension.JWTClient; -import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; -import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; -import org.wso2.carbon.user.api.UserStoreException; -import org.wso2.carbon.utils.multitenancy.MultitenantUtils; - -import java.nio.charset.StandardCharsets; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.util.UUID; - -/** - * This is an example for the use of the MQTT capabilities provided by the IoT-Server. This example depicts the use - * of MQTT Transport for the VirtualFirealarm device-type. This class extends the abstract class - * "MQTTTransportHandler". "MQTTTransportHandler" consists of the MQTT client specific functionality and implements - * the "TransportHandler" interface. The actual functionality related to the "TransportHandler" interface is - * implemented here, in this concrete class. Whilst the abstract class "MQTTTransportHandler" is intended to provide - * the common MQTT functionality, this class (which is its extension) provides the implementation specific to the - * MQTT communication of the Device-Type (VirtualFirealarm) in concern. - *

- * Hence, the methods of this class are implementation of the "TransportHandler" interface which handles the device - * specific logic to connect-to, publish-to, process-incoming-messages-from and disconnect-from the MQTT broker - * listed in the configurations. - */ -@SuppressWarnings("no JAX-WS annotation") -public class VirtualFireAlarmMQTTConnector extends MQTTTransportHandler { - - private static Log log = LogFactory.getLog(VirtualFireAlarmMQTTConnector.class); - // subscription topic: /+/virtual_firealarm/+/publisher - // wildcard (+) is in place for device_owner & device_id - private static final String subscribeTopic = "wso2/+/"+ VirtualFireAlarmConstants.DEVICE_TYPE + "/+/publisher"; - private static String iotServerSubscriber = UUID.randomUUID().toString().substring(0, 5); - private static final String KEY_TYPE = "PRODUCTION"; - private static final String EMPTY_STRING = ""; - private static final String JSON_SERIAL_KEY = "SerialNumber"; - private static final String JSON_TENANT_KEY = "Tenant"; - - /** - * Default constructor for the VirtualFirealarmMQTTConnector. - */ - private VirtualFireAlarmMQTTConnector() { - super(iotServerSubscriber, VirtualFireAlarmConstants.DEVICE_TYPE, - MqttConfig.getInstance().getMqttQueueEndpoint(), subscribeTopic); - } - - /** - * {@inheritDoc} - * VirtualFirealarm device-type specific implementation to connect to the MQTT broker and subscribe to a topic. - * This method is called to initiate a MQTT communication. - */ - @Override - public void connect() { - Runnable connector = new Runnable() { - public void run() { - while (!isConnected()) { - PrivilegedCarbonContext.startTenantFlow(); - PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain( - VirtualFireAlarmConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true); - try { - String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() - .getRealmConfiguration().getAdminUserName(); - PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(applicationUsername); - APIManagementProviderService apiManagementProviderService = APIUtil - .getAPIManagementProviderService(); - String[] tags = {VirtualFireAlarmConstants.DEVICE_TYPE}; - ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys( - VirtualFireAlarmConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true); - JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient(); - String scopes = "device_type_" + VirtualFireAlarmConstants.DEVICE_TYPE + " device_mqtt_connector"; - AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(), - apiApplicationKey.getConsumerSecret(), applicationUsername, scopes); - //create token - String accessToken = accessTokenInfo.getAccessToken(); - setUsernameAndPassword(accessToken, EMPTY_STRING); - connectToQueue(); - subscribeToQueue(); - } catch (TransportHandlerException e) { - log.error("Connection/Subscription to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e); - try { - Thread.sleep(timeoutInterval); - } catch (InterruptedException ex) { - log.error("MQTT-Connector: Thread Sleep Interrupt Exception.", ex); - } - } catch (JWTClientException e) { - log.error("Failed to retrieve token from JWT Client.", e); - return; - } catch (UserStoreException e) { - log.error("Failed to retrieve the user.", e); - return; - } catch (APIManagerException e) { - log.error("Failed to create an application and generate keys.", e); - return; - } finally { - PrivilegedCarbonContext.endTenantFlow(); - } - } - } - }; - - Thread connectorThread = new Thread(connector); - connectorThread.start(); - } - - /** - * {@inheritDoc} - * VirtualFirealarm device-type specific implementation to process incoming messages. This is the specific - * method signature of the overloaded "processIncomingMessage" method that gets called from the messageArrived() - * callback of the "MQTTTransportHandler". - */ - @Override - public void processIncomingMessage(MqttMessage mqttMessage, String... messageParams) { - if (messageParams.length != 0) { - // owner and the deviceId are extracted from the MQTT topic to which the message was received. - // = [ServerName/Owner/DeviceType/DeviceId/"publisher"] - String topic = messageParams[0]; - String[] topicParams = topic.split("/"); - String tenantDomain = topicParams[1]; - String deviceId = topicParams[3]; - if (log.isDebugEnabled()) { - log.debug("Received MQTT message for: [DEVICE.ID-" + deviceId + "]"); - } - JSONObject jsonPayload = new JSONObject(mqttMessage.toString()); - String actualMessage; - try { - PrivilegedCarbonContext.startTenantFlow(); - PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); - DeviceManagementProviderService deviceManagementProviderService = - (DeviceManagementProviderService) ctx.getOSGiService(DeviceManagementProviderService.class, - null); - ctx.setTenantDomain(tenantDomain, true); - if (deviceManagementProviderService != null) { - DeviceIdentifier identifier = new DeviceIdentifier(deviceId, - VirtualFireAlarmConstants.DEVICE_TYPE); - Device device = deviceManagementProviderService.getDevice(identifier); - if (device != null) { - String owner = device.getEnrolmentInfo().getOwner(); - ctx.setUsername(owner); - } else { - return; - } - } - Long serialNo = (Long)jsonPayload.get(JSON_SERIAL_KEY); - // the hash-code of the deviceId is used as the alias for device certificates during SCEP enrollment. - // hence, the same is used here to fetch the device-specific-certificate from the key store. - PublicKey clientPublicKey = VirtualFireAlarmServiceUtils.getDevicePublicKey("" + serialNo); - - // the MQTT-messages from VirtualFireAlarm devices are in the form {"Msg":, "Sig":} - actualMessage = VirtualFireAlarmServiceUtils.extractMessageFromPayload(mqttMessage.toString(), - clientPublicKey); - if (log.isDebugEnabled()) { - log.debug("MQTT: Received Message [" + actualMessage + "] topic: [" + topic + "]"); - } - - if (actualMessage.contains("PUBLISHER")) { - float temperature = Float.parseFloat(actualMessage.split(":")[2]); - if (!VirtualFireAlarmServiceUtils.publishToDAS(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 (actualMessage.contains("TEMPERATURE")) { - String temperatureValue = actualMessage.split(":")[1]; - } - } catch (VirtualFireAlarmException e) { - String errorMsg = - "CertificateManagementService failure oo Signature-Verification/Decryption was unsuccessful."; - log.error(errorMsg, e); - } catch (DeviceManagementException e) { - log.error("Failed to retreive the device managment service for device type " + - VirtualFireAlarmConstants.DEVICE_TYPE, e); - } finally { - PrivilegedCarbonContext.endTenantFlow(); - } - } else { - String errorMsg = - "MQTT message [" + mqttMessage.toString() + "] was received without the topic information."; - log.warn(errorMsg); - } - } - - /** - * {@inheritDoc} - * VirtualFirealarm device-type specific implementation to publish data to the device. This method calls the - * {@link #publishToQueue(String, MqttMessage)} method of the "MQTTTransportHandler" class. - */ - @Override - public void publishDeviceData(String... publishData) throws TransportHandlerException { - if (publishData.length != 3) { - String errorMsg = "Incorrect number of arguments received to SEND-MQTT Message. " + - "Need to be [owner, deviceId, resource{BULB/TEMP}, state{ON/OFF or null}]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg); - } - - String deviceId = publishData[0]; - String resource = publishData[1]; - String state = publishData[2]; - - MqttMessage pushMessage = new MqttMessage(); - String publishTopic = "wso2/" + APIUtil.getTenantDomainOftheUser() + "/" - + VirtualFireAlarmConstants.DEVICE_TYPE + "/" + deviceId; - - try { - PrivateKey serverPrivateKey = SecurityManager.getServerPrivateKey(); - String actualMessage = resource + ":" + state; - String encryptedMsg = VirtualFireAlarmServiceUtils.prepareSecurePayLoad(actualMessage, serverPrivateKey); - pushMessage.setPayload(encryptedMsg.getBytes(StandardCharsets.UTF_8)); - pushMessage.setQos(DEFAULT_MQTT_QUALITY_OF_SERVICE); - pushMessage.setRetained(false); - publishToQueue(publishTopic, pushMessage); - } catch (VirtualFireAlarmException e) { - String errorMsg = "Preparing Secure payload failed for device - [" + deviceId + "]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, e); - } - } - - - /** - * {@inheritDoc} - * VirtualFirealarm device-type specific implementation to disconnect from the MQTT broker. - */ - @Override - public void disconnect() { - Runnable stopConnection = new Runnable() { - public void run() { - while (isConnected()) { - try { - closeConnection(); - } catch (MqttException e) { - if (log.isDebugEnabled()) { - log.warn("Unable to 'STOP' MQTT connection at broker at: " + mqttBrokerEndPoint - + " for device-type - " + VirtualFireAlarmConstants.DEVICE_TYPE, e); - } - - try { - Thread.sleep(timeoutInterval); - } catch (InterruptedException e1) { - log.error("MQTT-Terminator: Thread Sleep Interrupt Exception at device-type - " + - VirtualFireAlarmConstants.DEVICE_TYPE, e1); - } - } - } - } - }; - - Thread terminatorThread = new Thread(stopConnection); - terminatorThread.start(); - } - - - /** - * {@inheritDoc} - */ - @Override - public void publishDeviceData() { - // nothing to do - } - - /** - * {@inheritDoc} - */ - @Override - public void publishDeviceData(MqttMessage publishData) throws TransportHandlerException { - // nothing to do - } - - /** - * {@inheritDoc} - */ - @Override - public void processIncomingMessage() { - // nothing to do - } - - /** - * {@inheritDoc} - */ - @Override - public void processIncomingMessage(MqttMessage message) throws TransportHandlerException { - // nothing to do - } -} diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/transport/VirtualFireAlarmXMPPConnector.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/transport/VirtualFireAlarmXMPPConnector.java deleted file mode 100644 index 420567952..000000000 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/transport/VirtualFireAlarmXMPPConnector.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.transport; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jivesoftware.smack.packet.Message; -import org.json.JSONObject; -import org.wso2.carbon.context.PrivilegedCarbonContext; -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.DeviceControllerException; -import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException; -import org.wso2.carbon.device.mgt.iot.transport.xmpp.XMPPTransportHandler; -import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants; -import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.SecurityManager; -import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException; -import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.VirtualFireAlarmServiceUtils; -import org.wso2.carbon.utils.multitenancy.MultitenantUtils; - -import java.io.File; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -@SuppressWarnings("no JAX-WS annotation") -public class VirtualFireAlarmXMPPConnector extends XMPPTransportHandler { - private static Log log = LogFactory.getLog(VirtualFireAlarmXMPPConnector.class); - - private static String xmppServerIP; - private static String xmppVFireAlarmAdminUsername; - private static String xmppVFireAlarmAdminAccountJID; - private static final String V_FIREALARM_XMPP_PASSWORD = "vfirealarm@123"; - private static final String DEVICEMGT_CONFIG_FILE = "devicemgt-config.xml"; - private static final String JSON_SERIAL_KEY = "SerialNumber"; - - private ScheduledFuture connectorServiceHandler; - private ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(); - - private VirtualFireAlarmXMPPConnector() { - super(XmppConfig.getInstance().getXmppServerIP(), XmppConfig.getInstance().getSERVER_CONNECTION_PORT()); - } - - public void initConnector() { - xmppVFireAlarmAdminUsername = "wso2admin_" + VirtualFireAlarmConstants.DEVICE_TYPE; - xmppServerIP = XmppConfig.getInstance().getXmppServerIP(); - xmppVFireAlarmAdminAccountJID = xmppVFireAlarmAdminUsername + "@" + xmppServerIP; - createXMPPAccountForDeviceType(); - } - - public void createXMPPAccountForDeviceType() { - boolean accountExists; - XmppServerClient xmppServerClient = new XmppServerClient(); - xmppServerClient.initControlQueue(); - - try { - accountExists = xmppServerClient.doesXMPPUserAccountExist(xmppVFireAlarmAdminUsername); - - if (!accountExists) { - XmppAccount xmppAccount = new XmppAccount(); - - xmppAccount.setAccountName(xmppVFireAlarmAdminUsername); - xmppAccount.setUsername(xmppVFireAlarmAdminUsername); - xmppAccount.setPassword(V_FIREALARM_XMPP_PASSWORD); - xmppAccount.setEmail(""); - - try { - boolean xmppCreated = xmppServerClient.createXMPPAccount(xmppAccount); - if (!xmppCreated) { - log.warn("Server XMPP Account was not created for device-type - " + - VirtualFireAlarmConstants.DEVICE_TYPE + - ". Check whether XMPP is enabled in \"devicemgt-config.xml\" & restart."); - } else { - log.info("Server XMPP Account [" + xmppVFireAlarmAdminUsername + - "] was not created for device - " + VirtualFireAlarmConstants.DEVICE_TYPE); - } - } catch (DeviceControllerException e) { - String errorMsg = - "An error was encountered whilst trying to create Server XMPP account for device-type - " - + VirtualFireAlarmConstants.DEVICE_TYPE; - log.error(errorMsg, e); - } - } - - } catch (DeviceControllerException e) { - if (e.getMessage().contains(DEVICEMGT_CONFIG_FILE)) { - log.warn("XMPP not Enabled"); - } else { - String errorMsg = "An error was encountered whilst trying to check whether Server XMPP account " + - "exists for device-type - " + VirtualFireAlarmConstants.DEVICE_TYPE ; - log.error(errorMsg, e); - } - } - } - - - @Override - public void connect() { - Runnable connector = new Runnable() { - public void run() { - if (!isConnected()) { - try { - connectToServer(); - loginToServer(xmppVFireAlarmAdminUsername, V_FIREALARM_XMPP_PASSWORD, null); - setFilterOnReceiver(xmppVFireAlarmAdminAccountJID); - - } catch (TransportHandlerException e) { - if (log.isDebugEnabled()) { - log.warn("Connection/Login to XMPP server at: " + server + " as " + - xmppVFireAlarmAdminUsername + " failed for device-type [" + - VirtualFireAlarmConstants.DEVICE_TYPE + "].", e); - } - } - } - } - }; - - connectorServiceHandler = service.scheduleAtFixedRate(connector, 0, timeoutInterval, TimeUnit.MILLISECONDS); - } - - @Override - public void processIncomingMessage(Message xmppMessage) throws TransportHandlerException { - String from = xmppMessage.getFrom(); - String subject = xmppMessage.getSubject(); - String message = xmppMessage.getBody(); - - int indexOfAt = from.indexOf("@"); - int indexOfSlash = from.indexOf("/"); - - if (indexOfAt != -1 && indexOfSlash != -1) { - String deviceId = from.substring(0, indexOfAt); - String owner = from.substring(indexOfSlash + 1, from.length()); - - if (log.isDebugEnabled()) { - log.debug("Received XMPP message for: [OWNER-" + owner + "] & [DEVICE.ID-" + deviceId + "]"); - } - - try { - PrivilegedCarbonContext.startTenantFlow(); - String tenantDomain = MultitenantUtils.getTenantDomain(owner); - PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain); - PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(owner); - - JSONObject jsonPayload = new JSONObject(message); - Long serialNo = (Long)jsonPayload.get(JSON_SERIAL_KEY); - PublicKey clientPublicKey = VirtualFireAlarmServiceUtils.getDevicePublicKey("" + serialNo); - String actualMessage = VirtualFireAlarmServiceUtils.extractMessageFromPayload(message, - clientPublicKey); - if (log.isDebugEnabled()) { - log.debug("XMPP: Received Message [" + actualMessage + "] from: [" + from + "]"); - } - if (subject != null) { - switch (subject) { - case "PUBLISHER": - float temperature = Float.parseFloat(actualMessage.split(":")[1]); - if (!VirtualFireAlarmServiceUtils.publishToDAS(deviceId, temperature)) { - log.error("XMPP Connector: Publishing VirtualFirealarm data to DAS failed."); - } - PrivilegedCarbonContext.endTenantFlow(); - if (log.isDebugEnabled()) { - log.debug("XMPP: Publisher Message [" + actualMessage + "] from [" + from + "] " + - "was successfully published to DAS"); - } - break; - case "CONTROL-REPLY": - String tempVal = actualMessage.split(":")[1]; - break; - - default: - if (log.isDebugEnabled()) { - log.warn("Unknown XMPP Message [" + actualMessage + "] from [" + from + "] received"); - } - break; - } - } - } catch (VirtualFireAlarmException e) { - String errorMsg = - "CertificateManagementService failure oo Signature-Verification/Decryption was unsuccessful."; - log.error(errorMsg, e); - } finally { - PrivilegedCarbonContext.endTenantFlow(); - } - } else { - log.warn("Received XMPP message from client with unexpected JID [" + from + "]."); - } - } - - @Override - public void publishDeviceData(String... publishData) throws TransportHandlerException { - if (publishData.length != 4) { - String errorMsg = "Incorrect number of arguments received to SEND-MQTT Message. " + - "Need to be [owner, deviceId, resource{BULB/TEMP}, state{ON/OFF or null}]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg); - } - - String deviceOwner = publishData[0]; - String deviceId = publishData[1]; - String resource = publishData[2]; - String state = publishData[3]; - - try { - PrivateKey serverPrivateKey = SecurityManager.getServerPrivateKey(); - String actualMessage = resource + ":" + state; - String encryptedMsg = VirtualFireAlarmServiceUtils.prepareSecurePayLoad(actualMessage, serverPrivateKey); - String clientToConnect = deviceId + "@" + xmppServerIP + File.separator + deviceOwner; - sendXMPPMessage(clientToConnect, encryptedMsg, "CONTROL-REQUEST"); - - } catch (VirtualFireAlarmException e) { - String errorMsg = "Preparing Secure payload failed for device - [" + deviceId + "] of owner - " + - "[" + deviceOwner + "]."; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg, e); - } - } - - - @Override - public void disconnect() { - Runnable stopConnection = new Runnable() { - public void run() { - while (isConnected()) { - connectorServiceHandler.cancel(true); - closeConnection(); - if (log.isDebugEnabled()) { - log.warn("Unable to 'STOP' connection to XMPP server at: " + server + - " for user - " + xmppVFireAlarmAdminUsername); - } - - try { - Thread.sleep(timeoutInterval); - } catch (InterruptedException e1) { - log.error("XMPP-Terminator: Thread Sleep Interrupt Exception for " - + VirtualFireAlarmConstants.DEVICE_TYPE + " type.", e1); - } - - } - } - }; - - Thread terminatorThread = new Thread(stopConnection); - terminatorThread.start(); - } - - - @Override - public void processIncomingMessage(Message message, String... messageParams) throws TransportHandlerException { - // nothing to do - } - - @Override - public void processIncomingMessage() throws TransportHandlerException { - // nothing to do - } - - @Override - public void publishDeviceData() throws TransportHandlerException { - // nothing to do - } - - @Override - public void publishDeviceData(Message publishData) throws TransportHandlerException { - // nothing to do - } -} - diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/APIUtil.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/APIUtil.java index e7b182ef4..c26586f91 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/APIUtil.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/APIUtil.java @@ -16,6 +16,7 @@ import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.SensorRecord; +import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService; import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; import java.util.ArrayList; @@ -168,4 +169,16 @@ public class APIUtil { } return deviceAccessAuthorizationService; } + + public static OutputEventAdapterService getOutputEventAdapterService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + OutputEventAdapterService outputEventAdapterService = + (OutputEventAdapterService) ctx.getOSGiService(OutputEventAdapterService.class, null); + if (outputEventAdapterService == null) { + String msg = "Device Authorization service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return outputEventAdapterService; + } } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/VirtualFireAlarmServiceUtils.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/VirtualFireAlarmServiceUtils.java index 7d29f8ffd..de76845d6 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/VirtualFireAlarmServiceUtils.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/VirtualFireAlarmServiceUtils.java @@ -21,333 +21,33 @@ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util; import org.apache.commons.codec.binary.Base64; 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.json.JSONObject; -import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException; -import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; -import org.wso2.carbon.context.PrivilegedCarbonContext; -import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException; -import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService; -import org.wso2.carbon.device.mgt.common.DeviceManagementException; -import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util.VirtualFirealarmSecurityManager; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException; -import javax.ws.rs.HttpMethod; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; import java.lang.*; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.ProtocolException; -import java.net.URL; -import java.security.Key; import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.cert.X509Certificate; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Future; /** * */ public class VirtualFireAlarmServiceUtils { - private static final Log log = LogFactory.getLog(VirtualFireAlarmServiceUtils.class); - private static final String TEMPERATURE_STREAM_DEFINITION = "org.wso2.iot.devices.temperature"; private static final String JSON_MESSAGE_KEY = "Msg"; private static final String JSON_SIGNATURE_KEY = "Sig"; - /** - * - * @return - * @throws VirtualFireAlarmException - */ - public static CertificateManagementService getCertificateManagementService() throws VirtualFireAlarmException { - - PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); - CertificateManagementService certificateManagementService = (CertificateManagementService) - ctx.getOSGiService(CertificateManagementService.class, null); - - if (certificateManagementService == null) { - String msg = "EnrollmentService is not initialized"; - log.error(msg); - throw new VirtualFireAlarmException(msg); - } - - return certificateManagementService; - } - - - /** - * - * @param deviceHTTPEndpoint - * @param urlContext - * @param fireAndForgot - * @return - * @throws DeviceManagementException - */ - public static String sendCommandViaHTTP(final String deviceHTTPEndpoint, String urlContext, boolean fireAndForgot) - throws DeviceManagementException { - - String responseMsg = ""; - String urlString = VirtualFireAlarmConstants.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; - } - - /* --------------------------------------------------------------------------------------- - Utility methods relevant to creating and sending http requests - --------------------------------------------------------------------------------------- */ - - /* This methods creates and returns a http connection object */ - - /** - * - * @param urlString - * @return - * @throws DeviceManagementException - */ - 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 deviceId, float temperature) { - PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); - EventsPublisherService deviceAnalyticsService = (EventsPublisherService) ctx.getOSGiService( - EventsPublisherService.class, null); - if (deviceAnalyticsService != null) { - String owner = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); - Object metdaData[] = {owner, VirtualFireAlarmConstants.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; - } - return true; - } - return false; - } - - /** - * - * @param message - * @param signatureKey - * @return - * @throws VirtualFireAlarmException - */ public static String prepareSecurePayLoad(String message, PrivateKey signatureKey) throws VirtualFireAlarmException { - message = Base64.encodeBase64String(message.getBytes()); - String signedPayload = SecurityManager.signMessage(message, signatureKey); - JSONObject jsonPayload = new JSONObject(); - jsonPayload.put(JSON_MESSAGE_KEY, message); - jsonPayload.put(JSON_SIGNATURE_KEY, signedPayload); - return jsonPayload.toString(); - } - - /** - * - * @param message - * @param verifySignatureKey - * @return - * @throws VirtualFireAlarmException - */ - public static String extractMessageFromPayload(String message, PublicKey verifySignatureKey) - throws VirtualFireAlarmException { - String actualMessage; - - JSONObject jsonPayload = new JSONObject(message); - Object encodedMessage = jsonPayload.get(JSON_MESSAGE_KEY); - Object signedPayload = jsonPayload.get(JSON_SIGNATURE_KEY); - - if (encodedMessage != null && signedPayload != null) { - if (SecurityManager.verifySignature( - encodedMessage.toString(), signedPayload.toString(), verifySignatureKey)) { - actualMessage = new String(Base64.decodeBase64(encodedMessage.toString())); - //SecurityManager.decryptMessage(encryptedMessage.toString(), decryptionKey); - } else { - String errorMsg = "The message was not signed by a valid client. Could not verify signature on payload"; - throw new VirtualFireAlarmException(errorMsg); - } - } else { - String errorMsg = "The received message is in an INVALID format. " + - "Need to be JSON - {\"Msg\":\"\", \"Sig\":\"\"}."; - throw new VirtualFireAlarmException(errorMsg); - } - - return actualMessage; - } - - /** - * - * @param alias - * @return - * @throws VirtualFireAlarmException - */ - public static PublicKey getDevicePublicKey(String alias) throws VirtualFireAlarmException { - PublicKey clientPublicKey; try { - CertificateManagementService certificateManagementService = - VirtualFireAlarmServiceUtils.getCertificateManagementService(); - X509Certificate clientCertificate = (X509Certificate) certificateManagementService.getCertificateByAlias( - alias); - clientPublicKey = clientCertificate.getPublicKey(); - - } catch (VirtualFireAlarmException e) { - String errorMsg = "Could not retrieve CertificateManagementService from the runtime."; - if(log.isDebugEnabled()){ - log.debug(errorMsg); - } - throw new VirtualFireAlarmException(errorMsg, e); - } catch (KeystoreException e) { - String errorMsg; - if (e.getMessage().contains("NULL_CERT")) { - errorMsg = "The Device-View page might have been accessed prior to the device being started."; - if(log.isDebugEnabled()){ - log.debug(errorMsg); - } - throw new VirtualFireAlarmException(errorMsg, e); - } else { - errorMsg = "An error occurred whilst trying to retrieve certificate for alias [" + alias + - "] with alias: [" + alias + "]"; - if(log.isDebugEnabled()){ - log.debug(errorMsg); - } - throw new VirtualFireAlarmException(errorMsg, e); - } + message = Base64.encodeBase64String(message.getBytes()); + String signedPayload = VirtualFirealarmSecurityManager.signMessage(message, signatureKey); + JSONObject jsonPayload = new JSONObject(); + jsonPayload.put(JSON_MESSAGE_KEY, message); + jsonPayload.put(JSON_SIGNATURE_KEY, signedPayload); + return jsonPayload.toString(); + } catch (VirtualFirealarmDeviceMgtPluginException e) { + throw new VirtualFireAlarmException(e); } - return clientPublicKey; - } + } } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java index 14ca5d07d..0e3707e99 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java @@ -19,12 +19,12 @@ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util; import org.wso2.carbon.device.mgt.common.DeviceManagementException; -import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig; -import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig; import org.wso2.carbon.device.mgt.iot.exception.IoTException; import org.wso2.carbon.device.mgt.iot.util.IoTUtil; import org.wso2.carbon.device.mgt.iot.util.IotDeviceManagementUtil; import org.wso2.carbon.device.mgt.iot.util.ZipArchive; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.mqtt.MqttConfig; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppConfig; import org.wso2.carbon.utils.CarbonUtils; import java.io.File; @@ -61,17 +61,15 @@ public class ZipUtil { String httpsServerEP = HTTPS_PROTOCOL_APPENDER + iotServerIP + ":" + httpsServerPort; String httpServerEP = HTTP_PROTOCOL_APPENDER + iotServerIP + ":" + httpServerPort; String apimEndpoint = httpsServerEP; - String mqttEndpoint = MqttConfig.getInstance().getMqttQueueEndpoint(); + String mqttEndpoint = MqttConfig.getInstance().getBrokerEndpoint(); if (mqttEndpoint.contains(LOCALHOST)) { mqttEndpoint = mqttEndpoint.replace(LOCALHOST, iotServerIP); } - String xmppEndpoint = XmppConfig.getInstance().getXmppEndpoint(); - int indexOfChar = xmppEndpoint.lastIndexOf(":"); - if (indexOfChar != -1) { - xmppEndpoint = xmppEndpoint.substring(0, indexOfChar); + String xmppEndpoint = XmppConfig.getInstance().getXmppServerIP() + ":" + + XmppConfig.getInstance().getXmppServerPort(); + if (xmppEndpoint.contains(LOCALHOST)) { + xmppEndpoint = xmppEndpoint.replace(LOCALHOST, iotServerIP); } - xmppEndpoint = xmppEndpoint + ":" + XmppConfig.getInstance().getSERVER_CONNECTION_PORT(); - Map contextParams = new HashMap<>(); contextParams.put("TENANT_DOMAIN", APIUtil.getTenantDomainOftheUser()); contextParams.put("DEVICE_OWNER", owner); @@ -81,7 +79,7 @@ public class ZipUtil { contextParams.put("HTTP_EP", httpServerEP); contextParams.put("APIM_EP", apimEndpoint); contextParams.put("MQTT_EP", mqttEndpoint); - contextParams.put("XMPP_EP", xmppEndpoint); + contextParams.put("XMPP_EP", "XMPP:" + xmppEndpoint); contextParams.put("DEVICE_TOKEN", token); contextParams.put("DEVICE_REFRESH_TOKEN", refreshToken); diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/scep/ContentType.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/scep/ContentType.java deleted file mode 100644 index 672f773bc..000000000 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/scep/ContentType.java +++ /dev/null @@ -1,26 +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.virtualfirealarm.service.impl.util.scep; - -public class ContentType { - public static final String X_PKI_MESSAGE = "application/x-pki-message"; - public static final String X_X509_CA_CERT = "application/x-x509-ca-cert"; - public static final String X_X509_CA_RA_CERT = "application/x-x509-ca-ra-cert"; -} - diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/scep/SCEPOperation.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/scep/SCEPOperation.java deleted file mode 100644 index 563261dd4..000000000 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/scep/SCEPOperation.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.scep; - -public enum SCEPOperation { - GET_CA_CERT("GetCACert"), - GET_CA_CAPS("GetCACaps"), - PKI_OPERATION("PKIOperation"); - - private String value; - - private SCEPOperation(String value) { - this.setValue(value); - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } -} diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/webapp/META-INF/permissions.xml b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/webapp/META-INF/permissions.xml index 5bfa0a85e..8b8957385 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/webapp/META-INF/permissions.xml +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/webapp/META-INF/permissions.xml @@ -44,7 +44,7 @@ Download device - /device-mgt/user + /device-mgt/virtual_firealarm/user /enrollment/devices/download GET virtual_firealarm_user diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/webapp/WEB-INF/cxf-servlet.xml index 62608adfb..dd9427cea 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/webapp/WEB-INF/cxf-servlet.xml +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -27,9 +27,6 @@ - - - @@ -40,15 +37,5 @@ - - - - - - - diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/pom.xml b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/pom.xml index 29b7704e1..25c1b8b2a 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/pom.xml +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/pom.xml @@ -71,11 +71,28 @@ org.wso2.carbon.device.mgt.common, org.wso2.carbon.device.mgt.iot.*, org.wso2.carbon.device.mgt.extensions.feature.mgt.*, - org.wso2.carbon.utils.* + org.wso2.carbon.utils.*, + org.wso2.carbon.event.output.adapter.core, + org.wso2.carbon.event.output.adapter.core.exception, + org.wso2.carbon.base, + org.wso2.carbon.core.util, + org.wso2.carbon.context, + org.wso2.carbon.core, + javax.crypto, + org.apache.commons.codec.binary, + org.json.*;version="${commons-json.version.range}", + org.wso2.carbon.certificate.mgt.core.exception, + org.wso2.carbon.certificate.mgt.core.service, + org.wso2.carbon.certificate.mgt.core.util, + org.wso2.carbon.device.mgt.analytics.data.publisher.exception, + org.wso2.carbon.device.mgt.analytics.data.publisher.service, + org.wso2.carbon.event.input.adapter.core, + org.wso2.carbon.event.input.adapter.core.exception, + org.jivesoftware.smack.* !org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.internal, - org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.* + org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.*, @@ -84,6 +101,10 @@ + + commons-codec.wso2 + commons-codec + org.eclipse.osgi org.eclipse.osgi @@ -100,6 +121,10 @@ org.wso2.carbon.devicemgt org.wso2.carbon.device.mgt.common + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.core + org.wso2.carbon org.wso2.carbon.ndatasource.core @@ -112,5 +137,37 @@ org.wso2.carbon org.wso2.carbon.utils + + org.wso2.carbon.analytics-common + org.wso2.carbon.event.output.adapter.core + + + org.wso2.carbon.analytics-common + org.wso2.carbon.event.input.adapter.core + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.input.adapter.extension + + + org.json.wso2 + json + + + org.wso2.carbon.devicemgt + org.wso2.carbon.certificate.mgt.core + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.analytics.data.publisher + + + org.igniterealtime.smack.wso2 + smack + + + org.igniterealtime.smack.wso2 + smackx + \ No newline at end of file diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/constants/VirtualFireAlarmConstants.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/constants/VirtualFireAlarmConstants.java index 3c8ef2de5..09e3bb718 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/constants/VirtualFireAlarmConstants.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/constants/VirtualFireAlarmConstants.java @@ -18,6 +18,10 @@ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants; +import org.wso2.carbon.utils.CarbonUtils; + +import java.io.File; + public class VirtualFireAlarmConstants { public final static String DEVICE_TYPE = "virtual_firealarm"; public final static String DEVICE_PLUGIN_DEVICE_NAME = "DEVICE_NAME"; @@ -26,17 +30,63 @@ public class VirtualFireAlarmConstants { public final static String STATE_OFF = "OFF"; public static final String URL_PREFIX = "http://"; - public static final String BULB_CONTEXT = "/BULB/"; - public static final String POLICY_CONTEXT = "/POLICY/"; - public static final String HUMIDITY_CONTEXT = "/HUMIDITY/"; - public static final String TEMPERATURE_CONTEXT = "/TEMPERATURE/"; + public static final String BULB_CONTEXT = "BULB"; + public static final String POLICY_CONTEXT = "POLICY"; - public static final String SENSOR_TEMP = "temperature"; //sensor events sumerized table name for temperature public static final String TEMPERATURE_EVENT_TABLE = "DEVICE_TEMPERATURE_SUMMARY"; - public static final String SENSOR_HUMIDITY = "humidity"; - //sensor events summerized table name for humidity - public static final String HUMIDITY_EVENT_TABLE = "DEVICE_HUMIDITY_SUMMARY"; public static final String DATA_SOURCE_NAME = "jdbc/VirtualFireAlarmDM_DB"; public final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super"; + + //mqtt tranport related constants + public static final String MQTT_ADAPTER_NAME = "virtual_firealarm_mqtt"; + public static final String MQTT_ADAPTER_TYPE = "oauth-mqtt"; + public static final String ADAPTER_TOPIC_PROPERTY = "topic"; + public static final String MQTT_PORT = "\\$\\{mqtt.broker.port\\}"; + public static final String MQTT_BROKER_HOST = "\\$\\{mqtt.broker.host\\}"; + public static final String CARBON_CONFIG_PORT_OFFSET = "Ports.Offset"; + public static final String DEFAULT_CARBON_LOCAL_IP_PROPERTY = "carbon.local.ip"; + public static final int CARBON_DEFAULT_PORT_OFFSET = 0; + public static final int DEFAULT_MQTT_PORT = 1883; + + //xmpp transport related constants + public static final String XMPP_ADAPTER_NAME = "virtual_firealarm_xmpp"; + public static final String XMPP_ADAPTER_TYPE = "xmpp"; + public static final String PASSWORD_PROPERTY_KEY = "password"; + public static final String JID_PROPERTY_KEY = "jid"; + public static final String SUBJECT_PROPERTY_KEY = "subject"; + public static final String MESSAGE_TYPE_PROPERTY_KEY = "messageType"; + public static final String CHAT_PROPERTY_KEY = "chat"; + + public static final String USERNAME_PROPERTY_KEY = "username"; + public static final String DCR_PROPERTY_KEY = "dcrUrl"; + public static final String BROKER_URL_PROPERTY_KEY = "url"; + public static final String SCOPES_PROPERTY_KEY = "scopes"; + public static final String QOS_PROPERTY_KEY = "qos"; + public static final String CLIENT_ID_PROPERTY_KEY = "qos"; + public static final String CLEAR_SESSION_PROPERTY_KEY = "clearSession"; + public static final String TOPIC = "topic"; + public static final String SUBSCRIBED_TOPIC = "carbon.super/virtual_firealarm/+/publisher"; + + public static final String CONTENT_VALIDATION = "contentValidation"; + public static final String CONTENT_TRANSFORMATION = "contentTransformer"; + public static final String RESOURCE = "resource"; + + public static final String JSON_SERIAL_KEY = "SerialNumber"; + public static final String TEMPERATURE_STREAM_DEFINITION = "org.wso2.iot.devices.temperature"; + public static final String JSON_MESSAGE_KEY = "Msg"; + public static final String JSON_SIGNATURE_KEY = "Sig"; + + public static final String IS_ENABLED_KEY = "enabled"; + public static final String HOST_KEY = "host"; + public static final String PORT_KEY = "port"; + public static final String CONNECTION_PORT = "connection.port"; + public static final String ADMIN_USERNAME = "admin.username"; + public static final String ADMIN_PASSWORD = "admin.password"; + public static final String XMPP_SERVER_PASSWORD = "admin@123456789"; + + public static final String MQTT_CONFIG_LOCATION = CarbonUtils.getEtcCarbonConfigDirPath() + File.separator + + "mqtt.properties"; + public static final String XMPP_CONFIG_LOCATION = CarbonUtils.getEtcCarbonConfigDirPath() + File.separator + + "xmpp.properties"; } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/VirtualFireAlarmManagerService.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/VirtualFireAlarmManagerService.java index 0371a7aca..00536d67b 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/VirtualFireAlarmManagerService.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/VirtualFireAlarmManagerService.java @@ -52,7 +52,7 @@ public class VirtualFireAlarmManagerService implements DeviceManagementService { @Override public ProvisioningConfig getProvisioningConfig() { - return new ProvisioningConfig(VirtualFireAlarmConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true); + return new ProvisioningConfig(VirtualFireAlarmConstants.DEVICE_TYPE_PROVIDER_DOMAIN, false); } @Override diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFireAlarmUtils.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFireAlarmUtils.java index 216b41f24..011334538 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFireAlarmUtils.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFireAlarmUtils.java @@ -18,22 +18,42 @@ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util; +import org.apache.commons.codec.binary.Base64; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.base.ServerConfiguration; +import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException; +import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.core.util.Utils; +import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException; +import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException; - +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.internal.VirtualFirealarmManagementDataHolder; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppConfig; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration; +import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterException; +import org.wso2.carbon.event.output.adapter.core.MessageType; +import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration; +import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException; +import org.json.JSONObject; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.security.PublicKey; +import java.security.cert.X509Certificate; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.List; +import java.util.HashMap; import java.util.Map; +import java.util.Properties; /** * Contains utility methods used by FireAlarm plugin. @@ -42,26 +62,6 @@ public class VirtualFireAlarmUtils { private static Log log = LogFactory.getLog(VirtualFireAlarmUtils.class); - public static String getDeviceProperty(List deviceProperties, String propertyKey) { - String deviceProperty = ""; - for(Device.Property property :deviceProperties){ - if(propertyKey.equals(property.getName())){ - deviceProperty = property.getValue(); - } - } - return deviceProperty; - } - - public static Device.Property getProperty(String property, String value) { - if (property != null) { - Device.Property prop = new Device.Property(); - prop.setName(property); - prop.setValue(value); - return prop; - } - return null; - } - public static void cleanupResources(Connection conn, PreparedStatement stmt, ResultSet rs) { if (rs != null) { try { @@ -105,7 +105,300 @@ public class VirtualFireAlarmUtils { log.error("Error while looking up the data source: " + VirtualFireAlarmConstants.DATA_SOURCE_NAME); } catch (Exception e) { throw new VirtualFirealarmDeviceMgtPluginException("Error occurred while initializing Iot Device " + - "Management database schema", e); + "Management database schema", e); } } + + public static void setupMqttOutputAdapter() throws IOException { + OutputEventAdapterConfiguration outputEventAdapterConfiguration = + createMqttOutputEventAdapterConfiguration(VirtualFireAlarmConstants.MQTT_ADAPTER_NAME, + VirtualFireAlarmConstants.MQTT_ADAPTER_TYPE, MessageType.TEXT); + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain( + VirtualFireAlarmConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true); + VirtualFirealarmManagementDataHolder.getInstance().getOutputEventAdapterService() + .create(outputEventAdapterConfiguration); + } catch (OutputEventAdapterException e) { + log.error("Unable to create Output Event Adapter : " + VirtualFireAlarmConstants.MQTT_ADAPTER_NAME, e); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } + + public static void setupMqttInputAdapter() throws IOException { + InputEventAdapterConfiguration inputEventAdapterConfiguration = + createMqttInputEventAdapterConfiguration(VirtualFireAlarmConstants.MQTT_ADAPTER_NAME, + VirtualFireAlarmConstants.MQTT_ADAPTER_TYPE, MessageType.TEXT); + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain( + VirtualFireAlarmConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true); + VirtualFirealarmManagementDataHolder.getInstance().getInputEventAdapterService() + .create(inputEventAdapterConfiguration, new VirtualFirealarmEventAdapterSubscription()); + } catch (InputEventAdapterException e) { + log.error("Unable to create Input Event Adapter : " + VirtualFireAlarmConstants.MQTT_ADAPTER_NAME, e); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } + + /** + * Create Output Event Adapter Configuration for given configuration. + * + * @param name Output Event Adapter name + * @param type Output Event Adapter type + * @param msgFormat Output Event Adapter message format + * @return OutputEventAdapterConfiguration instance for given configuration + */ + private static OutputEventAdapterConfiguration createMqttOutputEventAdapterConfiguration(String name, String type, + String msgFormat) throws IOException { + OutputEventAdapterConfiguration outputEventAdapterConfiguration = new OutputEventAdapterConfiguration(); + outputEventAdapterConfiguration.setName(name); + outputEventAdapterConfiguration.setType(type); + outputEventAdapterConfiguration.setMessageFormat(msgFormat); + File configFile = new File(VirtualFireAlarmConstants.MQTT_CONFIG_LOCATION); + if (configFile.exists()) { + Map mqttAdapterProperties = new HashMap<>(); + InputStream propertyStream = configFile.toURI().toURL().openStream(); + Properties properties = new Properties(); + properties.load(propertyStream); + mqttAdapterProperties.put(VirtualFireAlarmConstants.USERNAME_PROPERTY_KEY, properties.getProperty( + VirtualFireAlarmConstants.USERNAME_PROPERTY_KEY)); + mqttAdapterProperties.put(VirtualFireAlarmConstants.DCR_PROPERTY_KEY, Utils.replaceSystemProperty( + properties.getProperty(VirtualFireAlarmConstants.DCR_PROPERTY_KEY))); + mqttAdapterProperties.put(VirtualFireAlarmConstants.BROKER_URL_PROPERTY_KEY, replaceMqttProperty( + properties.getProperty(VirtualFireAlarmConstants.BROKER_URL_PROPERTY_KEY))); + mqttAdapterProperties.put(VirtualFireAlarmConstants.SCOPES_PROPERTY_KEY, properties.getProperty( + VirtualFireAlarmConstants.SCOPES_PROPERTY_KEY)); + mqttAdapterProperties.put(VirtualFireAlarmConstants.CLEAR_SESSION_PROPERTY_KEY, properties.getProperty( + VirtualFireAlarmConstants.CLEAR_SESSION_PROPERTY_KEY)); + mqttAdapterProperties.put(VirtualFireAlarmConstants.QOS_PROPERTY_KEY, properties.getProperty( + VirtualFireAlarmConstants.QOS_PROPERTY_KEY)); + mqttAdapterProperties.put(VirtualFireAlarmConstants.CLIENT_ID_PROPERTY_KEY, ""); + mqttAdapterProperties.put(VirtualFireAlarmConstants.RESOURCE, "output-event"); + outputEventAdapterConfiguration.setStaticProperties(mqttAdapterProperties); + } + return outputEventAdapterConfiguration; + } + + /** + * Create Output Event Adapter Configuration for given configuration. + * + * @param name Input Event Adapter name + * @param type Input Event Adapter type + * @param msgFormat Input Event Adapter message format + * @return InputEventAdapterConfiguration instance for given configuration + */ + private static InputEventAdapterConfiguration createMqttInputEventAdapterConfiguration(String name, String type, + String msgFormat) throws IOException { + InputEventAdapterConfiguration inputEventAdapterConfiguration = new InputEventAdapterConfiguration(); + inputEventAdapterConfiguration.setName(name); + inputEventAdapterConfiguration.setType(type); + inputEventAdapterConfiguration.setMessageFormat(msgFormat); + File configFile = new File(VirtualFireAlarmConstants.MQTT_CONFIG_LOCATION); + if (configFile.exists()) { + Map mqttAdapterProperties = new HashMap<>(); + InputStream propertyStream = configFile.toURI().toURL().openStream(); + Properties properties = new Properties(); + properties.load(propertyStream); + mqttAdapterProperties.put(VirtualFireAlarmConstants.USERNAME_PROPERTY_KEY, properties.getProperty( + VirtualFireAlarmConstants.USERNAME_PROPERTY_KEY)); + mqttAdapterProperties.put(VirtualFireAlarmConstants.DCR_PROPERTY_KEY, Utils.replaceSystemProperty( + properties.getProperty(VirtualFireAlarmConstants.DCR_PROPERTY_KEY))); + mqttAdapterProperties.put(VirtualFireAlarmConstants.BROKER_URL_PROPERTY_KEY, replaceMqttProperty( + properties.getProperty(VirtualFireAlarmConstants.BROKER_URL_PROPERTY_KEY))); + mqttAdapterProperties.put(VirtualFireAlarmConstants.SCOPES_PROPERTY_KEY, properties.getProperty( + VirtualFireAlarmConstants.SCOPES_PROPERTY_KEY)); + mqttAdapterProperties.put(VirtualFireAlarmConstants.CLEAR_SESSION_PROPERTY_KEY, properties.getProperty( + VirtualFireAlarmConstants.CLEAR_SESSION_PROPERTY_KEY)); + mqttAdapterProperties.put(VirtualFireAlarmConstants.QOS_PROPERTY_KEY, properties.getProperty( + VirtualFireAlarmConstants.QOS_PROPERTY_KEY)); + mqttAdapterProperties.put(VirtualFireAlarmConstants.CLIENT_ID_PROPERTY_KEY, ""); + mqttAdapterProperties.put(VirtualFireAlarmConstants.TOPIC, VirtualFireAlarmConstants.SUBSCRIBED_TOPIC); + mqttAdapterProperties.put(VirtualFireAlarmConstants.CONTENT_TRANSFORMATION, + VirtualFirealarmMqttContentTransformer.class.getName()); + mqttAdapterProperties.put(VirtualFireAlarmConstants.CONTENT_VALIDATION, "default"); + mqttAdapterProperties.put(VirtualFireAlarmConstants.RESOURCE, "input-event"); + inputEventAdapterConfiguration.setProperties(mqttAdapterProperties); + } + return inputEventAdapterConfiguration; + } + + public static String replaceMqttProperty(String urlWithPlaceholders) { + urlWithPlaceholders = Utils.replaceSystemProperty(urlWithPlaceholders); + urlWithPlaceholders = urlWithPlaceholders.replaceAll(VirtualFireAlarmConstants.MQTT_PORT, "" + + (VirtualFireAlarmConstants.DEFAULT_MQTT_PORT + getPortOffset())); + urlWithPlaceholders = urlWithPlaceholders.replaceAll(VirtualFireAlarmConstants.MQTT_BROKER_HOST, + System.getProperty(VirtualFireAlarmConstants.DEFAULT_CARBON_LOCAL_IP_PROPERTY, "localhost")); + return urlWithPlaceholders; + } + + private static int getPortOffset() { + ServerConfiguration carbonConfig = ServerConfiguration.getInstance(); + String portOffset = System.getProperty("portOffset", carbonConfig.getFirstProperty( + VirtualFireAlarmConstants.CARBON_CONFIG_PORT_OFFSET)); + try { + if ((portOffset != null)) { + return Integer.parseInt(portOffset.trim()); + } else { + return VirtualFireAlarmConstants.CARBON_DEFAULT_PORT_OFFSET; + } + } catch (NumberFormatException e) { + return VirtualFireAlarmConstants.CARBON_DEFAULT_PORT_OFFSET; + } + } + + public static String extractMessageFromPayload(String message, PublicKey verifySignatureKey) + throws VirtualFirealarmDeviceMgtPluginException { + String actualMessage; + + JSONObject jsonPayload = new JSONObject(message); + Object encodedMessage = jsonPayload.get(VirtualFireAlarmConstants.JSON_MESSAGE_KEY); + Object signedPayload = jsonPayload.get(VirtualFireAlarmConstants.JSON_SIGNATURE_KEY); + + if (encodedMessage != null && signedPayload != null) { + if (VirtualFirealarmSecurityManager.verifySignature( + encodedMessage.toString(), signedPayload.toString(), verifySignatureKey)) { + actualMessage = new String(Base64.decodeBase64(encodedMessage.toString())); + //VirtualFirealarmSecurityManager.decryptMessage(encryptedMessage.toString(), decryptionKey); + } else { + String errorMsg = "The message was not signed by a valid client. Could not verify signature on payload"; + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg); + } + } else { + String errorMsg = "The received message is in an INVALID format. " + + "Need to be JSON - {\"Msg\":\"\", \"Sig\":\"\"}."; + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg); + } + + return actualMessage; + } + + public static PublicKey getDevicePublicKey(String alias) throws VirtualFirealarmDeviceMgtPluginException { + PublicKey clientPublicKey; + try { + CertificateManagementService certificateManagementService = + VirtualFirealarmManagementDataHolder.getInstance().getCertificateManagementService(); + X509Certificate clientCertificate = (X509Certificate) certificateManagementService.getCertificateByAlias( + alias); + clientPublicKey = clientCertificate.getPublicKey(); + } catch (KeystoreException e) { + String errorMsg; + if (e.getMessage().contains("NULL_CERT")) { + errorMsg = "The Device-View page might have been accessed prior to the device being started."; + if(log.isDebugEnabled()){ + log.debug(errorMsg); + } + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); + } else { + errorMsg = "An error occurred whilst trying to retrieve certificate for alias [" + alias + + "] with alias: [" + alias + "]"; + if(log.isDebugEnabled()){ + log.debug(errorMsg); + } + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); + } + } + return clientPublicKey; + } + + public static boolean publishToDAS(String deviceId, float temperature) { + EventsPublisherService deviceAnalyticsService = + VirtualFirealarmManagementDataHolder.getInstance().getEventsPublisherService(); + if (deviceAnalyticsService != null) { + String owner = ""; + Object metdaData[] = {owner, VirtualFireAlarmConstants.DEVICE_TYPE, deviceId, System.currentTimeMillis()}; + Object payloadData[] = {temperature}; + try { + deviceAnalyticsService.publishEvent(VirtualFireAlarmConstants.TEMPERATURE_STREAM_DEFINITION, + "1.0.0", metdaData, new Object[0], payloadData); + } catch (DataPublisherConfigurationException e) { + return false; + } + return true; + } + return false; + } + + public static void setupXmppInputAdapter() throws IOException { + if (!XmppConfig.getInstance().isEnabled()) return; + InputEventAdapterConfiguration inputEventAdapterConfiguration = + createXmppInputEventAdapterConfiguration(VirtualFireAlarmConstants.XMPP_ADAPTER_NAME, + VirtualFireAlarmConstants.XMPP_ADAPTER_TYPE, MessageType.TEXT); + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain( + VirtualFireAlarmConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true); + VirtualFirealarmManagementDataHolder.getInstance().getInputEventAdapterService() + .create(inputEventAdapterConfiguration, new VirtualFirealarmEventAdapterSubscription()); + } catch (InputEventAdapterException e) { + log.error("Unable to create Input Event Adapter : " + VirtualFireAlarmConstants.MQTT_ADAPTER_NAME, e); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } + + /** + * Create Input Event Adapter Configuration for given configuration. + * + * @param name Input Event Adapter name + * @param type Input Event Adapter type + * @param msgFormat Input Event Adapter message format + * @return InputEventAdapterConfiguration instance for given configuration + */ + private static InputEventAdapterConfiguration createXmppInputEventAdapterConfiguration(String name, String type, + String msgFormat) throws IOException { + InputEventAdapterConfiguration inputEventAdapterConfiguration = new InputEventAdapterConfiguration(); + inputEventAdapterConfiguration.setName(name); + inputEventAdapterConfiguration.setType(type); + inputEventAdapterConfiguration.setMessageFormat(msgFormat); + Map xmppAdapterProperties = new HashMap<>(); + XmppConfig xmppConfig = XmppConfig.getInstance(); + xmppAdapterProperties.put(VirtualFireAlarmConstants.HOST_KEY, xmppConfig.getXmppServerIP()); + xmppAdapterProperties.put(VirtualFireAlarmConstants.PORT_KEY, String.valueOf(xmppConfig.getXmppServerPort())); + xmppAdapterProperties.put(VirtualFireAlarmConstants.USERNAME_PROPERTY_KEY, xmppConfig.getVirtualFirealarmAdminUsername()); + xmppAdapterProperties.put(VirtualFireAlarmConstants.PASSWORD_PROPERTY_KEY, xmppConfig.getVirtualFirealarmAdminPassword()); + xmppAdapterProperties.put(VirtualFireAlarmConstants.JID_PROPERTY_KEY, xmppConfig.getVirtualFirealarmAdminJID()); + xmppAdapterProperties.put(VirtualFireAlarmConstants.CONTENT_TRANSFORMATION, + VirtualFirealarmXmppContentTransformer.class.getName()); + xmppAdapterProperties.put(VirtualFireAlarmConstants.CONTENT_VALIDATION, "default"); + inputEventAdapterConfiguration.setProperties(xmppAdapterProperties); + return inputEventAdapterConfiguration; + } + + public static void setupXmppOutputAdapter() throws IOException { + if(!XmppConfig.getInstance().isEnabled()) return; + OutputEventAdapterConfiguration outputEventAdapterConfiguration = + createXmppOutputEventAdapterConfiguration(VirtualFireAlarmConstants.XMPP_ADAPTER_NAME, + VirtualFireAlarmConstants.XMPP_ADAPTER_TYPE, MessageType.TEXT); + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain( + VirtualFireAlarmConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true); + VirtualFirealarmManagementDataHolder.getInstance().getOutputEventAdapterService() + .create(outputEventAdapterConfiguration); + } catch (OutputEventAdapterException e) { + log.error("Unable to create Output Event Adapter : " + VirtualFireAlarmConstants.MQTT_ADAPTER_NAME, e); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } + + private static OutputEventAdapterConfiguration createXmppOutputEventAdapterConfiguration(String name, String type, + String msgFormat) throws IOException { + OutputEventAdapterConfiguration outputEventAdapterConfiguration = new OutputEventAdapterConfiguration(); + outputEventAdapterConfiguration.setName(name); + outputEventAdapterConfiguration.setType(type); + outputEventAdapterConfiguration.setMessageFormat(msgFormat); + Map xmppAdapterProperties = new HashMap<>(); + XmppConfig xmppConfig = XmppConfig.getInstance(); + xmppAdapterProperties.put(VirtualFireAlarmConstants.HOST_KEY, xmppConfig.getXmppServerIP()); + xmppAdapterProperties.put(VirtualFireAlarmConstants.PORT_KEY, String.valueOf(xmppConfig.getXmppServerPort())); + xmppAdapterProperties.put(VirtualFireAlarmConstants.USERNAME_PROPERTY_KEY, xmppConfig.getVirtualFirealarmAdminUsername()); + xmppAdapterProperties.put(VirtualFireAlarmConstants.PASSWORD_PROPERTY_KEY, xmppConfig.getVirtualFirealarmAdminPassword()); + xmppAdapterProperties.put(VirtualFireAlarmConstants.JID_PROPERTY_KEY, xmppConfig.getVirtualFirealarmAdminJID()); + outputEventAdapterConfiguration.setStaticProperties(xmppAdapterProperties); + return outputEventAdapterConfiguration; + } } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmEventAdapterSubscription.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmEventAdapterSubscription.java new file mode 100644 index 000000000..ee3ec6a6e --- /dev/null +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmEventAdapterSubscription.java @@ -0,0 +1,20 @@ +package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util; + +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterSubscription; + +public class VirtualFirealarmEventAdapterSubscription implements InputEventAdapterSubscription { + + @Override + public void onEvent(Object o) { + String msg = (String) o; + if (msg != null && !msg.isEmpty()) { + String[] messages = (msg).split(","); + String deviceId = messages[0]; + String actualMessage = messages[1]; + if (actualMessage.contains("PUBLISHER")) { + float temperature = Float.parseFloat(actualMessage.split(":")[2]); + VirtualFireAlarmUtils.publishToDAS(deviceId, temperature); + } + } + } +} diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmMqttContentTransformer.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmMqttContentTransformer.java new file mode 100644 index 000000000..24d534536 --- /dev/null +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmMqttContentTransformer.java @@ -0,0 +1,39 @@ +package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util; + +import org.json.JSONObject; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentTransformer; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException; + +import java.security.PublicKey; +import java.util.Map; + +public class VirtualFirealarmMqttContentTransformer implements ContentTransformer { + + @Override + public Object transform(Object message, Map dynamicProperties) { + String topic = dynamicProperties.get("topic"); + String[] topicParams = topic.split("/"); + String tenantDomain = topicParams[0]; + String deviceId = topicParams[2]; + JSONObject jsonPayload = new JSONObject((String) message); + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + ctx.setTenantDomain(tenantDomain, true); + Long serialNo = (Long) jsonPayload.get(VirtualFireAlarmConstants.JSON_SERIAL_KEY); + // the hash-code of the deviceId is used as the alias for device certificates during SCEP enrollment. + // hence, the same is used here to fetch the device-specific-certificate from the key store. + PublicKey clientPublicKey = VirtualFireAlarmUtils.getDevicePublicKey("" + serialNo); + + // the MQTT-messages from VirtualFireAlarm devices are in the form {"Msg":, "Sig":} + String actualMessage = VirtualFireAlarmUtils.extractMessageFromPayload((String) message, clientPublicKey); + return deviceId + "," + actualMessage; + } catch (VirtualFirealarmDeviceMgtPluginException e) { + return ""; + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } +} diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/SecurityManager.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmSecurityManager.java similarity index 82% rename from components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/SecurityManager.java rename to components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmSecurityManager.java index 5384db878..257ed36c6 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/SecurityManager.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmSecurityManager.java @@ -16,14 +16,14 @@ * under the License. */ -package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util; +package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util; import org.apache.commons.codec.binary.Base64; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException; import org.wso2.carbon.certificate.mgt.core.util.ConfigurationUtil; -import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; @@ -47,18 +47,18 @@ import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; -public class SecurityManager { - private static final Log log = LogFactory.getLog(SecurityManager.class); +public class VirtualFirealarmSecurityManager { + private static final Log log = LogFactory.getLog(VirtualFirealarmSecurityManager.class); private static PrivateKey serverPrivateKey; private static final String SIGNATURE_ALG = "SHA1withRSA"; private static final String CIPHER_PADDING = "RSA/ECB/PKCS1Padding"; - private SecurityManager() { + private VirtualFirealarmSecurityManager() { } - public void initVerificationManager() { + public static void initVerificationManager() { serverPrivateKey = retrievePrivateKey(ConfigurationUtil.CA_CERT_ALIAS, ConfigurationUtil.KEYSTORE_CA_CERT_PRIV_PASSWORD); } @@ -117,7 +117,8 @@ public class SecurityManager { return serverPrivateKey; } - public static String encryptMessage(String message, Key encryptionKey) throws VirtualFireAlarmException { + public static String encryptMessage(String message, Key encryptionKey) throws + VirtualFirealarmDeviceMgtPluginException { Cipher encrypter; byte[] cipherData; @@ -129,30 +130,29 @@ public class SecurityManager { } catch (NoSuchAlgorithmException e) { String errorMsg = "Algorithm not found exception occurred for Cipher instance of [" + CIPHER_PADDING + "]"; log.error(errorMsg); - throw new VirtualFireAlarmException(errorMsg, e); + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); } catch (NoSuchPaddingException e) { String errorMsg = "No Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]"; log.error(errorMsg); - throw new VirtualFireAlarmException(errorMsg, e); + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); } catch (InvalidKeyException e) { String errorMsg = "InvalidKey exception occurred for encryptionKey \n[\n" + encryptionKey + "\n]\n"; log.error(errorMsg); - throw new VirtualFireAlarmException(errorMsg, e); + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); } catch (BadPaddingException e) { String errorMsg = "Bad Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]"; log.error(errorMsg); - throw new VirtualFireAlarmException(errorMsg, e); + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); } catch (IllegalBlockSizeException e) { String errorMsg = "Illegal blockSize error occurred for Cipher instance of [" + CIPHER_PADDING + "]"; log.error(errorMsg); - throw new VirtualFireAlarmException(errorMsg, e); + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); } return Base64.encodeBase64String(cipherData); } - - public static String signMessage(String encryptedData, PrivateKey signatureKey) throws VirtualFireAlarmException { + public static String signMessage(String encryptedData, PrivateKey signatureKey) throws VirtualFirealarmDeviceMgtPluginException { Signature signature; String signedEncodedString; @@ -168,23 +168,22 @@ public class SecurityManager { } catch (NoSuchAlgorithmException e) { String errorMsg = "Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; log.error(errorMsg); - throw new VirtualFireAlarmException(errorMsg, e); + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); } catch (SignatureException e) { String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; log.error(errorMsg); - throw new VirtualFireAlarmException(errorMsg, e); + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); } catch (InvalidKeyException e) { String errorMsg = "InvalidKey exception occurred for signatureKey \n[\n" + signatureKey + "\n]\n"; log.error(errorMsg); - throw new VirtualFireAlarmException(errorMsg, e); + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); } return signedEncodedString; } - public static boolean verifySignature(String data, String signedData, PublicKey verificationKey) - throws VirtualFireAlarmException { + throws VirtualFirealarmDeviceMgtPluginException { Signature signature; boolean verified; @@ -199,22 +198,21 @@ public class SecurityManager { } catch (NoSuchAlgorithmException e) { String errorMsg = "Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; log.error(errorMsg); - throw new VirtualFireAlarmException(errorMsg, e); + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); } catch (SignatureException e) { String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; log.error(errorMsg); - throw new VirtualFireAlarmException(errorMsg, e); + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); } catch (InvalidKeyException e) { String errorMsg = "InvalidKey exception occurred for signatureKey \n[\n" + verificationKey + "\n]\n"; log.error(errorMsg); - throw new VirtualFireAlarmException(errorMsg, e); + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); } return verified; } - - public static String decryptMessage(String encryptedMessage, Key decryptKey) throws VirtualFireAlarmException { + public static String decryptMessage(String encryptedMessage, Key decryptKey) throws VirtualFirealarmDeviceMgtPluginException { Cipher decrypter; String decryptedMessage; @@ -228,23 +226,23 @@ public class SecurityManager { } catch (NoSuchAlgorithmException e) { String errorMsg = "Algorithm not found exception occurred for Cipher instance of [" + CIPHER_PADDING + "]"; log.error(errorMsg); - throw new VirtualFireAlarmException(errorMsg, e); + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); } catch (NoSuchPaddingException e) { String errorMsg = "No Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]"; log.error(errorMsg); - throw new VirtualFireAlarmException(errorMsg, e); + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); } catch (InvalidKeyException e) { String errorMsg = "InvalidKey exception occurred for encryptionKey \n[\n" + decryptKey + "\n]\n"; log.error(errorMsg); - throw new VirtualFireAlarmException(errorMsg, e); + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); } catch (BadPaddingException e) { String errorMsg = "Bad Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]"; log.error(errorMsg); - throw new VirtualFireAlarmException(errorMsg, e); + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); } catch (IllegalBlockSizeException e) { String errorMsg = "Illegal blockSize error occurred for Cipher instance of [" + CIPHER_PADDING + "]"; log.error(errorMsg); - throw new VirtualFireAlarmException(errorMsg, e); + throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); } return decryptedMessage; diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmStartupListener.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmStartupListener.java new file mode 100644 index 000000000..054085471 --- /dev/null +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmStartupListener.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.core.ServerStartupObserver; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppUtil; + +import java.io.IOException; + +public class VirtualFirealarmStartupListener implements ServerStartupObserver { + private static final Log log = LogFactory.getLog(VirtualFirealarmStartupListener.class); + + @Override + public void completingServerStartup() { + } + + @Override + public void completedServerStartup() { + try { + XmppUtil.createXMPPAccountForDeviceType(); + VirtualFireAlarmUtils.setupMqttOutputAdapter(); + VirtualFireAlarmUtils.setupMqttInputAdapter(); + VirtualFireAlarmUtils.setupXmppInputAdapter(); + VirtualFireAlarmUtils.setupXmppOutputAdapter(); + + } catch (IOException e) { + log.error("Failed to intilaize the virtual firealarm output adapter", e); + } + } + +} diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmXmppContentTransformer.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmXmppContentTransformer.java new file mode 100644 index 000000000..11a99b7bc --- /dev/null +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmXmppContentTransformer.java @@ -0,0 +1,46 @@ +package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util; + +import org.json.JSONObject; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentTransformer; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException; + +import java.security.PublicKey; +import java.util.Map; + +public class VirtualFirealarmXmppContentTransformer implements ContentTransformer { + + @Override + public Object transform(Object message, Map dynamicProperties) { + String from = dynamicProperties.get("from"); + String subject = dynamicProperties.get("subject"); + + int indexOfAt = from.indexOf("@"); + int indexOfSlash = from.indexOf("/"); + + if (indexOfAt != -1 && indexOfSlash != -1) { + String deviceId = from.substring(0, indexOfAt); + JSONObject jsonPayload = new JSONObject((String) message); + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + ctx.setTenantDomain(subject, true); + Long serialNo = (Long) jsonPayload.get(VirtualFireAlarmConstants.JSON_SERIAL_KEY); + // the hash-code of the deviceId is used as the alias for device certificates during SCEP enrollment. + // hence, the same is used here to fetch the device-specific-certificate from the key store. + PublicKey clientPublicKey = VirtualFireAlarmUtils.getDevicePublicKey("" + serialNo); + + // the MQTT-messages from VirtualFireAlarm devices are in the form {"Msg":, "Sig":} + String actualMessage = VirtualFireAlarmUtils.extractMessageFromPayload((String) message, + clientPublicKey); + return deviceId + "," + actualMessage; + } catch (VirtualFirealarmDeviceMgtPluginException e) { + return ""; + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } + return ""; + } +} diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/internal/VirtualFirealarmManagementDataHolder.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/internal/VirtualFirealarmManagementDataHolder.java new file mode 100644 index 000000000..603e716cc --- /dev/null +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/internal/VirtualFirealarmManagementDataHolder.java @@ -0,0 +1,79 @@ +/* + * 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.virtualfirealarm.plugin.internal; + +import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; +import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.VirtualFireAlarmManagerService; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterService; +import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService; + +/** + * DataHolder class of virtual firealarm plugins component. + */ +public class VirtualFirealarmManagementDataHolder { + + private OutputEventAdapterService outputEventAdapterService; + private InputEventAdapterService inputEventAdapterService; + private EventsPublisherService eventsPublisherService; + private CertificateManagementService certificateManagementService; + + private static VirtualFirealarmManagementDataHolder thisInstance = new VirtualFirealarmManagementDataHolder(); + + private VirtualFirealarmManagementDataHolder() { + } + + public static VirtualFirealarmManagementDataHolder getInstance() { + return thisInstance; + } + + public OutputEventAdapterService getOutputEventAdapterService() { + return outputEventAdapterService; + } + + public void setOutputEventAdapterService( + OutputEventAdapterService outputEventAdapterService) { + this.outputEventAdapterService = outputEventAdapterService; + } + + public InputEventAdapterService getInputEventAdapterService() { + return inputEventAdapterService; + } + + public void setInputEventAdapterService(InputEventAdapterService inputEventAdapterService) { + this.inputEventAdapterService = inputEventAdapterService; + } + + public EventsPublisherService getEventsPublisherService() { + return eventsPublisherService; + } + + public void setEventsPublisherService( + EventsPublisherService eventsPublisherService) { + this.eventsPublisherService = eventsPublisherService; + } + + public CertificateManagementService getCertificateManagementService() { + return certificateManagementService; + } + + public void setCertificateManagementService(CertificateManagementService certificateManagementService) { + this.certificateManagementService = certificateManagementService; + } +} diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/internal/VirtualFirealarmManagementServiceComponent.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/internal/VirtualFirealarmManagementServiceComponent.java index bdc3d3a75..c6c8ee64b 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/internal/VirtualFirealarmManagementServiceComponent.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/internal/VirtualFirealarmManagementServiceComponent.java @@ -1,20 +1,20 @@ /* - * 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. - */ +* 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.virtualfirealarm.plugin.internal; @@ -23,15 +23,46 @@ import org.apache.commons.logging.LogFactory; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.osgi.service.component.ComponentContext; +import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; +import org.wso2.carbon.core.ServerStartupObserver; +import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService; import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.VirtualFireAlarmManagerService; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util.VirtualFireAlarmUtils; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util.VirtualFirealarmSecurityManager; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util.VirtualFirealarmStartupListener; +import org.wso2.carbon.event.input.adapter.core.InputEventAdapterService; +import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService; /** * @scr.component name="org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.internal * .VirtualFirealarmManagementServiceComponent" * immediate="true" + * @scr.reference name="event.output.adapter.service" + * interface="org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService" + * cardinality="1..1" + * policy="dynamic" + * bind="setOutputEventAdapterService" + * unbind="unsetOutputEventAdapterService" + * @scr.reference name="event.input.adapter.service" + * interface="org.wso2.carbon.event.input.adapter.core.InputEventAdapterService" + * cardinality="1..1" + * policy="dynamic" + * bind="setInputEventAdapterService" + * unbind="unsetInputEventAdapterService" + * @scr.reference name="certificate.management.service" + * interface="org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService" + * cardinality="1..1" + * policy="dynamic" + * bind="setCertificateManagementService" + * unbind="unsetCertificateManagementService" + * @scr.reference name="event.publisher.service" + * interface="org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService" + * cardinality="1..1" + * policy="dynamic" + * bind="setEventsPublisherService" + * unbind="unsetEventsPublisherService" */ public class VirtualFirealarmManagementServiceComponent { @@ -43,9 +74,12 @@ public class VirtualFirealarmManagementServiceComponent { log.debug("Activating Virtual Firealarm Device Management Service Component"); } try { + VirtualFireAlarmManagerService virtualFireAlarmManagerService = new VirtualFireAlarmManagerService(); BundleContext bundleContext = ctx.getBundleContext(); - firealarmServiceRegRef = bundleContext.registerService(DeviceManagementService.class.getName(), - new VirtualFireAlarmManagerService(), null); + firealarmServiceRegRef = bundleContext.registerService(DeviceManagementService.class.getName() + ,virtualFireAlarmManagerService, null); + bundleContext.registerService(ServerStartupObserver.class.getName(), new VirtualFirealarmStartupListener(), + null); String setupOption = System.getProperty("setup"); if (setupOption != null) { if (log.isDebugEnabled()) { @@ -61,6 +95,7 @@ public class VirtualFirealarmManagementServiceComponent { if (log.isDebugEnabled()) { log.debug("Virtual Firealarm Device Management Service Component has been successfully activated"); } + VirtualFirealarmSecurityManager.initVerificationManager(); } catch (Throwable e) { log.error("Error occurred while activating Virtual Firealarm Device Management Service Component", e); } @@ -81,4 +116,52 @@ public class VirtualFirealarmManagementServiceComponent { log.error("Error occurred while de-activating Virtual Firealarm Device Management bundle", e); } } + + /** + * Initialize the Output EventAdapter Service dependency + * + * @param outputEventAdapterService Output EventAdapter Service reference + */ + protected void setOutputEventAdapterService(OutputEventAdapterService outputEventAdapterService) { + VirtualFirealarmManagementDataHolder.getInstance().setOutputEventAdapterService(outputEventAdapterService); + } + + /** + * De-reference the Output EventAdapter Service dependency. + */ + protected void unsetOutputEventAdapterService(OutputEventAdapterService outputEventAdapterService) { + VirtualFirealarmManagementDataHolder.getInstance().setOutputEventAdapterService(null); + } + + /** + * Initialize the Input EventAdapter Service dependency + * + * @param inputEventAdapterService Input EventAdapter Service reference + */ + protected void setInputEventAdapterService(InputEventAdapterService inputEventAdapterService) { + VirtualFirealarmManagementDataHolder.getInstance().setInputEventAdapterService(inputEventAdapterService); + } + + /** + * De-reference the Input EventAdapter Service dependency. + */ + protected void unsetInputEventAdapterService(InputEventAdapterService inputEventAdapterService) { + VirtualFirealarmManagementDataHolder.getInstance().setInputEventAdapterService(null); + } + + protected void setCertificateManagementService(CertificateManagementService certificateManagementService) { + VirtualFirealarmManagementDataHolder.getInstance().setCertificateManagementService(certificateManagementService); + } + + protected void unsetCertificateManagementService(CertificateManagementService certificateManagementService) { + VirtualFirealarmManagementDataHolder.getInstance().setCertificateManagementService(null); + } + + protected void setEventsPublisherService(EventsPublisherService eventsPublisherService) { + VirtualFirealarmManagementDataHolder.getInstance().setEventsPublisherService(eventsPublisherService); + } + + protected void unsetEventsPublisherService(EventsPublisherService eventsPublisherService) { + VirtualFirealarmManagementDataHolder.getInstance().setEventsPublisherService(null); + } } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/mqtt/MqttConfig.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/mqtt/MqttConfig.java new file mode 100644 index 000000000..e274e87ee --- /dev/null +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/mqtt/MqttConfig.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.mqtt; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util.VirtualFireAlarmUtils; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +public class MqttConfig { + + private static String brokerEndpoint; + + private static MqttConfig mqttConfig = new MqttConfig(); + private static final Log log = LogFactory.getLog(MqttConfig.class); + + private MqttConfig() { + File configFile = new File(VirtualFireAlarmConstants.MQTT_CONFIG_LOCATION); + if (configFile.exists()) { + try { + InputStream propertyStream = configFile.toURI().toURL().openStream(); + Properties properties = new Properties(); + properties.load(propertyStream); + brokerEndpoint = VirtualFireAlarmUtils.replaceMqttProperty( + properties.getProperty(VirtualFireAlarmConstants.BROKER_URL_PROPERTY_KEY)); + } catch (IOException e) { + log.error("Failed to read the mqtt.properties file" + e); + } + } + } + + public static MqttConfig getInstance() { + return mqttConfig; + } + + public String getBrokerEndpoint() { + return brokerEndpoint; + } +} diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/controlqueue/xmpp/XmppAccount.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/xmpp/XmppAccount.java similarity index 89% rename from components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/controlqueue/xmpp/XmppAccount.java rename to components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/xmpp/XmppAccount.java index 94c6dd6d5..f8239a8d9 100644 --- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/controlqueue/xmpp/XmppAccount.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/xmpp/XmppAccount.java @@ -16,8 +16,11 @@ * under the License. */ -package org.wso2.carbon.device.mgt.iot.controlqueue.xmpp; +package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp; +/** + * holds the information related to account that needs to be created on xmpp server. + */ public class XmppAccount { private String username; diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/xmpp/XmppConfig.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/xmpp/XmppConfig.java new file mode 100644 index 000000000..3a0eebebb --- /dev/null +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/xmpp/XmppConfig.java @@ -0,0 +1,100 @@ +/* + * 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.virtualfirealarm.plugin.xmpp; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +public class XmppConfig { + + private String xmppServerIP; + private int xmppServerPort; + private String xmppUsername; + private String xmppPassword; + private boolean isEnabled; + private String virtualFirealarmAdminUsername; + private String virtualFirealarmAdminPassword; + private String virtualFirealarmAdminJID; + private static XmppConfig xmppConfig = new XmppConfig(); + private static final Log log = LogFactory.getLog(XmppConfig.class); + + private XmppConfig() { + File configFile = new File(VirtualFireAlarmConstants.XMPP_CONFIG_LOCATION); + if (configFile.exists()) { + try { + InputStream propertyStream = configFile.toURI().toURL().openStream(); + Properties properties = new Properties(); + properties.load(propertyStream); + xmppServerIP = properties.getProperty(VirtualFireAlarmConstants.HOST_KEY); + xmppServerPort = Integer.parseInt(properties.getProperty(VirtualFireAlarmConstants.PORT_KEY)); + isEnabled = Boolean.parseBoolean(properties.getProperty(VirtualFireAlarmConstants.IS_ENABLED_KEY)); + xmppUsername = properties.getProperty(VirtualFireAlarmConstants.ADMIN_USERNAME); + xmppPassword = properties.getProperty(VirtualFireAlarmConstants.ADMIN_PASSWORD); + virtualFirealarmAdminUsername = "wso2admin_" + VirtualFireAlarmConstants.DEVICE_TYPE; + virtualFirealarmAdminJID = virtualFirealarmAdminUsername + "@" + xmppServerIP; + virtualFirealarmAdminPassword = VirtualFireAlarmConstants.XMPP_SERVER_PASSWORD; + } catch (IOException e) { + log.error(e); + } + } + } + + public String getXmppServerIP() { + return xmppServerIP; + } + + public int getXmppServerPort() { + return xmppServerPort; + } + + public String getXmppUsername() { + return xmppUsername; + } + + public String getXmppPassword() { + return xmppPassword; + } + + public boolean isEnabled() { + return isEnabled; + } + + public static XmppConfig getInstance() { + return xmppConfig; + } + + public String getVirtualFirealarmAdminUsername() { + return virtualFirealarmAdminUsername; + } + + public String getVirtualFirealarmAdminPassword() { + return virtualFirealarmAdminPassword; + } + + public String getVirtualFirealarmAdminJID() { + return virtualFirealarmAdminJID; + } + +} diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/xmpp/XmppServerClient.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/xmpp/XmppServerClient.java new file mode 100644 index 000000000..fccb6c70a --- /dev/null +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/xmpp/XmppServerClient.java @@ -0,0 +1,65 @@ +/* + * 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.virtualfirealarm.plugin.xmpp; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jivesoftware.smack.AccountManager; +import org.jivesoftware.smack.ConnectionConfiguration; +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.XMPPException; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException; + +import java.util.HashMap; +import java.util.Map; + +public class XmppServerClient { + + public static boolean createAccount(XmppAccount xmppAccount) + throws VirtualFirealarmDeviceMgtPluginException { + if (xmppAccount != null) { + try { + ConnectionConfiguration config = new ConnectionConfiguration(XmppConfig.getInstance().getXmppServerIP(), + XmppConfig.getInstance().getXmppServerPort()); + XMPPConnection xmppConnection = new XMPPConnection(config); + xmppConnection.connect(); + xmppConnection.login(XmppConfig.getInstance().getXmppUsername(), XmppConfig.getInstance().getXmppPassword()); + AccountManager accountManager = xmppConnection.getAccountManager(); + Map attributes = new HashMap<>(); + attributes.put("username", xmppAccount.getUsername()); + attributes.put("password", xmppAccount.getPassword()); + attributes.put("email", xmppAccount.getEmail()); + attributes.put("name", xmppAccount.getAccountName()); + accountManager.createAccount(xmppAccount.getUsername(), xmppAccount.getPassword(), attributes); + xmppConnection.disconnect(); + return true; + } catch (XMPPException e) { + if (e.getXMPPError().getCode() == 409) { + //AccountAlreadyExist + return true; + } else { + throw new VirtualFirealarmDeviceMgtPluginException( + "XMPP account creation failed. Error: " + e.getLocalizedMessage(), e); + } + } + } else { + throw new VirtualFirealarmDeviceMgtPluginException("Invalid XMPP attributes"); + } + } +} diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/xmpp/XmppUtil.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/xmpp/XmppUtil.java new file mode 100644 index 000000000..fa6f3c089 --- /dev/null +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/xmpp/XmppUtil.java @@ -0,0 +1,46 @@ +package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLContextBuilder; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; + +/** + * This holds the utility class related to XMPP. + */ +public class XmppUtil { + private static final Log log = LogFactory.getLog(XmppUtil.class); + + public static void createXMPPAccountForDeviceType() { + if (!XmppConfig.getInstance().isEnabled()) { + return; + } + XmppServerClient xmppServerClient = new XmppServerClient(); + try { + XmppAccount xmppAccount = new XmppAccount(); + xmppAccount.setAccountName(XmppConfig.getInstance().getVirtualFirealarmAdminJID()); + xmppAccount.setUsername(XmppConfig.getInstance().getVirtualFirealarmAdminUsername()); + xmppAccount.setPassword(XmppConfig.getInstance().getVirtualFirealarmAdminPassword()); + xmppAccount.setEmail(""); + xmppServerClient.createAccount(xmppAccount); + } catch (VirtualFirealarmDeviceMgtPluginException e) { + String errorMsg = "An error was encountered whilst trying to create Server XMPP account for device-type - " + + VirtualFireAlarmConstants.DEVICE_TYPE; + log.error(errorMsg, e); + } + } +} diff --git a/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/pom.xml b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/pom.xml new file mode 100644 index 000000000..d4b8435ee --- /dev/null +++ b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/pom.xml @@ -0,0 +1,149 @@ + + + + + + + + org.wso2.carbon.devicemgt-plugins + iot-base-plugin-feature + 2.1.0-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.device.mgt.iot.adapter.feature + pom + 2.1.0-SNAPSHOT + WSO2 Carbon - IoT Device Management Feature + http://wso2.org + This feature contains the adapter bundles required for IoT Server + + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.output.adapter.mqtt + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.output.adapter.xmpp + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.input.adapter.extension + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.input.adapter.http + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.input.adapter.mqtt + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.input.adapter.xmpp + + + + + + + maven-resources-plugin + + + copy-resources + generate-resources + + copy-resources + + + src/main/resources + + + resources + + build.properties + p2.inf + + + + + + + + + org.wso2.maven + carbon-p2-plugin + ${carbon.p2.plugin.version} + + + p2-feature-generation + package + + p2-feature-gen + + + org.wso2.carbon.device.mgt.iot.adapter + ../../../features/etc/feature.properties + + + org.wso2.carbon.p2.category.type:server + org.eclipse.equinox.p2.type.group:false + + + + + org.wso2.carbon.devicemgt-plugins:org.wso2.carbon.device.mgt.iot.output.adapter.mqtt:${carbon.devicemgt.plugins.version} + + + org.wso2.carbon.devicemgt-plugins:org.wso2.carbon.device.mgt.iot.output.adapter.xmpp:${carbon.devicemgt.plugins.version} + + + org.wso2.carbon.devicemgt-plugins:org.wso2.carbon.device.mgt.iot.input.adapter.extension:${carbon.devicemgt.plugins.version} + + + org.wso2.carbon.devicemgt-plugins:org.wso2.carbon.device.mgt.iot.input.adapter.http:${carbon.devicemgt.plugins.version} + + + org.wso2.carbon.devicemgt-plugins:org.wso2.carbon.device.mgt.iot.input.adapter.mqtt:${carbon.devicemgt.plugins.version} + + + org.wso2.carbon.devicemgt-plugins:org.wso2.carbon.device.mgt.iot.input.adapter.xmpp:${carbon.devicemgt.plugins.version} + + + + + org.wso2.carbon.event.output.adapter.server:${carbon.analytics.common.version} + + + org.wso2.carbon.event.input.adapter.server:${carbon.analytics.common.version} + + + org.wso2.carbon.identity.jwt.client.extension:${carbon.devicemgt.version} + + + + + + + + + diff --git a/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/src/main/resources/build.properties b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/src/main/resources/build.properties new file mode 100644 index 000000000..33bb0980d --- /dev/null +++ b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/src/main/resources/build.properties @@ -0,0 +1,19 @@ +# +# Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +# +# WSO2 Inc. licenses this file to you under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +custom = true diff --git a/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/src/main/resources/p2.inf b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/src/main/resources/p2.inf new file mode 100644 index 000000000..7ab37b9d7 --- /dev/null +++ b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.adapter.feature/src/main/resources/p2.inf @@ -0,0 +1 @@ +instructions.configure = \ \ No newline at end of file diff --git a/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/pom.xml b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/pom.xml index de37121f2..80aaa6b70 100644 --- a/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/pom.xml +++ b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/pom.xml @@ -54,11 +54,6 @@ org.igniterealtime.smack.wso2 smackx - - net.sf.ehcache.wso2 - ehcache - 1.5.0.wso2v3 - diff --git a/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/conf/devicemgt-config.xml b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/conf/devicemgt-config.xml deleted file mode 100644 index add9c2ee2..000000000 --- a/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/conf/devicemgt-config.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - MQTT - true - org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttControlPublisher - MQTT - - tcp://localhost - 1883 - admin - admin - - - - XMPP - false - org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppServerClient - XMPP - http://localhost - 9090 - admin - admin - - - diff --git a/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/conf/devicemgt-config.xsd b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/conf/devicemgt-config.xsd deleted file mode 100644 index 99b00269e..000000000 --- a/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/conf/devicemgt-config.xsd +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/conf/mqtt.properties b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/conf/mqtt.properties new file mode 100644 index 000000000..8b8867201 --- /dev/null +++ b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/conf/mqtt.properties @@ -0,0 +1,6 @@ +url=tcp://${mqtt.broker.host}:${mqtt.broker.port} +username=admin +dcrUrl=https://localhost:${carbon.https.port}/dynamic-client-web/register +scopes= +clearSession=true +qos=0 \ No newline at end of file diff --git a/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/conf/xmpp.properties b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/conf/xmpp.properties new file mode 100644 index 000000000..23e272d69 --- /dev/null +++ b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/conf/xmpp.properties @@ -0,0 +1,5 @@ +enabled=false +host=localhost +port=5222 +admin.username=admin +admin.password=admin \ No newline at end of file diff --git a/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/p2.inf b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/p2.inf index b493aa4af..0787ff9d7 100644 --- a/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/p2.inf +++ b/features/iot-plugins-feature/iot-base-plugin-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/p2.inf @@ -1,6 +1,6 @@ instructions.configure = \ org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/jaggeryapps/);\ org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot_${feature.version}/jaggeryapps/,target:${installFolder}/../../deployment/server/jaggeryapps/,overwrite:true);\ -org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../conf/iot/);\ -org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot_${feature.version}/conf/devicemgt-config.xml,target:${installFolder}/../../conf/iot/devicemgt-config.xml,overwrite:true);\ -org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot_${feature.version}/conf/devicemgt-config.xsd,target:${installFolder}/../../conf/iot/devicemgt-config.xsd,overwrite:true);\ \ No newline at end of file +org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../conf/etc/);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot_${feature.version}/conf/mqtt.properties,target:${installFolder}/../../conf/etc/mqtt.properties,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot_${feature.version}/conf/xmpp.properties,target:${installFolder}/../../conf/etc/xmpp.properties,overwrite:true);\ \ No newline at end of file diff --git a/features/iot-plugins-feature/iot-base-plugin-feature/pom.xml b/features/iot-plugins-feature/iot-base-plugin-feature/pom.xml index 040202a90..a7ff1b759 100644 --- a/features/iot-plugins-feature/iot-base-plugin-feature/pom.xml +++ b/features/iot-plugins-feature/iot-base-plugin-feature/pom.xml @@ -35,6 +35,7 @@ org.wso2.carbon.device.mgt.iot.feature + org.wso2.carbon.device.mgt.iot.adapter.feature diff --git a/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/deviceConfig.properties b/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/deviceConfig.properties index 06de853d8..133429198 100644 --- a/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/deviceConfig.properties +++ b/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/deviceConfig.properties @@ -20,8 +20,8 @@ owner=${DEVICE_OWNER} deviceId=${DEVICE_ID} device-name=${DEVICE_NAME} controller-context=/raspberrypi/controller -mqtt-sub-topic=wso2/{owner}/raspberrypi/{deviceId} -mqtt-pub-topic=wso2/{owner}/raspberrypi/{deviceId}/publisher +mqtt-sub-topic=${SERVER_NAME}/{owner}/raspberrypi/{deviceId} +mqtt-pub-topic=${SERVER_NAME}/{owner}/raspberrypi/{deviceId}/publisher https-ep=${HTTPS_EP} http-ep=${HTTP_EP} apim-ep=${APIM_EP} diff --git a/features/iot-plugins-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/p2.inf b/features/iot-plugins-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/p2.inf index 1cf4d078d..6d8daf854 100644 --- a/features/iot-plugins-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/p2.inf +++ b/features/iot-plugins-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/p2.inf @@ -16,6 +16,7 @@ org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../data org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot.virtualfirealarm_${feature.version}/database/,target:${installFolder}/../../database/,overwrite:true);\ org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../resources/security/);\ org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot.virtualfirealarm_${feature.version}/certs/,target:${installFolder}/../../resources/security/,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../resources/device-types/);\ instructions.unconfigure = \ org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../conf/device-types/virtual_firealarm.json);\ diff --git a/pom.xml b/pom.xml index 646be5d21..4444a55bd 100644 --- a/pom.xml +++ b/pom.xml @@ -304,6 +304,16 @@ + + org.wso2.carbon.analytics-common + org.wso2.carbon.event.output.adapter.core + ${carbon.analytics.common.version} + + + org.wso2.carbon.analytics-common + org.wso2.carbon.event.input.adapter.core + ${carbon.analytics.common.version} + org.wso2.carbon.analytics-common org.wso2.carbon.databridge.commons @@ -316,16 +326,41 @@ - - - - org.wso2.carbon.devicemgt-plugins org.wso2.carbon.device.mgt.iot ${carbon.devicemgt.plugins.version} - + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.output.adapter.mqtt + ${carbon.devicemgt.plugins.version} + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.output.adapter.xmpp + ${carbon.devicemgt.plugins.version} + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.input.adapter.extension + ${carbon.devicemgt.plugins.version} + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.input.adapter.http + ${carbon.devicemgt.plugins.version} + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.input.adapter.mqtt + ${carbon.devicemgt.plugins.version} + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot.input.adapter.xmpp + ${carbon.devicemgt.plugins.version} + org.wso2.carbon.devicemgt-plugins org.wso2.carbon.device.mgt.iot.api @@ -333,9 +368,7 @@ war - - org.wso2.carbon.devicemgt-plugins org.wso2.carbon.device.mgt.iot.androidsense.plugin @@ -348,9 +381,7 @@ war - - org.wso2.carbon.devicemgt-plugins org.wso2.carbon.device.mgt.iot.arduino.plugin @@ -363,9 +394,7 @@ war - - org.wso2.carbon.devicemgt-plugins org.wso2.carbon.device.mgt.iot.raspberrypi.plugin @@ -378,9 +407,7 @@ war - - org.wso2.carbon.devicemgt-plugins org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin @@ -399,27 +426,17 @@ ${carbon.devicemgt.plugins.version} war - org.wso2.carbon.devicemgt-plugins org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl ${carbon.devicemgt.plugins.version} - org.wso2.carbon.devicemgt-plugins org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.impl ${carbon.devicemgt.plugins.version} - - - - org.wso2.carbon.devicemgt-plugins - org.wso2.carbon.device.mgt.iot.camera.plugin - ${carbon.devicemgt.plugins.version} - - org.wso2.carbon.analytics @@ -443,11 +460,6 @@ org.wso2.carbon.device.mgt.mobile.url.printer ${carbon.devicemgt.plugins.version} - - org.wso2.carbon.devicemgt-plugins - org.wso2.carbon.device.mgt.mobile - ${carbon.devicemgt.plugins.version} - @@ -525,19 +537,6 @@ tomcat-servlet-api ${orbit.version.tomcat-servlet-api} - - - org.wso2.carbon.apimgt org.wso2.carbon.apimgt.api @@ -946,7 +945,11 @@ commons-io ${commons-io.version} - + + com.googlecode.json-simple.wso2 + json-simple + ${json-simple.version} + org.wso2.carbon.identity org.wso2.carbon.identity.oauth.stub @@ -959,7 +962,16 @@ ${carbon.identity.version} provided - + + org.apache.httpcomponents.wso2 + httpcore + ${httpcore.version} + + + org.wso2.orbit.org.apache.httpcomponents + httpclient + ${httpclient.version} + commons-collections commons-collections @@ -970,20 +982,32 @@ commons-configuration ${commons-configuration.version} - org.wso2.carbon.commons org.wso2.carbon.user.mgt ${carbon.commons.version} - junit junit test ${junit.version} - + + com.jayway.jsonpath + json-path + ${json.path.version} + + + org.wso2.orbit.com.nimbusds + nimbus-jose-jwt + ${nimbus.orbit.version} + + + commons-pool.wso2 + commons-pool + ${commons.pool.wso2.version} + @@ -1096,10 +1120,23 @@ 2.4 3.0.0.wso2v1 + (3.0.0, 4.0.0] + 0.9.1 + 1.1.wso2v1 3.2.2 1.8 7.0.59.wso2v1 + + 4.3.1.wso2v2 + [4.3.1, 5.0.0) + 4.3.3.wso2v1 + + + 2.26.1.wso2v3 + [2.26.1, 3.0.0) + + 1.5.6.wso2v1 github-scm