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/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/pom.xml b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/pom.xml
new file mode 100644
index 000000000..922cb286c
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/pom.xml
@@ -0,0 +1,177 @@
+
+
+
+
+ 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
+ bundle
+ WSO2 Carbon - Device Mgt Input Adaptor Module
+ 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.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.input.adapter.internal,
+ org.wso2.carbon.device.mgt.iot.input.adapter.internal.*
+
+
+ !org.wso2.carbon.device.mgt.iot.input.adapter.internal,
+ !org.wso2.carbon.device.mgt.iot.input.adapter.internal.*,
+ org.wso2.carbon.device.mgt.iot.input.adapter.*
+
+
+ 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.*,
+ javax.net.ssl,
+ org.apache.commons.logging,
+ org.apache.http.entity,
+ org.osgi.framework,
+ org.osgi.service.component,
+ org.wso2.carbon.context,
+ org.wso2.carbon.core,
+ javax.servlet,
+ javax.servlet.http,
+ org.apache.axiom.om.util,
+ org.osgi.service.http,
+ org.wso2.carbon.user.api,
+ org.wso2.carbon.user.core.service,
+ org.wso2.carbon.user.core.tenant,
+ org.wso2.carbon.utils,
+ org.wso2.carbon.utils.multitenancy,
+ org.wso2.carbon.identity.oauth2.stub;version="${carbon.identity.version.range}",
+ org.wso2.carbon.identity.oauth2.stub.dto;version="${carbon.identity.version.range}",
+ org.apache.axis2,
+ org.apache.axis2.client,
+ org.apache.axis2.context,
+ org.apache.axis2.transport.http,
+ org.apache.commons.httpclient,
+ org.apache.commons.httpclient.contrib.ssl,
+ org.apache.commons.httpclient.params,
+ org.apache.commons.httpclient.protocol,
+ org.apache.commons.pool,
+ org.apache.commons.pool.impl,
+ 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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/ContentInfo.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/ContentInfo.java
new file mode 100644
index 000000000..0f1cc48f2
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/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;
+
+/**
+ * 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 String msgText;
+
+ public ContentInfo(boolean isValidContent, String msgText) {
+ this.isValidContent = isValidContent;
+ this.msgText = msgText;
+ }
+
+ public boolean isValidContent() {
+ return isValidContent;
+ }
+
+ public void setIsValidContent(boolean isValidContent) {
+ this.isValidContent = isValidContent;
+ }
+
+ public String getMsgText() {
+ return msgText;
+ }
+
+ public void setMsgText(String msgText) {
+ this.msgText = msgText;
+ }
+}
diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/ContentTransformer.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/ContentTransformer.java
new file mode 100644
index 000000000..1e6857d28
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/ContentTransformer.java
@@ -0,0 +1,8 @@
+package org.wso2.carbon.device.mgt.iot.input.adapter;
+
+import java.util.Map;
+
+public interface ContentTransformer {
+
+ String transform(String message, Map dynamicProperties);
+}
diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/ContentValidator.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/ContentValidator.java
new file mode 100644
index 000000000..738d2fa53
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/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;
+
+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(String msgPayload, Map contentValidationParams, Map dynamicParameter);
+}
diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/DefaultContentTransformer.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/DefaultContentTransformer.java
new file mode 100644
index 000000000..f127c29ed
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/DefaultContentTransformer.java
@@ -0,0 +1,14 @@
+package org.wso2.carbon.device.mgt.iot.input.adapter;
+
+import java.util.Map;
+
+/**
+ * This holds the default implementation of ContentTransformer
+ */
+public class DefaultContentTransformer implements ContentTransformer{
+
+ @Override
+ public String transform(String message, Map dynamicProperties) {
+ return message;
+ }
+}
diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/DefaultContentValidator.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/DefaultContentValidator.java
new file mode 100644
index 000000000..f14a5c796
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/DefaultContentValidator.java
@@ -0,0 +1,11 @@
+package org.wso2.carbon.device.mgt.iot.input.adapter;
+
+import java.util.Map;
+
+public class DefaultContentValidator implements ContentValidator {
+ @Override
+ public ContentInfo validate(String msgPayload, Map params, Map dynamicPaarams) {
+ return new ContentInfo(true, msgPayload);
+ }
+
+}
diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/HTTPEventAdapter.java
new file mode 100644
index 000000000..1bf79aca6
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/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.internal.EventAdapterServiceDataHolder;
+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 = EventAdapterServiceDataHolder.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 = EventAdapterServiceDataHolder.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/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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/HTTPEventAdapterFactory.java
new file mode 100644
index 000000000..6730c9a09
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/HTTPEventAdapterFactory.java
@@ -0,0 +1,171 @@
+/*
+ * 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.device.mgt.iot.input.adapter.mqtt.Constants;
+import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.util.MQTTEventAdapterConstants;
+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;
+ private int portOffset;
+
+ public HTTPEventAdapterFactory() {
+ 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.MQTT_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(Constants.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/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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/HTTPMessageServlet.java
new file mode 100644
index 000000000..90934de30
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/HTTPMessageServlet.java
@@ -0,0 +1,394 @@
+/*
+ * 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.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.context.PrivilegedCarbonContext;
+import org.wso2.carbon.device.mgt.iot.input.adapter.ContentInfo;
+import org.wso2.carbon.device.mgt.iot.input.adapter.ContentTransformer;
+import org.wso2.carbon.device.mgt.iot.input.adapter.DefaultContentTransformer;
+import org.wso2.carbon.device.mgt.iot.input.adapter.DefaultContentValidator;
+import org.wso2.carbon.device.mgt.iot.input.adapter.http.exception.HTTPContentInitializationException;
+import org.wso2.carbon.device.mgt.iot.input.adapter.http.oauth.OAuthTokenValidaterStubFactory;
+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.device.mgt.iot.input.adapter.internal.EventAdapterServiceDataHolder;
+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.ContentValidator;
+import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.exception.MQTTContentInitializationException;
+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.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.rmi.RemoteException;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * This will act as the event reciver.
+ */
+public class HTTPMessageServlet extends HttpServlet {
+
+ private static final String AUTHORIZATION_HEADER = "Authorization";
+ 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 final Pattern PATTERN = Pattern.compile("[B|b]earer\\s");
+ private static final String TOKEN_TYPE = "bearer";
+ private static String cookie;
+ private static Log log = LogFactory.getLog(HTTPMessageServlet.class);
+ private GenericObjectPool stubs;
+ private static Map contentValidationProperties;
+ private static ContentValidator contentValidator;
+ private static ContentTransformer contentTransformer;
+ private InputEventAdapterListener eventAdaptorListener;
+ private int tenantId;
+ private String exposedTransports;
+
+ public HTTPMessageServlet(InputEventAdapterListener eventAdaptorListener, int tenantId,
+ InputEventAdapterConfiguration eventAdapterConfiguration) {
+ this.eventAdaptorListener = eventAdaptorListener;
+ this.tenantId = tenantId;
+ this.exposedTransports = eventAdapterConfiguration.getProperties().get(
+ HTTPEventAdapterConstants.EXPOSED_TRANSPORTS);
+ this.stubs = new GenericObjectPool(new OAuthTokenValidaterStubFactory(eventAdapterConfiguration));
+ 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 extends ContentValidator> 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 extends ContentTransformer> 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);
+ }
+ }
+ }
+
+ 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;
+ }
+
+ private AuthenticationInfo checkAuthentication(HttpServletRequest req) {
+ AuthenticationInfo authenticationInfo = (AuthenticationInfo) req.getSession().getAttribute(
+ AUTH_MESSAGE_STORE_AUTHENTICATION_INFO);
+ if (authenticationInfo != null) {
+ return authenticationInfo;
+ }
+ String bearerToken = getBearerToken(req);
+ if (bearerToken == null) {
+ return authenticationInfo;
+ }
+ try {
+ authenticationInfo = validateToken(bearerToken);
+ boolean success = authenticationInfo.isAuthenticated();
+ if (success) {
+ req.getSession().setAttribute(AUTH_MESSAGE_STORE_AUTHENTICATION_INFO, authenticationInfo);
+ }
+ } catch (Exception e) {
+ if (log.isDebugEnabled()) {
+ log.debug("checkAuthentication() fail: " + e.getMessage(), e);
+ }
+ }
+ 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;
+ }
+
+ /**
+ * 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 = EventAdapterServiceDataHolder.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;
+ }
+
+
+ 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();
+ }
+
+ @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 = contentTransformer.transform(data, paramMap);
+ ContentInfo contentInfo = contentValidator.validate(data, contentValidationProperties, paramMap);
+ if (contentInfo != null && contentInfo.isValidContent()) {
+ HTTPEventAdapter.executorService.submit(new HTTPRequestProcessor(eventAdaptorListener,
+ contentInfo.getMsgText(), 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);
+
+ if (log.isDebugEnabled()) {
+ log.debug("Event received in HTTP Event Adapter - " + payload);
+ }
+
+ if (payload.trim() != 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();
+ }
+ }
+
+ }
+
+}
diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/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/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/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/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/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/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/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/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/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/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/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/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/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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/util/HTTPContentValidator.java
new file mode 100644
index 000000000..fe872781d
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/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.ContentInfo;
+import org.wso2.carbon.device.mgt.iot.input.adapter.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(String msgPayload, Map contentValidationParams,
+ Map dynamicParams) {
+ String deviceId = dynamicParams.get("deviceId");
+ String msg = 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/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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/util/HTTPEventAdapterConstants.java
new file mode 100644
index 000000000..e9b81ffff
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/http/util/HTTPEventAdapterConstants.java
@@ -0,0 +1,76 @@
+/*
+ * 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 MQTT_CONTENT_VALIDATION_DEFAULT_PARAMETERS =
+ "device_id_json_path:meta_deviceId";
+ 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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/internal/EventAdapterServiceComponent.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/internal/EventAdapterServiceComponent.java
new file mode 100644
index 000000000..6f101164e
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/internal/EventAdapterServiceComponent.java
@@ -0,0 +1,81 @@
+/*
+* 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.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.device.mgt.iot.input.adapter.mqtt.MQTTEventAdapterFactory;
+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 component.name="input.iot.Mqtt.AdapterService.component" immediate="true"
+ */
+
+/**
+ * @scr.component name="org.wso2.carbon.event.input.adapter.extension.EventAdapterServiceComponent" 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 EventAdapterServiceComponent {
+
+ private static final Log log = LogFactory.getLog(EventAdapterServiceComponent.class);
+
+ protected void activate(ComponentContext context) {
+ try {
+ InputEventAdapterFactory mqttEventAdapterFactory = new MQTTEventAdapterFactory();
+ context.getBundleContext().registerService(InputEventAdapterFactory.class.getName(),
+ mqttEventAdapterFactory, null);
+ InputEventAdapterFactory httpEventEventAdapterFactory = new HTTPEventAdapterFactory();
+ context.getBundleContext().registerService(InputEventAdapterFactory.class.getName(),
+ httpEventEventAdapterFactory, null);
+ 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) {
+ EventAdapterServiceDataHolder.registerRealmService(realmService);
+ }
+
+ protected void unsetRealmService(RealmService realmService) {
+ EventAdapterServiceDataHolder.registerRealmService(null);
+ }
+
+ protected void setHttpService(HttpService httpService) {
+ EventAdapterServiceDataHolder.registerHTTPService(httpService);
+ }
+
+ protected void unsetHttpService(HttpService httpService) {
+ EventAdapterServiceDataHolder.registerHTTPService(null);
+ }
+
+}
diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/internal/EventAdapterServiceDataHolder.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/internal/EventAdapterServiceDataHolder.java
new file mode 100644
index 000000000..cfa866e1b
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/internal/EventAdapterServiceDataHolder.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.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 EventAdapterServiceDataHolder {
+
+ private static RealmService realmService;
+ private static HttpService httpService;
+
+ private EventAdapterServiceDataHolder() {
+ }
+
+ public static void registerRealmService(
+ RealmService realmService) {
+ EventAdapterServiceDataHolder.realmService = realmService;
+ }
+
+ public static RealmService getRealmService() {
+ return realmService;
+ }
+
+ public static void registerHTTPService(
+ HttpService httpService) {
+ EventAdapterServiceDataHolder.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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/Constants.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/Constants.java
new file mode 100644
index 000000000..c411c1193
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/Constants.java
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+/**
+ * This holds the constants related to MQTT input adapter.
+ */
+public class Constants {
+ 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 =
+ "device_id_json_path:event.metaData.deviceId,device_id_topic_hierarchy_index:2";
+ 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/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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/MQTTEventAdapter.java
new file mode 100644
index 000000000..ba7070cce
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/MQTTEventAdapter.java
@@ -0,0 +1,165 @@
+/*
+* 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);
+ String params[] = contentValidationParams.split(",");
+ Map paramsMap = new HashMap<>();
+ 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_VALIDATOR_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/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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/MQTTEventAdapterFactory.java
new file mode 100644
index 000000000..ecff0323a
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/MQTTEventAdapterFactory.java
@@ -0,0 +1,149 @@
+/*
+* 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.device.mgt.iot.input.adapter.xmpp.util.XMPPEventAdapterConstants;
+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(Constants.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(Constants.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(Constants.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/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/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/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/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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTAdapterListener.java
new file mode 100644
index 000000000..d2e8a6366
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTAdapterListener.java
@@ -0,0 +1,305 @@
+/*
+* 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.ContentInfo;
+import org.wso2.carbon.device.mgt.iot.input.adapter.ContentTransformer;
+import org.wso2.carbon.device.mgt.iot.input.adapter.DefaultContentTransformer;
+import org.wso2.carbon.device.mgt.iot.input.adapter.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.ContentValidator;
+import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.Constants;
+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 int keepAlive;
+
+ private MQTTBrokerConnectionConfiguration mqttBrokerConnectionConfiguration;
+ private String mqttClientId;
+ 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.mqttClientId = mqttClientId;
+ this.mqttBrokerConnectionConfiguration = mqttBrokerConnectionConfiguration;
+ this.cleanSession = mqttBrokerConnectionConfiguration.isCleanSession();
+ this.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 {
+ // Construct the connection options object that contains connection parameters
+ // such as cleanSession and LWT
+ connectionOptions = new MqttConnectOptions();
+ connectionOptions.setCleanSession(cleanSession);
+ connectionOptions.setKeepAliveInterval(keepAlive);
+
+ // Construct an MQTT blocking mode client
+ mqttClient = new MqttClient(this.mqttBrokerConnectionConfiguration.getBrokerUrl(), this.mqttClientId,
+ dataStore);
+
+ // Set this wrapper as the callback handler
+ mqttClient.setCallback(this);
+ String contentValidatorClassName = this.mqttBrokerConnectionConfiguration.getContentValidatorClassName();
+
+ if (contentValidatorClassName != null && contentValidatorClassName.equals(Constants.DEFAULT)) {
+ contentValidator = new DefaultContentValidator();
+ } else if (contentValidatorClassName != null && !contentValidatorClassName.isEmpty()) {
+ try {
+ Class extends ContentValidator> 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(Constants.DEFAULT)) {
+ contentTransformer = new DefaultContentTransformer();
+ } else if (contentTransformerClassName != null && !contentTransformerClassName.isEmpty()) {
+ try {
+ Class extends ContentTransformer> 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);
+ } catch (Throwable 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(Constants.EMPTY_STRING);
+ registrationProfile.setGrantType(Constants.GRANT_TYPE);
+ registrationProfile.setOwner(username);
+ registrationProfile.setTokenScope(Constants.TOKEN_SCOPE);
+ registrationProfile.setApplicationType(Constants.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(Constants.CLIENT_ID);
+ String clientSecret = (String) jsonPayload.get(Constants.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();
+ }
+ }
+ }
+ // Connect to the MQTT server
+ mqttClient.connect(connectionOptions);
+
+ // Subscribe to the requested topic
+ // The QoS specified is the maximum level that messages will be sent to the client at.
+ // For instance if QoS 1 is specified, any messages originally published at QoS 2 will
+ // be downgraded to 1 when delivering to the client but messages published at 1 and 0
+ // will be received at the same level they were published at.
+ mqttClient.subscribe(topic);
+ }
+
+ public void stopListener(String adapterName) {
+ if (connectionSucceeded) {
+ try {
+ // Un-subscribe accordingly and disconnect from the MQTT server.
+ 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);
+ }
+ }
+ //This is to stop all running reconnection threads
+ 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(Constants.TOPIC, topic);
+ msgText = contentTransformer.transform(msgText, dynamicProperties);
+ contentInfo = contentValidator.validate(msgText,contentValidationParams, dynamicProperties);
+ if (contentInfo != null && contentInfo.isValidContent()) {
+ eventAdapterListener.onEvent(contentInfo.getMsgText());
+ }
+ } 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/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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTBrokerConnectionConfiguration.java
new file mode 100644
index 000000000..14c171eba
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTBrokerConnectionConfiguration.java
@@ -0,0 +1,131 @@
+/*
+* 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.wso2.carbon.device.mgt.iot.input.adapter.mqtt.Constants;
+import org.wso2.carbon.device.mgt.iot.input.adapter.util.PropertyUtils;
+
+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 void setBrokerScopes(String brokerScopes) {
+ this.brokerScopes = brokerScopes;
+ }
+
+ public String getBrokerUsername() {
+ return brokerUsername;
+ }
+
+ public void setBrokerUsername(String brokerUsername) {
+ this.brokerUsername = brokerUsername;
+ }
+
+ public void setCleanSession(boolean cleanSession) {
+ this.cleanSession = cleanSession;
+ }
+
+
+ public boolean isCleanSession() {
+ return cleanSession;
+ }
+
+ public String getBrokerUrl() {
+ return brokerUrl;
+ }
+
+ public void setBrokerUrl(String brokerUrl) {
+ this.brokerUrl = brokerUrl;
+ }
+
+ public String getDcrUrl() {
+ return dcrUrl;
+ }
+
+ public void setDcrUrl(String dcrUrl) {
+ this.dcrUrl = dcrUrl;
+ }
+
+ public int getKeepAlive() {
+ return keepAlive;
+ }
+
+ public void setKeepAlive(int keepAlive) {
+ this.keepAlive = keepAlive;
+ }
+
+ public String getContentValidatorClassName() {
+ return contentValidatorClassName;
+ }
+
+ public void setContentValidatorClassName(String contentValidatorClassName) {
+ this.contentValidatorClassName = contentValidatorClassName;
+ }
+
+ public Map getContentValidatorParams() {
+ return contentValidatorParams;
+ }
+
+ public void setContentValidatorParams(Map contentValidatorParams) {
+ this.contentValidatorParams = 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 = Constants.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/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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTContentValidator.java
new file mode 100644
index 000000000..5e24715a6
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTContentValidator.java
@@ -0,0 +1,87 @@
+/*
+* 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.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+import org.wso2.carbon.device.mgt.iot.input.adapter.ContentInfo;
+import org.wso2.carbon.device.mgt.iot.input.adapter.ContentValidator;
+import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.Constants;
+
+import java.util.Map;
+
+public class MQTTContentValidator implements ContentValidator {
+ private static String JSON_ARRAY_START_CHAR = "[";
+ private static final Log log = LogFactory.getLog(MQTTContentValidator.class);
+
+ @Override
+ public ContentInfo validate(String msgPayload, Map contentValidationParams,
+ Map dynamicParams) {
+ String topic = dynamicParams.get(Constants.TOPIC);
+ String topics[] = topic.split("/");
+
+ String msg = msgPayload;
+ String deviceIdJsonPath = contentValidationParams.get(Constants.DEVICE_ID_JSON_PATH);
+ String deviceIdInTopicHierarchyLevel = contentValidationParams.get(Constants.DEVICE_ID_TOPIC_HIERARCHY_INDEX);
+ int deviceIdInTopicHierarchyLevelIndex = 0;
+ if (deviceIdInTopicHierarchyLevel != null && !deviceIdInTopicHierarchyLevel.isEmpty()) {
+ deviceIdInTopicHierarchyLevelIndex = Integer.parseInt(deviceIdInTopicHierarchyLevel);
+ }
+ String deviceIdFromTopic = topics[deviceIdInTopicHierarchyLevelIndex];
+ boolean status;
+ if (msg.startsWith(JSON_ARRAY_START_CHAR)) {
+ status = processMultipleEvents(msg, deviceIdFromTopic, deviceIdJsonPath);
+ } else {
+ status = processSingleEvent(msg, deviceIdFromTopic, 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/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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTEventAdapterConstants.java
new file mode 100644
index 000000000..fc5ae8f2c
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/mqtt/util/MQTTEventAdapterConstants.java
@@ -0,0 +1,52 @@
+/*
+* 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;
+}
diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/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/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/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/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/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/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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/util/PropertyUtils.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/util/PropertyUtils.java
new file mode 100644
index 000000000..da872feb9
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/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.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_SERVER_HOST_PROPERTY = "server.host";
+ 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_SERVER_HOST_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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/Constants.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/Constants.java
new file mode 100644
index 000000000..0fcec9983
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/Constants.java
@@ -0,0 +1,32 @@
+/*
+ * 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;
+
+/**
+ * This holds the constants related to MQTT input adapter.
+ */
+public class Constants {
+
+ public static final String DEFAULT = "default";
+ public static final String XMPP_CONTENT_VALIDATION_DEFAULT_PARAMETERS =
+ "device_id_json_path:event.metaData.deviceId,device_id_topic_hierarchy_index:2";
+ public static final String FROM_KEY = "from";
+ public static final String SUBJECT_KEY = "subject";
+ 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/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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/XMPPEventAdapter.java
new file mode 100644
index 000000000..8e580717d
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/XMPPEventAdapter.java
@@ -0,0 +1,161 @@
+/*
+* 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);
+ String params[] = contentValidationParams.split(",");
+ Map paramsMap = new HashMap<>();
+ 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_VALIDATOR_CLASSNAME)
+ );
+
+ xmppAdapterListener = new XMPPAdapterListener(xmppServerConnectionConfiguration,
+ 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() {
+ 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/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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/XMPPEventAdapterFactory.java
new file mode 100644
index 000000000..966703ce7
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/XMPPEventAdapterFactory.java
@@ -0,0 +1,151 @@
+/*
+* 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.mqtt.util.MQTTEventAdapterConstants;
+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(true);
+ 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(org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.Constants.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(Constants.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(Constants.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/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/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/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/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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/util/XMPPAdapterListener.java
new file mode 100644
index 000000000..5dc61811c
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/util/XMPPAdapterListener.java
@@ -0,0 +1,226 @@
+/*
+* 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.ContentInfo;
+import org.wso2.carbon.device.mgt.iot.input.adapter.ContentTransformer;
+import org.wso2.carbon.device.mgt.iot.input.adapter.ContentValidator;
+import org.wso2.carbon.device.mgt.iot.input.adapter.DefaultContentTransformer;
+import org.wso2.carbon.device.mgt.iot.input.adapter.DefaultContentValidator;
+import org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.Constants;
+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 PacketFilter packetFilter;
+ 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(Constants.DEFAULT)) {
+ contentValidator = new DefaultContentValidator();
+ } else if (contentValidatorClassName != null && !contentValidatorClassName.isEmpty()) {
+ try {
+ Class extends ContentValidator> 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(Constants.DEFAULT)) {
+ contentTransformer = new DefaultContentTransformer();
+ } else if (contentTransformerClassName != null && !contentTransformerClassName.isEmpty()) {
+ try {
+ Class extends ContentTransformer> 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 = 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(Constants.FROM_KEY, from);
+ dynamicParmaters.put(Constants.SUBJECT_KEY, subject);
+ message = contentTransformer.transform(message, dynamicParmaters);
+ ContentInfo contentInfo = contentValidator.validate(message, contentValidationParams, dynamicParmaters);
+ if (contentInfo != null && contentInfo.isValidContent()) {
+ eventAdapterListener.onEvent(contentInfo.getMsgText());
+ }
+ } 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/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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/util/XMPPEventAdapterConstants.java
new file mode 100644
index 000000000..dcd89c4c6
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/util/XMPPEventAdapterConstants.java
@@ -0,0 +1,54 @@
+/*
+* 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;
+}
diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/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/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/util/XMPPServerConnectionConfiguration.java
new file mode 100644
index 000000000..34ffc8a11
--- /dev/null
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot.input.adapter/src/main/java/org/wso2/carbon/device/mgt/iot/input/adapter/xmpp/util/XMPPServerConnectionConfiguration.java
@@ -0,0 +1,99 @@
+/*
+* 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.wso2.carbon.device.mgt.iot.input.adapter.util.PropertyUtils;
+import org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.Constants;
+
+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/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/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/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 eventsFor 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/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/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/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/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/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/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..b427bfdf9
--- /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.xmpp 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.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.*,
+ 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/xmpp/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/xmpp/MQTTEventAdapter.java
new file mode 100644
index 000000000..b8402db2d
--- /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/xmpp/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.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.MQTTAdapterPublisher;
+import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.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 org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.util.MQTTEventAdapterConstants;
+
+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();
+ //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) {
+ 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/xmpp/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/xmpp/MQTTEventAdapterFactory.java
new file mode 100644
index 000000000..fd2abb182
--- /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/xmpp/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.xmpp;
+
+import org.wso2.carbon.event.output.adapter.core.*;
+import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.util.MQTTEventAdapterConstants;
+
+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/xmpp/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/xmpp/internal/MQTTEventAdapterServiceComponent.java
new file mode 100644
index 000000000..8af149983
--- /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/xmpp/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.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.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/xmpp/util/Constants.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/xmpp/util/Constants.java
new file mode 100644
index 000000000..7a36d247a
--- /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/xmpp/util/Constants.java
@@ -0,0 +1,32 @@
+/*
+ * 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.xmpp.util;
+
+/**
+ * This holds the constants related to MQTT input adapter.
+ */
+public class Constants {
+ 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/xmpp/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/xmpp/util/MQTTAdapterPublisher.java
new file mode 100644
index 000000000..c7e3103da
--- /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/xmpp/util/MQTTAdapterPublisher.java
@@ -0,0 +1,191 @@
+/*
+* 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.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(Constants.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()) {
+ 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(Constants.DEFAULT_CALLBACK);
+ registrationProfile.setGrantType(Constants.GRANT_TYPE);
+ registrationProfile.setOwner(username);
+ registrationProfile.setTokenScope(Constants.TOKEN_SCOPE);
+ registrationProfile.setApplicationType(Constants.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(Constants.CLIENT_ID);
+ String clientSecret = (String) jsonPayload.get(Constants.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);
+ } finally {
+ PrivilegedCarbonContext.endTenantFlow();
+ }
+ }
+ 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/xmpp/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/xmpp/util/MQTTBrokerConnectionConfiguration.java
new file mode 100644
index 000000000..1dde59d31
--- /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/xmpp/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.xmpp.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/xmpp/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/xmpp/util/MQTTEventAdapterConstants.java
new file mode 100644
index 000000000..f2586c281
--- /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/xmpp/util/MQTTEventAdapterConstants.java
@@ -0,0 +1,54 @@
+/*
+* 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 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";
+
+}
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/xmpp/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/xmpp/util/MQTTUtil.java
new file mode 100644
index 000000000..01c185495
--- /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/xmpp/util/MQTTUtil.java
@@ -0,0 +1,98 @@
+/*
+ * 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.xmpp.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.output.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/iot/output/adapter/xmpp/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/xmpp/util/RegistrationProfile.java
new file mode 100644
index 000000000..9dc855654
--- /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/xmpp/util/RegistrationProfile.java
@@ -0,0 +1,73 @@
+package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.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/xmpp/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/xmpp/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/xmpp/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..211ab3d84
--- /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.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 org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.util.XMPPEventAdapterConstants;
+
+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..687672120
--- /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.event.output.adapter.core.*;
+import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.util.XMPPEventAdapterConstants;
+
+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(true);
+ 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/pom.xml b/components/iot-plugins/iot-base-plugin/pom.xml
index 6c491e480..662ee621f 100644
--- a/components/iot-plugins/iot-base-plugin/pom.xml
+++ b/components/iot-plugins/iot-base-plugin/pom.xml
@@ -35,6 +35,9 @@
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
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..f8f710046 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
@@ -41,27 +41,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 +58,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..bd9bd2d10 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;
@@ -35,6 +35,7 @@ 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.service.impl.dto.SensorRecord;
+import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException;
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.util.APIUtil;
@@ -54,8 +55,12 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import java.nio.charset.StandardCharsets;
+import java.security.PrivateKey;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@SuppressWarnings("Non-Annoted WebService")
@@ -71,26 +76,7 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
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")
@@ -106,7 +92,7 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
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(
@@ -115,29 +101,35 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
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);
break;
default:
String mqttResource = VirtualFireAlarmConstants.BULB_CONTEXT.replace("/", "");
- virtualFireAlarmMQTTConnector.publishDeviceData(deviceId, mqttResource, switchToState);
+ String publishTopic = "wso2/" + APIUtil.getTenantDomainOftheUser() + "/"
+ + VirtualFireAlarmConstants.DEVICE_TYPE + "/" + deviceId;
+ PrivateKey serverPrivateKey = SecurityManager.getServerPrivateKey();
+ String actualMessage = mqttResource + ":" + state.toUpperCase();
+ String encryptedMsg = VirtualFireAlarmServiceUtils.prepareSecurePayLoad(actualMessage,
+ serverPrivateKey);
+ Map dynamicProperties = new HashMap<>();
+ dynamicProperties.put(VirtualFireAlarmConstants.ADAPTER_TOPIC_PROPERTY, publishTopic);
+ APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.ADAPTER_NAME,
+ dynamicProperties, encryptedMsg);
break;
}
return Response.ok().build();
- } catch (DeviceManagementException | TransportHandlerException e) {
+ } catch (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();
}
}
@@ -157,17 +149,14 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
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:
+ 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;
}
return Response.ok().build();
} catch (TransportHandlerException e) {
@@ -179,36 +168,6 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
}
}
- @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
@@ -303,7 +262,8 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
if (waitForServerStartup()) {
return;
}
- VirtualFireAlarmControllerServiceImpl.this.virtualFireAlarmXMPPConnector = virtualFireAlarmXMPPConnector;
+ VirtualFireAlarmControllerServiceImpl.this.virtualFireAlarmXMPPConnector =
+ virtualFireAlarmXMPPConnector;
if (XmppConfig.getInstance().isEnabled()) {
Runnable xmppStarter = new Runnable() {
@@ -318,7 +278,9 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
xmppStarterThread.setDaemon(true);
xmppStarterThread.start();
} else {
- log.warn("XMPP disabled in 'devicemgt-config.xml'. Hence, VirtualFireAlarmXMPPConnector not started.");
+ log.warn(
+ "XMPP disabled in 'devicemgt-config.xml'. Hence, VirtualFireAlarmXMPPConnector not " +
+ "started.");
}
}
};
@@ -357,11 +319,13 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
- VirtualFireAlarmControllerServiceImpl.this.virtualFireAlarmMQTTConnector = virtualFireAlarmMQTTConnector;
+ VirtualFireAlarmControllerServiceImpl.this.virtualFireAlarmMQTTConnector =
+ virtualFireAlarmMQTTConnector;
if (MqttConfig.getInstance().isEnabled()) {
virtualFireAlarmMQTTConnector.connect();
} else {
- log.warn("MQTT disabled in 'devicemgt-config.xml'. Hence, VirtualFireAlarmMQTTConnector not started.");
+ log.warn(
+ "MQTT disabled in 'devicemgt-config.xml'. Hence, VirtualFireAlarmMQTTConnector not started.");
}
}
};
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..71e5f9667 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
@@ -269,8 +269,7 @@ public class VirtualFireAlarmManagerServiceImpl implements VirtualFireAlarmManag
if (XmppConfig.getInstance().isEnabled()) {
status = xmppServerClient.createXMPPAccount(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/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
index 420567952..c39e95b69 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/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
@@ -257,7 +257,6 @@ public class VirtualFireAlarmXMPPConnector extends XMPPTransportHandler {
}
}
};
-
Thread terminatorThread = new Thread(stopConnection);
terminatorThread.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/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/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.plugin/pom.xml b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/pom.xml
index 29b7704e1..c7e044c13 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,17 @@
org.wso2.carbon.device.mgt.common,
org.wso2.carbon.device.mgt.iot.*,
org.wso2.carbon.device.mgt.extensions.feature.mgt.*,
- org.wso2.carbon.utils.*
+ org.wso2.carbon.utils.*,
+ org.wso2.carbon.event.output.adapter.core,
+ org.wso2.carbon.event.output.adapter.core.exception,
+ org.wso2.carbon.base,
+ org.wso2.carbon.core.util,
+ org.wso2.carbon.context,
+ org.wso2.carbon.core
!org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.internal,
- org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.*
+ org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.*,
@@ -112,5 +118,10 @@
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/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..7f69e90de 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
@@ -28,15 +28,28 @@ public class VirtualFireAlarmConstants {
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 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";
+
+ //tranport related constants
+ public static final String ADAPTER_NAME = "virtual_firealarm_mqtt";
+ public static final String 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_SERVER_HOST_PROPERTY = "server.host";
+ 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";
}
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..bf4bc3344 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
@@ -20,20 +20,31 @@ 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.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.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.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.wso2.carbon.utils.CarbonUtils;
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 FireAlarm plugin.
@@ -41,26 +52,9 @@ import java.util.Map;
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;
- }
+ private static final String VIRTUAL_FIREALARM_CONFIG_LOCATION =
+ CarbonUtils.getCarbonHome() + File.separator + "repository" + File.separator + "resources" +
+ File.separator + "device-types" + File.separator + "virtual-firealarm.properties";
public static void cleanupResources(Connection conn, PreparedStatement stmt, ResultSet rs) {
if (rs != null) {
@@ -105,7 +99,89 @@ 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 setupOutputAdapter() throws IOException {
+ OutputEventAdapterConfiguration outputEventAdapterConfiguration =
+ createOutputEventAdapterConfiguration(VirtualFireAlarmConstants.ADAPTER_NAME,
+ VirtualFireAlarmConstants.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.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 createOutputEventAdapterConfiguration(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(VIRTUAL_FIREALARM_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, properties.getProperty(
+ VirtualFireAlarmConstants.CLIENT_ID_PROPERTY_KEY));
+ outputEventAdapterConfiguration.setStaticProperties(mqttAdapterProperties);
+ }
+ return outputEventAdapterConfiguration;
+ }
+
+ 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_SERVER_HOST_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;
}
}
+
}
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..a88200fde
--- /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,43 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package 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 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 {
+ VirtualFireAlarmUtils.setupOutputAdapter();
+ } 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/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..1c3759ccb
--- /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,47 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * you may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.internal;
+
+import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
+
+/**
+ * DataHolder class of virtual firealarm plugins component.
+ */
+public class VirtualFirealarmManagementDataHolder {
+
+ private OutputEventAdapterService outputEventAdapterService;
+
+ 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;
+ }
+}
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..6395656a3 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,24 @@ 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.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.VirtualFirealarmStartupListener;
+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"
*/
public class VirtualFirealarmManagementServiceComponent {
@@ -45,7 +54,9 @@ public class VirtualFirealarmManagementServiceComponent {
try {
BundleContext bundleContext = ctx.getBundleContext();
firealarmServiceRegRef = bundleContext.registerService(DeviceManagementService.class.getName(),
- new VirtualFireAlarmManagerService(), null);
+ new VirtualFireAlarmManagerService(), null);
+ bundleContext.registerService(ServerStartupObserver.class.getName(), new VirtualFirealarmStartupListener(),
+ null);
String setupOption = System.getProperty("setup");
if (setupOption != null) {
if (log.isDebugEnabled()) {
@@ -81,4 +92,22 @@ 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.
+ *
+ * @param outputEventAdapterService
+ */
+ protected void unsetOutputEventAdapterService(OutputEventAdapterService outputEventAdapterService) {
+ VirtualFirealarmManagementDataHolder.getInstance().setOutputEventAdapterService(null);
+ }
}
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..dd33e8dd2 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
@@ -41,6 +41,10 @@
org.wso2.carbon.devicemgt-plugins
org.wso2.carbon.device.mgt.iot
+
+ org.wso2.carbon.devicemgt-plugins
+ org.wso2.carbon.device.mgt.iot.output.adapter.mqtt
+
org.json.wso2
json
@@ -140,6 +144,9 @@
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.json.wso2:json:${commons-json.version}
@@ -158,6 +165,9 @@
org.wso2.carbon.device.mgt.server:${carbon.devicemgt.version}
+
+ org.wso2.carbon.event.output.adapter.server:${carbon.analytics.common.version}
+
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..0b3a15f07 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
@@ -3,4 +3,4 @@ org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../depl
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.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);\
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..b07adfada 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,9 +16,12 @@ 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/);\
+org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot.virtualfirealarm_${feature.version}/virtual-firealarm.properties,target:${installFolder}/../../resources/device-types/virtual-firealarm.properties,overwrite:true);\
instructions.unconfigure = \
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../conf/device-types/virtual_firealarm.json);\
+org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../resources/device-types/virtual_firealarm.properties);\
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../deployment/server/webapps/virtual_firealarm.war);\
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../deployment/server/webapps/virtual_firealarm);\
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../deployment/server/webapps/virtual_firealarm_scep.war);\
diff --git a/features/iot-plugins-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/virtual-firealarm.properties b/features/iot-plugins-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/virtual-firealarm.properties
new file mode 100644
index 000000000..f827a0881
--- /dev/null
+++ b/features/iot-plugins-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/virtual-firealarm.properties
@@ -0,0 +1,7 @@
+url=tcp://${mqtt.broker.host}:${mqtt.broker.port}
+username=admin
+dcrUrl=https://${server.host}:${mgt.transport.https.port}/dynamic-client-web/register
+scopes=
+clearSession=true
+qos=0
+clientId=
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 646be5d21..46e17dd0d 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,16 @@
-
-
-
-
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.api
@@ -333,9 +343,7 @@
war
-
-
org.wso2.carbon.devicemgt-plugins
org.wso2.carbon.device.mgt.iot.androidsense.plugin
@@ -348,9 +356,7 @@
war
-
-
org.wso2.carbon.devicemgt-plugins
org.wso2.carbon.device.mgt.iot.arduino.plugin
@@ -363,9 +369,7 @@
war
-
-
org.wso2.carbon.devicemgt-plugins
org.wso2.carbon.device.mgt.iot.raspberrypi.plugin
@@ -378,9 +382,7 @@
war
-
-
org.wso2.carbon.devicemgt-plugins
org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin
@@ -399,27 +401,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 +435,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 +512,6 @@
tomcat-servlet-api
${orbit.version.tomcat-servlet-api}
-
-
-
org.wso2.carbon.apimgt
org.wso2.carbon.apimgt.api
@@ -946,7 +920,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 +937,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,19 +957,22 @@
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}
+
@@ -1096,11 +1086,16 @@
2.4
3.0.0.wso2v1
+ 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
github-scm