added input and output adapters as transport

This commit is contained in:
ayyoob 2016-05-12 02:44:43 +05:30
parent edaacd4989
commit 44fa7aa486
112 changed files with 2032 additions and 1925 deletions

View File

@ -19,9 +19,9 @@
<eventReceiver name="EventReceiver_AndroidSense" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver"> <eventReceiver name="EventReceiver_AndroidSense" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver">
<from eventAdapterType="oauth-mqtt"> <from eventAdapterType="oauth-mqtt">
<property name="topic">wso2/carbon.super/android_sense/+/data</property> <property name="topic">carbon.super/android_sense/+/data</property>
<property name="username">admin</property> <property name="username">admin</property>
<property name="contentValidationParams">device_id_json_path:event.metaData.deviceId,device_id_topic_hierarchy_index:3</property> <property name="contentValidationParams">device_id_json_path:event.metaData.deviceId,device_id_topic_hierarchy_index:2</property>
<property name="contentValidation">default</property> <property name="contentValidation">default</property>
<property name="dcrUrl">https://${server.host}:${mgt.transport.https.port}/dynamic-client-web/register</property> <property name="dcrUrl">https://${server.host}:${mgt.transport.https.port}/dynamic-client-web/register</property>
<property name="url">tcp://${mqtt.broker.host}:${mqtt.broker.port}</property> <property name="url">tcp://${mqtt.broker.host}:${mqtt.broker.port}</property>

View File

@ -55,8 +55,7 @@ public class ArduinoControllerServiceImpl implements ArduinoControllerService {
public Response switchBulb(@PathParam("deviceId") String deviceId, @QueryParam("state") String state) { public Response switchBulb(@PathParam("deviceId") String deviceId, @QueryParam("state") String state) {
try { try {
if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(new DeviceIdentifier(deviceId, if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(new DeviceIdentifier(deviceId,
ArduinoConstants.DEVICE_TYPE), ArduinoConstants.DEVICE_TYPE), DeviceGroupConstants.Permissions.DEFAULT_OPERATOR_PERMISSIONS)) {
DeviceGroupConstants.Permissions.DEFAULT_OPERATOR_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
} }
LinkedList<String> deviceControlList = internalControlsQueue.get(deviceId); LinkedList<String> deviceControlList = internalControlsQueue.get(deviceId);

View File

@ -19,9 +19,9 @@
<eventReceiver name="temperature-mqtt" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver"> <eventReceiver name="temperature-mqtt" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver">
<from eventAdapterType="oauth-mqtt"> <from eventAdapterType="oauth-mqtt">
<property name="topic">wso2/carbon.super/raspberrypi/+/temperature</property> <property name="topic">carbon.super/+/+/temperature</property>
<property name="username">admin</property> <property name="username">admin</property>
<property name="contentValidationParams">device_id_json_path:event.metaData.deviceId,device_id_topic_hierarchy_index:3</property> <property name="contentValidationParams">device_id_json_path:event.metaData.deviceId,device_id_topic_hierarchy_index:2</property>
<property name="contentValidation">default</property> <property name="contentValidation">default</property>
<property name="dcrUrl">https://${server.host}:${mgt.transport.https.port}/dynamic-client-web/register</property> <property name="dcrUrl">https://${server.host}:${mgt.transport.https.port}/dynamic-client-web/register</property>
<property name="clientId">temperatureMqttClient</property> <property name="clientId">temperatureMqttClient</property>

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>iot-base-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.iot.input.adapter.extension</artifactId>
<packaging>bundle</packaging>
<name>WSO2 Carbon - Device Mgt Input Adaptor Extensions Module</name>
<description>Provides the back-end functionality of Input adaptor</description>
<url>http://wso2.org</url>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name>
<Export-Package>
org.wso2.carbon.device.mgt.iot.input.adapter.extension.*
</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -16,7 +16,7 @@
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.input.adapter; package org.wso2.carbon.device.mgt.iot.input.adapter.extension;
/** /**
* This is the return type of the ContentValidator. * This is the return type of the ContentValidator.
@ -30,11 +30,11 @@ public class ContentInfo {
* msgText to be returned. eg: if the content is encrypted then we can decrypt the content and then validate and * msgText to be returned. eg: if the content is encrypted then we can decrypt the content and then validate and
* return it. * return it.
*/ */
private String msgText; private Object message;
public ContentInfo(boolean isValidContent, String msgText) { public ContentInfo(boolean isValidContent, Object message) {
this.isValidContent = isValidContent; this.isValidContent = isValidContent;
this.msgText = msgText; this.message = message;
} }
public boolean isValidContent() { public boolean isValidContent() {
@ -45,11 +45,11 @@ public class ContentInfo {
this.isValidContent = isValidContent; this.isValidContent = isValidContent;
} }
public String getMsgText() { public Object getMessage() {
return msgText; return message;
} }
public void setMsgText(String msgText) { public void setMessage(Object message) {
this.msgText = msgText; this.message = message;
} }
} }

View File

@ -0,0 +1,17 @@
package org.wso2.carbon.device.mgt.iot.input.adapter.extension;
import java.util.Map;
/**
* Content Transformer will be triggered through input adapters
*/
public interface ContentTransformer {
/**
* This is used to transform the receiver content
* @param message message to be format
* @param dynamicProperties related to transport.
* @return transformed message
*/
Object transform(Object message, Map<String, String> dynamicProperties);
}

View File

@ -16,7 +16,7 @@
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.input.adapter; package org.wso2.carbon.device.mgt.iot.input.adapter.extension;
import java.util.Map; import java.util.Map;
@ -29,5 +29,5 @@ public interface ContentValidator {
* @param dynamicParameter that message. * @param dynamicParameter that message.
* @return ContentInfo. * @return ContentInfo.
*/ */
ContentInfo validate(String msgPayload, Map<String, String> contentValidationParams, Map<String, String> dynamicParameter); ContentInfo validate(Object message, Map<String, String> contentValidationParams, Map<String, String> dynamicParameter);
} }

View File

@ -1,4 +1,4 @@
package org.wso2.carbon.device.mgt.iot.input.adapter; package org.wso2.carbon.device.mgt.iot.input.adapter.extension;
import java.util.Map; import java.util.Map;
@ -8,7 +8,7 @@ import java.util.Map;
public class DefaultContentTransformer implements ContentTransformer{ public class DefaultContentTransformer implements ContentTransformer{
@Override @Override
public String transform(String message, Map<String, String> dynamicProperties) { public Object transform(Object message, Map<String, String> dynamicProperties) {
return message; return message;
} }
} }

View File

@ -0,0 +1,15 @@
package org.wso2.carbon.device.mgt.iot.input.adapter.extension;
import java.util.Map;
/**
* This holds the default implementation of content validator interface.
*/
public class DefaultContentValidator implements ContentValidator {
@Override
public ContentInfo validate(Object message, Map<String, String> params, Map<String, String> dynamicParams) {
return new ContentInfo(true, message);
}
}

View File

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>iot-base-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.iot.input.adapter.http</artifactId>
<packaging>bundle</packaging>
<name>WSO2 Carbon - Device Mgt Input Adaptor Module - Http</name>
<description>Provides the back-end functionality of Input adaptor</description>
<url>http://wso2.org</url>
<dependencies>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.input.adapter.core</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.logging</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.core</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>org.wso2.carbon.device.mgt.iot.input.adapter.extension</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple.wso2</groupId>
<artifactId>json-simple</artifactId>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<artifactId>org.wso2.carbon.identity.oauth.stub</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.orbit.com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.user.api</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.user.core</artifactId>
</dependency>
<dependency>
<groupId>commons-pool.wso2</groupId>
<artifactId>commons-pool</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
<executions>
<execution>
<id>generate-scr-descriptor</id>
<goals>
<goal>scr</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name>
<Private-Package>
org.wso2.carbon.device.mgt.iot.input.adapter.http.internal,
org.wso2.carbon.device.mgt.iot.input.adapter.http.internal.*
</Private-Package>
<Export-Package>
!org.wso2.carbon.device.mgt.iot.input.adapter.http.internal,
!org.wso2.carbon.device.mgt.iot.input.adapter.http.internal.*,
org.wso2.carbon.device.mgt.iot.input.adapter.http.*
</Export-Package>
<Import-Package>
org.wso2.carbon.event.input.adapter.core,
org.wso2.carbon.event.input.adapter.core.*,
javax.xml.namespace; version=0.0.0,
com.jayway.jsonpath.*,
com.nimbusds.jose,
com.nimbusds.jose.crypto,
com.nimbusds.jwt,
org.osgi.framework,
org.osgi.service.component,
javax.servlet,
javax.servlet.http,
org.osgi.service.http,
org.wso2.carbon.user.api,
org.wso2.carbon.user.core.service,
org.wso2.carbon.user.core.tenant,
org.apache.commons.pool,
org.apache.commons.pool.impl
</Import-Package>
<DynamicImport-Package>*</DynamicImport-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -20,7 +20,7 @@ import org.apache.commons.logging.LogFactory;
import org.osgi.service.http.HttpService; import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException; import org.osgi.service.http.NamespaceException;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.iot.input.adapter.internal.InputAdapterServiceDataHolder; import org.wso2.carbon.device.mgt.iot.input.adapter.http.internal.InputAdapterServiceDataHolder;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapter; import org.wso2.carbon.event.input.adapter.core.InputEventAdapter;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration; 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.InputEventAdapterListener;

View File

@ -14,9 +14,6 @@
*/ */
package org.wso2.carbon.device.mgt.iot.input.adapter.http; 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.InputEventAdapter;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration; 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.InputEventAdapterFactory;
@ -40,10 +37,9 @@ public class HTTPEventAdapterFactory extends InputEventAdapterFactory {
ResourceBundle.getBundle("org.wso2.carbon.device.mgt.iot.input.adapter.http.i18n.Resources", Locale.getDefault()); ResourceBundle.getBundle("org.wso2.carbon.device.mgt.iot.input.adapter.http.i18n.Resources", Locale.getDefault());
private int httpPort; private int httpPort;
private int httpsPort; private int httpsPort;
private int portOffset;
public HTTPEventAdapterFactory() { public HTTPEventAdapterFactory() {
portOffset = getPortOffset(); int portOffset = getPortOffset();
httpPort = HTTPEventAdapterConstants.DEFAULT_HTTP_PORT + portOffset; httpPort = HTTPEventAdapterConstants.DEFAULT_HTTP_PORT + portOffset;
httpsPort = HTTPEventAdapterConstants.DEFAULT_HTTPS_PORT + portOffset; httpsPort = HTTPEventAdapterConstants.DEFAULT_HTTPS_PORT + portOffset;
} }
@ -55,7 +51,7 @@ public class HTTPEventAdapterFactory extends InputEventAdapterFactory {
@Override @Override
public List<String> getSupportedMessageFormats() { public List<String> getSupportedMessageFormats() {
List<String> supportInputMessageTypes = new ArrayList<String>(); List<String> supportInputMessageTypes = new ArrayList<>();
supportInputMessageTypes.add(MessageType.JSON); supportInputMessageTypes.add(MessageType.JSON);
supportInputMessageTypes.add(MessageType.TEXT); supportInputMessageTypes.add(MessageType.TEXT);
supportInputMessageTypes.add(MessageType.XML); supportInputMessageTypes.add(MessageType.XML);
@ -66,7 +62,7 @@ public class HTTPEventAdapterFactory extends InputEventAdapterFactory {
@Override @Override
public List<Property> getPropertyList() { public List<Property> getPropertyList() {
List<Property> propertyList = new ArrayList<Property>(); List<Property> propertyList = new ArrayList<>();
// Transport Exposed // Transport Exposed
Property exposedTransportsProperty = new Property(HTTPEventAdapterConstants.EXPOSED_TRANSPORTS); Property exposedTransportsProperty = new Property(HTTPEventAdapterConstants.EXPOSED_TRANSPORTS);
@ -135,7 +131,7 @@ public class HTTPEventAdapterFactory extends InputEventAdapterFactory {
contentValidatorParams.setRequired(false); contentValidatorParams.setRequired(false);
contentValidatorParams.setHint( contentValidatorParams.setHint(
resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS_HINT)); resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS_HINT));
contentValidatorParams.setDefaultValue(HTTPEventAdapterConstants.MQTT_CONTENT_VALIDATION_DEFAULT_PARAMETERS); contentValidatorParams.setDefaultValue(HTTPEventAdapterConstants.HTTP_CONTENT_VALIDATION_DEFAULT_PARAMETERS);
propertyList.add(contentValidatorParams); propertyList.add(contentValidatorParams);
//Content Transformer details //Content Transformer details
@ -145,7 +141,7 @@ public class HTTPEventAdapterFactory extends InputEventAdapterFactory {
contentTransformer.setRequired(false); contentTransformer.setRequired(false);
contentTransformer.setHint( contentTransformer.setHint(
resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT)); resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT));
contentTransformer.setDefaultValue(Constants.DEFAULT); contentTransformer.setDefaultValue(HTTPEventAdapterConstants.DEFAULT);
propertyList.add(contentTransformer); propertyList.add(contentTransformer);
return propertyList; return propertyList;
} }

View File

@ -15,33 +15,21 @@
package org.wso2.carbon.device.mgt.iot.input.adapter.http; 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.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.wso2.carbon.context.PrivilegedCarbonContext; 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.extension.ContentInfo;
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentTransformer; import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentTransformer;
import org.wso2.carbon.device.mgt.iot.input.adapter.DefaultContentTransformer; import org.wso2.carbon.device.mgt.iot.input.adapter.extension.DefaultContentTransformer;
import org.wso2.carbon.device.mgt.iot.input.adapter.DefaultContentValidator; import org.wso2.carbon.device.mgt.iot.input.adapter.extension.DefaultContentValidator;
import org.wso2.carbon.device.mgt.iot.input.adapter.http.exception.HTTPContentInitializationException; import org.wso2.carbon.device.mgt.iot.input.adapter.http.exception.HTTPContentInitializationException;
import org.wso2.carbon.device.mgt.iot.input.adapter.http.jwt.JWTAuthenticator; import org.wso2.carbon.device.mgt.iot.input.adapter.http.jwt.JWTAuthenticator;
import org.wso2.carbon.device.mgt.iot.input.adapter.http.oauth.OAuthAuthenticator; import org.wso2.carbon.device.mgt.iot.input.adapter.http.oauth.OAuthAuthenticator;
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.AuthenticationInfo;
import org.wso2.carbon.device.mgt.iot.input.adapter.http.util.HTTPEventAdapterConstants; import org.wso2.carbon.device.mgt.iot.input.adapter.http.util.HTTPEventAdapterConstants;
import org.wso2.carbon.device.mgt.iot.input.adapter.internal.InputAdapterServiceDataHolder;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration; 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.InputEventAdapterListener;
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentValidator; import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentValidator;
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.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -49,12 +37,9 @@ import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.rmi.RemoteException;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** /**
* This will act as the event reciver. * This will act as the event reciver.
@ -206,11 +191,11 @@ public class HTTPMessageServlet extends HttpServlet {
paramMap.put(HTTPEventAdapterConstants.USERNAME_TAG, authenticationInfo.getUsername()); paramMap.put(HTTPEventAdapterConstants.USERNAME_TAG, authenticationInfo.getUsername());
paramMap.put(HTTPEventAdapterConstants.TENANT_DOMAIN_TAG, authenticationInfo.getTenantDomain()); paramMap.put(HTTPEventAdapterConstants.TENANT_DOMAIN_TAG, authenticationInfo.getTenantDomain());
if (contentValidator != null && contentTransformer != null) { if (contentValidator != null && contentTransformer != null) {
data = contentTransformer.transform(data, paramMap); data = (String) contentTransformer.transform(data, paramMap);
ContentInfo contentInfo = contentValidator.validate(data, contentValidationProperties, paramMap); ContentInfo contentInfo = contentValidator.validate(data, contentValidationProperties, paramMap);
if (contentInfo != null && contentInfo.isValidContent()) { if (contentInfo != null && contentInfo.isValidContent()) {
HTTPEventAdapter.executorService.submit(new HTTPRequestProcessor(eventAdaptorListener, HTTPEventAdapter.executorService.submit(new HTTPRequestProcessor(eventAdaptorListener,
contentInfo.getMsgText(), tenantId)); (String) contentInfo.getMessage(), tenantId));
} }
} }
} }
@ -237,11 +222,11 @@ public class HTTPMessageServlet extends HttpServlet {
public void run() { public void run() {
try { try {
PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Event received in HTTP Event Adapter - " + payload); log.debug("Event received in HTTP Event Adapter - " + payload);
} }
if (payload.trim() != null) { if (payload != null) {
inputEventAdapterListener.onEvent(payload); inputEventAdapterListener.onEvent(payload);
} else { } else {
log.warn("Dropping the empty/null event received through http adapter"); log.warn("Dropping the empty/null event received through http adapter");

View File

@ -15,24 +15,18 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.input.adapter.internal; package org.wso2.carbon.device.mgt.iot.input.adapter.http.internal;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.osgi.service.component.ComponentContext; import org.osgi.service.component.ComponentContext;
import org.osgi.service.http.HttpService; 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.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.event.input.adapter.core.InputEventAdapterFactory;
import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.user.core.service.RealmService;
/** /**
* @scr.component component.name="input.iot.Mqtt.AdapterService.component" immediate="true" * @scr.component name="input.iot.http.AdapterService.component" immediate="true"
*/
/**
* @scr.component name="org.wso2.carbon.event.input.adapter.extension.InputAdapterServiceComponent" immediate="true"
* @scr.reference name="user.realmservice.default" * @scr.reference name="user.realmservice.default"
* interface="org.wso2.carbon.user.core.service.RealmService" cardinality="1..1" * interface="org.wso2.carbon.user.core.service.RealmService" cardinality="1..1"
* policy="dynamic" bind="setRealmService" unbind="unsetRealmService" * policy="dynamic" bind="setRealmService" unbind="unsetRealmService"
@ -41,19 +35,14 @@ import org.wso2.carbon.user.core.service.RealmService;
*/ */
public class InputAdapterServiceComponent { public class InputAdapterServiceComponent {
private static final Log log = LogFactory.getLog(InputAdapterServiceComponent.class); private static final Log log = LogFactory.getLog(
org.wso2.carbon.device.mgt.iot.input.adapter.http.internal.InputAdapterServiceComponent.class);
protected void activate(ComponentContext context) { protected void activate(ComponentContext context) {
try { try {
InputEventAdapterFactory mqttEventAdapterFactory = new MQTTEventAdapterFactory();
context.getBundleContext().registerService(InputEventAdapterFactory.class.getName(),
mqttEventAdapterFactory, null);
InputEventAdapterFactory httpEventEventAdapterFactory = new HTTPEventAdapterFactory(); InputEventAdapterFactory httpEventEventAdapterFactory = new HTTPEventAdapterFactory();
context.getBundleContext().registerService(InputEventAdapterFactory.class.getName(), context.getBundleContext().registerService(InputEventAdapterFactory.class.getName(),
httpEventEventAdapterFactory, null); httpEventEventAdapterFactory, null);
InputEventAdapterFactory xmppEventEventAdapterFactory = new XMPPEventAdapterFactory();
context.getBundleContext().registerService(InputEventAdapterFactory.class.getName(),
xmppEventEventAdapterFactory, null);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Successfully deployed the input adapter service"); log.debug("Successfully deployed the input adapter service");
} }

View File

@ -12,7 +12,7 @@
* CONDITIONS OF ANY KIND, either express or implied. See the License for the * CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License. * specific language governing permissions and limitations under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.input.adapter.internal; package org.wso2.carbon.device.mgt.iot.input.adapter.http.internal;
import org.osgi.service.http.HttpService; import org.osgi.service.http.HttpService;
import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.user.core.service.RealmService;

View File

@ -27,8 +27,8 @@ import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.core.util.KeyStoreManager; import org.wso2.carbon.core.util.KeyStoreManager;
import org.wso2.carbon.device.mgt.iot.input.adapter.http.internal.InputAdapterServiceDataHolder;
import org.wso2.carbon.device.mgt.iot.input.adapter.http.util.AuthenticationInfo; import org.wso2.carbon.device.mgt.iot.input.adapter.http.util.AuthenticationInfo;
import org.wso2.carbon.device.mgt.iot.input.adapter.internal.InputAdapterServiceDataHolder;
import org.wso2.carbon.user.api.TenantManager; import org.wso2.carbon.user.api.TenantManager;
import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.api.UserStoreManager; import org.wso2.carbon.user.api.UserStoreManager;

View File

@ -23,8 +23,8 @@ import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.commons.pool.impl.GenericObjectPool; import org.apache.commons.pool.impl.GenericObjectPool;
import org.wso2.carbon.device.mgt.iot.input.adapter.http.internal.InputAdapterServiceDataHolder;
import org.wso2.carbon.device.mgt.iot.input.adapter.http.util.AuthenticationInfo; import org.wso2.carbon.device.mgt.iot.input.adapter.http.util.AuthenticationInfo;
import org.wso2.carbon.device.mgt.iot.input.adapter.internal.InputAdapterServiceDataHolder;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration; import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration;
import org.wso2.carbon.identity.oauth2.stub.OAuth2TokenValidationServiceStub; 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;

View File

@ -24,8 +24,8 @@ import org.apache.commons.logging.LogFactory;
import org.json.simple.JSONArray; import org.json.simple.JSONArray;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; 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.extension.ContentInfo;
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentValidator; import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentValidator;
import java.util.Map; import java.util.Map;
@ -34,10 +34,10 @@ public class HTTPContentValidator implements ContentValidator {
private static String JSON_ARRAY_START_CHAR = "["; private static String JSON_ARRAY_START_CHAR = "[";
@Override @Override
public ContentInfo validate(String msgPayload, Map<String, String> contentValidationParams, public ContentInfo validate(Object msgPayload, Map<String, String> contentValidationParams,
Map<String, String> dynamicParams) { Map<String, String> dynamicParams) {
String deviceId = dynamicParams.get("deviceId"); String deviceId = dynamicParams.get("deviceId");
String msg = msgPayload; String msg = (String) msgPayload;
String deviceIdJsonPath = contentValidationParams.get(HTTPEventAdapterConstants.DEVICE_ID_JSON_PATH); String deviceIdJsonPath = contentValidationParams.get(HTTPEventAdapterConstants.DEVICE_ID_JSON_PATH);
boolean status; boolean status;
if (msg.startsWith(JSON_ARRAY_START_CHAR)) { if (msg.startsWith(JSON_ARRAY_START_CHAR)) {

View File

@ -69,8 +69,7 @@ public final class HTTPEventAdapterConstants {
public static final String ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS = "contentValidationParams"; 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_VALIDATOR_PARAMS_HINT = "contentValidationParams.hint";
public static final String DEFAULT = "default"; public static final String DEFAULT = "default";
public static final String MQTT_CONTENT_VALIDATION_DEFAULT_PARAMETERS = public static final String HTTP_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 = "contentTransformer";
public static final String ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT = "contentTransformer.hint"; public static final String ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT = "contentTransformer.hint";
} }

View File

@ -25,9 +25,9 @@
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.iot.input.adapter</artifactId> <artifactId>org.wso2.carbon.device.mgt.iot.input.adapter.mqtt</artifactId>
<packaging>bundle</packaging> <packaging>bundle</packaging>
<name>WSO2 Carbon - Device Mgt Input Adaptor Module</name> <name>WSO2 Carbon - Device Mgt Input Adaptor Module - MQTT</name>
<description>Provides the back-end functionality of Input adaptor</description> <description>Provides the back-end functionality of Input adaptor</description>
<url>http://wso2.org</url> <url>http://wso2.org</url>
@ -73,12 +73,8 @@
<artifactId>org.wso2.carbon.identity.oauth.stub</artifactId> <artifactId>org.wso2.carbon.identity.oauth.stub</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.igniterealtime.smack.wso2</groupId> <groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>smack</artifactId> <artifactId>org.wso2.carbon.device.mgt.iot.input.adapter.extension</artifactId>
</dependency>
<dependency>
<groupId>org.igniterealtime.smack.wso2</groupId>
<artifactId>smackx</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>
@ -109,13 +105,13 @@
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name> <Bundle-Name>${project.artifactId}</Bundle-Name>
<Private-Package> <Private-Package>
org.wso2.carbon.device.mgt.iot.input.adapter.internal, org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.internal,
org.wso2.carbon.device.mgt.iot.input.adapter.internal.* org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.internal.*
</Private-Package> </Private-Package>
<Export-Package> <Export-Package>
!org.wso2.carbon.device.mgt.iot.input.adapter.internal, !org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.internal,
!org.wso2.carbon.device.mgt.iot.input.adapter.internal.*, !org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.internal.*,
org.wso2.carbon.device.mgt.iot.input.adapter.* org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.*
</Export-Package> </Export-Package>
<Import-Package> <Import-Package>
org.wso2.carbon.event.input.adapter.core, org.wso2.carbon.event.input.adapter.core,
@ -133,39 +129,7 @@
org.apache.http.impl.client;version="${httpclient.version.range}", org.apache.http.impl.client;version="${httpclient.version.range}",
org.json.simple.*, org.json.simple.*,
org.wso2.carbon.identity.jwt.client.extension.*, org.wso2.carbon.identity.jwt.client.extension.*,
com.jayway.jsonpath.*, 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
</Import-Package> </Import-Package>
<DynamicImport-Package>*</DynamicImport-Package> <DynamicImport-Package>*</DynamicImport-Package>
</instructions> </instructions>

View File

@ -63,16 +63,17 @@ public class MQTTEventAdapter implements InputEventAdapter {
keepAlive = MQTTEventAdapterConstants.ADAPTER_CONF_DEFAULT_KEEP_ALIVE; keepAlive = MQTTEventAdapterConstants.ADAPTER_CONF_DEFAULT_KEEP_ALIVE;
} }
String contentValidationParams = eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS); String contentValidationParams = eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS);
String params[] = contentValidationParams.split(",");
Map<String, String> paramsMap = new HashMap<>(); Map<String, String> paramsMap = new HashMap<>();
for (String param: params) { if (contentValidationParams != null && !contentValidationParams.isEmpty()) {
String paramsKeyAndValue[] = splitOnFirst(param, ':'); String params[] = contentValidationParams.split(",");
if (paramsKeyAndValue.length != 2) { for (String param : params) {
throw new InputEventAdapterException("Invalid parameters for content validation - " + param); String paramsKeyAndValue[] = splitOnFirst(param, ':');
if (paramsKeyAndValue.length != 2) {
throw new InputEventAdapterException("Invalid parameters for content validation - " + param);
}
paramsMap.put(paramsKeyAndValue[0], paramsKeyAndValue[1]);
} }
paramsMap.put(paramsKeyAndValue[0], paramsKeyAndValue[1]);
} }
mqttBrokerConnectionConfiguration = new MQTTBrokerConnectionConfiguration( mqttBrokerConnectionConfiguration = new MQTTBrokerConnectionConfiguration(
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_URL), eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_URL),
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME), eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME),
@ -82,7 +83,7 @@ public class MQTTEventAdapter implements InputEventAdapter {
keepAlive, keepAlive,
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME), eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME),
paramsMap, paramsMap,
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME) eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME)
); );
mqttAdapterListener = new MQTTAdapterListener(mqttBrokerConnectionConfiguration, mqttAdapterListener = new MQTTAdapterListener(mqttBrokerConnectionConfiguration,
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_MESSAGE_TOPIC), eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_MESSAGE_TOPIC),

View File

@ -17,7 +17,6 @@
*/ */
package org.wso2.carbon.device.mgt.iot.input.adapter.mqtt; 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.event.input.adapter.core.*;
import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.util.MQTTEventAdapterConstants; import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.util.MQTTEventAdapterConstants;
@ -78,7 +77,7 @@ public class MQTTEventAdapterFactory extends InputEventAdapterFactory {
contentValidator.setRequired(false); contentValidator.setRequired(false);
contentValidator.setHint( contentValidator.setHint(
resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT)); resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT));
contentValidator.setDefaultValue(Constants.DEFAULT); contentValidator.setDefaultValue(MQTTEventAdapterConstants.DEFAULT);
propertyList.add(contentValidator); propertyList.add(contentValidator);
//Content Validator Params details //Content Validator Params details
@ -88,7 +87,7 @@ public class MQTTEventAdapterFactory extends InputEventAdapterFactory {
contentValidatorParams.setRequired(false); contentValidatorParams.setRequired(false);
contentValidatorParams.setHint( contentValidatorParams.setHint(
resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS_HINT)); resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS_HINT));
contentValidatorParams.setDefaultValue(Constants.MQTT_CONTENT_VALIDATION_DEFAULT_PARAMETERS); contentValidatorParams.setDefaultValue(MQTTEventAdapterConstants.MQTT_CONTENT_VALIDATION_DEFAULT_PARAMETERS);
propertyList.add(contentValidatorParams); propertyList.add(contentValidatorParams);
//Broker Username //Broker Username
@ -123,7 +122,7 @@ public class MQTTEventAdapterFactory extends InputEventAdapterFactory {
contentTransformer.setRequired(false); contentTransformer.setRequired(false);
contentTransformer.setHint( contentTransformer.setHint(
resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT)); resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT));
contentTransformer.setDefaultValue(Constants.DEFAULT); contentTransformer.setDefaultValue(MQTTEventAdapterConstants.DEFAULT);
propertyList.add(contentTransformer); propertyList.add(contentTransformer);
// set clientId // set clientId

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.internal;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.http.HttpService;
import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.MQTTEventAdapterFactory;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterFactory;
import org.wso2.carbon.user.core.service.RealmService;
/**
* @scr.component name="input.iot.mqtt.AdapterService.component" immediate="true"
* @scr.reference name="user.realmservice.default"
* interface="org.wso2.carbon.user.core.service.RealmService" cardinality="1..1"
* policy="dynamic" bind="setRealmService" unbind="unsetRealmService"
*/
public class InputAdapterServiceComponent {
private static final Log log = LogFactory.getLog(InputAdapterServiceComponent.class);
protected void activate(ComponentContext context) {
try {
InputEventAdapterFactory mqttEventAdapterFactory = new MQTTEventAdapterFactory();
context.getBundleContext().registerService(InputEventAdapterFactory.class.getName(),
mqttEventAdapterFactory, null);
if (log.isDebugEnabled()) {
log.debug("Successfully deployed the input adapter service");
}
} catch (RuntimeException e) {
log.error("Can not create the input adapter service ", e);
}
}
protected void setRealmService(RealmService realmService) {
InputAdapterServiceDataHolder.registerRealmService(realmService);
}
protected void unsetRealmService(RealmService realmService) {
InputAdapterServiceDataHolder.registerRealmService(null);
}
protected void setHttpService(HttpService httpService) {
InputAdapterServiceDataHolder.registerHTTPService(httpService);
}
protected void unsetHttpService(HttpService httpService) {
InputAdapterServiceDataHolder.registerHTTPService(null);
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.internal;
import org.osgi.service.http.HttpService;
import org.wso2.carbon.user.core.service.RealmService;
/**
* common place to hold some OSGI service references.
*/
public final class InputAdapterServiceDataHolder {
private static RealmService realmService;
private static HttpService httpService;
private InputAdapterServiceDataHolder() {
}
public static void registerRealmService(
RealmService realmService) {
InputAdapterServiceDataHolder.realmService = realmService;
}
public static RealmService getRealmService() {
return realmService;
}
public static void registerHTTPService(
HttpService httpService) {
InputAdapterServiceDataHolder.httpService = httpService;
}
public static HttpService getHTTPService() {
return httpService;
}
}

View File

@ -31,14 +31,13 @@ import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.ServerStatus; 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.extension.ContentInfo;
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentTransformer; import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentTransformer;
import org.wso2.carbon.device.mgt.iot.input.adapter.DefaultContentTransformer; import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentValidator;
import org.wso2.carbon.device.mgt.iot.input.adapter.DefaultContentValidator; import org.wso2.carbon.device.mgt.iot.input.adapter.extension.DefaultContentTransformer;
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.DefaultContentValidator;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener; import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener;
import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterRuntimeException; 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.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.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
@ -59,10 +58,8 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
private MqttClient mqttClient; private MqttClient mqttClient;
private MqttConnectOptions connectionOptions; private MqttConnectOptions connectionOptions;
private boolean cleanSession; private boolean cleanSession;
private int keepAlive;
private MQTTBrokerConnectionConfiguration mqttBrokerConnectionConfiguration; private MQTTBrokerConnectionConfiguration mqttBrokerConnectionConfiguration;
private String mqttClientId;
private String topic; private String topic;
private int tenantId; private int tenantId;
private boolean connectionSucceeded = false; private boolean connectionSucceeded = false;
@ -80,11 +77,9 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
if(mqttClientId == null || mqttClientId.trim().isEmpty()){ if(mqttClientId == null || mqttClientId.trim().isEmpty()){
mqttClientId = MqttClient.generateClientId(); mqttClientId = MqttClient.generateClientId();
} }
this.mqttClientId = mqttClientId;
this.mqttBrokerConnectionConfiguration = mqttBrokerConnectionConfiguration; this.mqttBrokerConnectionConfiguration = mqttBrokerConnectionConfiguration;
this.cleanSession = mqttBrokerConnectionConfiguration.isCleanSession(); this.cleanSession = mqttBrokerConnectionConfiguration.isCleanSession();
this.keepAlive = mqttBrokerConnectionConfiguration.getKeepAlive(); int keepAlive = mqttBrokerConnectionConfiguration.getKeepAlive();
this.topic = topic; this.topic = topic;
this.eventAdapterListener = inputEventAdapterListener; this.eventAdapterListener = inputEventAdapterListener;
this.tenantId = tenantId; this.tenantId = tenantId;
@ -95,21 +90,19 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
try { try {
// Construct the connection options object that contains connection parameters
// such as cleanSession and LWT
connectionOptions = new MqttConnectOptions(); connectionOptions = new MqttConnectOptions();
connectionOptions.setCleanSession(cleanSession); connectionOptions.setCleanSession(cleanSession);
connectionOptions.setKeepAliveInterval(keepAlive); connectionOptions.setKeepAliveInterval(keepAlive);
// Construct an MQTT blocking mode client // Construct an MQTT blocking mode client
mqttClient = new MqttClient(this.mqttBrokerConnectionConfiguration.getBrokerUrl(), this.mqttClientId, mqttClient = new MqttClient(this.mqttBrokerConnectionConfiguration.getBrokerUrl(), mqttClientId,
dataStore); dataStore);
// Set this wrapper as the callback handler // Set this wrapper as the callback handler
mqttClient.setCallback(this); mqttClient.setCallback(this);
String contentValidatorClassName = this.mqttBrokerConnectionConfiguration.getContentValidatorClassName(); String contentValidatorClassName = this.mqttBrokerConnectionConfiguration.getContentValidatorClassName();
if (contentValidatorClassName != null && contentValidatorClassName.equals(Constants.DEFAULT)) { if (contentValidatorClassName != null && contentValidatorClassName.equals(MQTTEventAdapterConstants.DEFAULT)) {
contentValidator = new DefaultContentValidator(); contentValidator = new DefaultContentValidator();
} else if (contentValidatorClassName != null && !contentValidatorClassName.isEmpty()) { } else if (contentValidatorClassName != null && !contentValidatorClassName.isEmpty()) {
try { try {
@ -130,7 +123,7 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
contentValidationParams = mqttBrokerConnectionConfiguration.getContentValidatorParams(); contentValidationParams = mqttBrokerConnectionConfiguration.getContentValidatorParams();
String contentTransformerClassName = this.mqttBrokerConnectionConfiguration.getContentTransformerClassName(); String contentTransformerClassName = this.mqttBrokerConnectionConfiguration.getContentTransformerClassName();
if (contentTransformerClassName != null && contentTransformerClassName.equals(Constants.DEFAULT)) { if (contentTransformerClassName != null && contentTransformerClassName.equals(MQTTEventAdapterConstants.DEFAULT)) {
contentTransformer = new DefaultContentTransformer(); contentTransformer = new DefaultContentTransformer();
} else if (contentTransformerClassName != null && !contentTransformerClassName.isEmpty()) { } else if (contentTransformerClassName != null && !contentTransformerClassName.isEmpty()) {
try { try {
@ -151,16 +144,12 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
log.error("Exception occurred while subscribing to MQTT broker at " log.error("Exception occurred while subscribing to MQTT broker at "
+ mqttBrokerConnectionConfiguration.getBrokerUrl()); + mqttBrokerConnectionConfiguration.getBrokerUrl());
throw new InputEventAdapterRuntimeException(e); 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 { public void startListener() throws MqttException {
if (this.mqttBrokerConnectionConfiguration.getBrokerUsername() != null && this.mqttBrokerConnectionConfiguration.getDcrUrl() != null) { if (this.mqttBrokerConnectionConfiguration.getBrokerUsername() != null &&
this.mqttBrokerConnectionConfiguration.getDcrUrl() != null) {
String username = this.mqttBrokerConnectionConfiguration.getBrokerUsername(); String username = this.mqttBrokerConnectionConfiguration.getBrokerUsername();
String dcrUrlString = this.mqttBrokerConnectionConfiguration.getDcrUrl(); String dcrUrlString = this.mqttBrokerConnectionConfiguration.getDcrUrl();
String scopes = this.mqttBrokerConnectionConfiguration.getBrokerScopes(); String scopes = this.mqttBrokerConnectionConfiguration.getBrokerScopes();
@ -174,11 +163,11 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
HttpClient httpClient = MQTTUtil.getHttpClient(dcrUrl.getProtocol()); HttpClient httpClient = MQTTUtil.getHttpClient(dcrUrl.getProtocol());
HttpPost postMethod = new HttpPost(dcrUrlString); HttpPost postMethod = new HttpPost(dcrUrlString);
RegistrationProfile registrationProfile = new RegistrationProfile(); RegistrationProfile registrationProfile = new RegistrationProfile();
registrationProfile.setCallbackUrl(Constants.EMPTY_STRING); registrationProfile.setCallbackUrl(MQTTEventAdapterConstants.EMPTY_STRING);
registrationProfile.setGrantType(Constants.GRANT_TYPE); registrationProfile.setGrantType(MQTTEventAdapterConstants.GRANT_TYPE);
registrationProfile.setOwner(username); registrationProfile.setOwner(username);
registrationProfile.setTokenScope(Constants.TOKEN_SCOPE); registrationProfile.setTokenScope(MQTTEventAdapterConstants.TOKEN_SCOPE);
registrationProfile.setApplicationType(Constants.APPLICATION_TYPE); registrationProfile.setApplicationType(MQTTEventAdapterConstants.APPLICATION_TYPE);
registrationProfile.setClientName(username + "_" + tenantId); registrationProfile.setClientName(username + "_" + tenantId);
String jsonString = registrationProfile.toJSON(); String jsonString = registrationProfile.toJSON();
StringEntity requestEntity = new StringEntity(jsonString, ContentType.APPLICATION_JSON); StringEntity requestEntity = new StringEntity(jsonString, ContentType.APPLICATION_JSON);
@ -188,8 +177,8 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
try { try {
JSONParser jsonParser = new JSONParser(); JSONParser jsonParser = new JSONParser();
JSONObject jsonPayload = (JSONObject) jsonParser.parse(response); JSONObject jsonPayload = (JSONObject) jsonParser.parse(response);
String clientId = (String) jsonPayload.get(Constants.CLIENT_ID); String clientId = (String) jsonPayload.get(MQTTEventAdapterConstants.CLIENT_ID);
String clientSecret = (String) jsonPayload.get(Constants.CLIENT_SECRET); String clientSecret = (String) jsonPayload.get(MQTTEventAdapterConstants.CLIENT_SECRET);
JWTClientManagerService jwtClientManagerService = MQTTUtil.getJWTClientManagerService(); JWTClientManagerService jwtClientManagerService = MQTTUtil.getJWTClientManagerService();
AccessTokenInfo accessTokenInfo = jwtClientManagerService.getJWTClient().getAccessToken( AccessTokenInfo accessTokenInfo = jwtClientManagerService.getJWTClient().getAccessToken(
clientId, clientSecret, username, scopes); clientId, clientSecret, username, scopes);
@ -210,31 +199,22 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
} }
} }
} }
// Connect to the MQTT server
mqttClient.connect(connectionOptions); 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); mqttClient.subscribe(topic);
} }
public void stopListener(String adapterName) { public void stopListener(String adapterName) {
if (connectionSucceeded) { if (connectionSucceeded) {
try { try {
// Un-subscribe accordingly and disconnect from the MQTT server.
if (!ServerStatus.getCurrentStatus().equals(ServerStatus.STATUS_SHUTTING_DOWN) || cleanSession) { if (!ServerStatus.getCurrentStatus().equals(ServerStatus.STATUS_SHUTTING_DOWN) || cleanSession) {
mqttClient.unsubscribe(topic); mqttClient.unsubscribe(topic);
} }
mqttClient.disconnect(3000); mqttClient.disconnect(3000);
} catch (MqttException e) { } catch (MqttException e) {
log.error("Can not unsubscribe from the destination " + topic log.error("Can not unsubscribe from the destination " + topic +
+ " with the event adapter " + adapterName, e); " with the event adapter " + adapterName, e);
} }
} }
//This is to stop all running reconnection threads
connectionSucceeded = true; connectionSucceeded = true;
} }
@ -262,11 +242,11 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
if (contentValidator != null && contentTransformer != null) { if (contentValidator != null && contentTransformer != null) {
ContentInfo contentInfo; ContentInfo contentInfo;
Map<String, String> dynamicProperties = new HashMap<>(); Map<String, String> dynamicProperties = new HashMap<>();
dynamicProperties.put(Constants.TOPIC, topic); dynamicProperties.put(MQTTEventAdapterConstants.TOPIC, topic);
msgText = contentTransformer.transform(msgText, dynamicProperties); msgText = (String) contentTransformer.transform(msgText, dynamicProperties);
contentInfo = contentValidator.validate(msgText,contentValidationParams, dynamicProperties); contentInfo = contentValidator.validate(msgText,contentValidationParams, dynamicProperties);
if (contentInfo != null && contentInfo.isValidContent()) { if (contentInfo != null && contentInfo.isValidContent()) {
eventAdapterListener.onEvent(contentInfo.getMsgText()); eventAdapterListener.onEvent(contentInfo.getMessage());
} }
} else { } else {
eventAdapterListener.onEvent(msgText); eventAdapterListener.onEvent(msgText);

View File

@ -17,9 +17,6 @@
*/ */
package org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.util; 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; import java.util.Map;
/** /**
@ -41,23 +38,10 @@ public class MQTTBrokerConnectionConfiguration {
return brokerScopes; return brokerScopes;
} }
public void setBrokerScopes(String brokerScopes) {
this.brokerScopes = brokerScopes;
}
public String getBrokerUsername() { public String getBrokerUsername() {
return brokerUsername; return brokerUsername;
} }
public void setBrokerUsername(String brokerUsername) {
this.brokerUsername = brokerUsername;
}
public void setCleanSession(boolean cleanSession) {
this.cleanSession = cleanSession;
}
public boolean isCleanSession() { public boolean isCleanSession() {
return cleanSession; return cleanSession;
} }
@ -66,42 +50,22 @@ public class MQTTBrokerConnectionConfiguration {
return brokerUrl; return brokerUrl;
} }
public void setBrokerUrl(String brokerUrl) {
this.brokerUrl = brokerUrl;
}
public String getDcrUrl() { public String getDcrUrl() {
return dcrUrl; return dcrUrl;
} }
public void setDcrUrl(String dcrUrl) {
this.dcrUrl = dcrUrl;
}
public int getKeepAlive() { public int getKeepAlive() {
return keepAlive; return keepAlive;
} }
public void setKeepAlive(int keepAlive) {
this.keepAlive = keepAlive;
}
public String getContentValidatorClassName() { public String getContentValidatorClassName() {
return contentValidatorClassName; return contentValidatorClassName;
} }
public void setContentValidatorClassName(String contentValidatorClassName) {
this.contentValidatorClassName = contentValidatorClassName;
}
public Map<String, String> getContentValidatorParams() { public Map<String, String> getContentValidatorParams() {
return contentValidatorParams; return contentValidatorParams;
} }
public void setContentValidatorParams(Map<String, String> contentValidatorParams) {
this.contentValidatorParams = contentValidatorParams;
}
public String getContentTransformerClassName() { public String getContentTransformerClassName() {
return contentTransformerClassName; return contentTransformerClassName;
} }
@ -113,7 +77,7 @@ public class MQTTBrokerConnectionConfiguration {
this.brokerUsername = brokerUsername; this.brokerUsername = brokerUsername;
this.brokerScopes = brokerScopes; this.brokerScopes = brokerScopes;
if (brokerScopes == null) { if (brokerScopes == null) {
this.brokerScopes = Constants.EMPTY_STRING; this.brokerScopes = MQTTEventAdapterConstants.EMPTY_STRING;
} }
this.brokerUrl = PropertyUtils.replaceMqttProperty(brokerUrl); this.brokerUrl = PropertyUtils.replaceMqttProperty(brokerUrl);
this.dcrUrl = PropertyUtils.replaceMqttProperty(dcrUrl); this.dcrUrl = PropertyUtils.replaceMqttProperty(dcrUrl);
@ -125,7 +89,6 @@ public class MQTTBrokerConnectionConfiguration {
if (contentValidatorParams != null) { if (contentValidatorParams != null) {
this.contentValidatorParams = contentValidatorParams; this.contentValidatorParams = contentValidatorParams;
} }
this.contentTransformerClassName = contentTransformerClassName; this.contentTransformerClassName = contentTransformerClassName;
} }
} }

View File

@ -22,40 +22,38 @@ import com.jayway.jsonpath.JsonPath;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.json.simple.JSONArray; import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; 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.extension.ContentInfo;
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentValidator; import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentValidator;
import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.Constants;
import java.util.Map; import java.util.Map;
public class MQTTContentValidator implements ContentValidator { public class MQTTContentValidator implements ContentValidator {
private static String JSON_ARRAY_START_CHAR = "["; private static final String JSON_ARRAY_START_CHAR = "[";
private static final Log log = LogFactory.getLog(MQTTContentValidator.class); private static final Log log = LogFactory.getLog(MQTTContentValidator.class);
@Override @Override
public ContentInfo validate(String msgPayload, Map<String, String> contentValidationParams, public ContentInfo validate(Object msgPayload, Map<String, String> contentValidationParams,
Map<String, String> dynamicParams) { Map<String, String> dynamicParams) {
String topic = dynamicParams.get(Constants.TOPIC); String topic = dynamicParams.get(MQTTEventAdapterConstants.TOPIC);
String topics[] = topic.split("/"); String topics[] = topic.split("/");
String deviceIdJsonPath = contentValidationParams.get(MQTTEventAdapterConstants.DEVICE_ID_JSON_PATH);
String msg = msgPayload; String deviceIdInTopicHierarchyLevel = contentValidationParams.get(
String deviceIdJsonPath = contentValidationParams.get(Constants.DEVICE_ID_JSON_PATH); MQTTEventAdapterConstants.DEVICE_ID_TOPIC_HIERARCHY_INDEX);
String deviceIdInTopicHierarchyLevel = contentValidationParams.get(Constants.DEVICE_ID_TOPIC_HIERARCHY_INDEX);
int deviceIdInTopicHierarchyLevelIndex = 0; int deviceIdInTopicHierarchyLevelIndex = 0;
if (deviceIdInTopicHierarchyLevel != null && !deviceIdInTopicHierarchyLevel.isEmpty()) { if (deviceIdInTopicHierarchyLevel != null && !deviceIdInTopicHierarchyLevel.isEmpty()) {
deviceIdInTopicHierarchyLevelIndex = Integer.parseInt(deviceIdInTopicHierarchyLevel); deviceIdInTopicHierarchyLevelIndex = Integer.parseInt(deviceIdInTopicHierarchyLevel);
} }
String deviceIdFromTopic = topics[deviceIdInTopicHierarchyLevelIndex]; String deviceIdFromTopic = topics[deviceIdInTopicHierarchyLevelIndex];
boolean status; boolean status;
if (msg.startsWith(JSON_ARRAY_START_CHAR)) { String message = (String) msgPayload;
status = processMultipleEvents(msg, deviceIdFromTopic, deviceIdJsonPath); if (message.startsWith(JSON_ARRAY_START_CHAR)) {
status = processMultipleEvents(message, deviceIdFromTopic, deviceIdJsonPath);
} else { } else {
status = processSingleEvent(msg, deviceIdFromTopic, deviceIdJsonPath); status = processSingleEvent(message, deviceIdFromTopic, deviceIdJsonPath);
} }
return new ContentInfo(status, msg); return new ContentInfo(status, msgPayload);
} }
private boolean processSingleEvent(String msg, String deviceIdFromTopic, String deviceIdJsonPath) { private boolean processSingleEvent(String msg, String deviceIdFromTopic, String deviceIdJsonPath) {
@ -75,7 +73,7 @@ public class MQTTContentValidator implements ContentValidator {
for (int i = 0; i < jsonArray.size(); i++) { for (int i = 0; i < jsonArray.size(); i++) {
status = processSingleEvent(jsonArray.get(i).toString(), deviceIdFromTopic, deviceIdJsonPath); status = processSingleEvent(jsonArray.get(i).toString(), deviceIdFromTopic, deviceIdJsonPath);
if (!status) { if (!status) {
return status; return false;
} }
} }
return status; return status;

View File

@ -49,4 +49,18 @@ public class MQTTEventAdapterConstants {
public static int initialReconnectDuration = 10000; public static int initialReconnectDuration = 10000;
public static final int reconnectionProgressionFactor = 2; public static final int reconnectionProgressionFactor = 2;
public static final String EMPTY_STRING = "";
public static final String GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer refresh_token";
public static final String TOKEN_SCOPE = "production";
public static final String APPLICATION_TYPE = "device";
public static final String CLIENT_ID = "client_id";
public static final String CLIENT_SECRET = "client_secret";
public static final String CLIENT_NAME = "client_name";
public static final String DEFAULT = "default";
public static final String MQTT_CONTENT_VALIDATION_DEFAULT_PARAMETERS = "";
public static final String TOPIC = "topic";
public static final String PAYLOAD = "payload";
public static final String DEVICE_ID_JSON_PATH = "device_id_json_path";
public static final String DEVICE_ID_TOPIC_HIERARCHY_INDEX = "device_id_topic_hierarchy_index";
} }

View File

@ -16,7 +16,7 @@
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.input.adapter.util; package org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.util;
import org.wso2.carbon.base.ServerConfiguration; import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.core.util.Utils; import org.wso2.carbon.core.util.Utils;

View File

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
~ Version 2.0 (the "License"); you may not use this file except
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>iot-base-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>2.1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.iot.input.adapter.xmpp</artifactId>
<packaging>bundle</packaging>
<name>WSO2 Carbon - Device Mgt Input Adaptor Module - XMPP</name>
<description>Provides the back-end functionality of Input adaptor</description>
<url>http://wso2.org</url>
<dependencies>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.input.adapter.core</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.logging</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.core</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple.wso2</groupId>
<artifactId>json-simple</artifactId>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
</dependency>
<dependency>
<groupId>org.igniterealtime.smack.wso2</groupId>
<artifactId>smack</artifactId>
</dependency>
<dependency>
<groupId>org.igniterealtime.smack.wso2</groupId>
<artifactId>smackx</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.user.api</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.user.core</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>org.wso2.carbon.device.mgt.iot.input.adapter.extension</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
<executions>
<execution>
<id>generate-scr-descriptor</id>
<goals>
<goal>scr</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name>
<Private-Package>
org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.internal,
org.wso2.carbon.device.mgt.iot.input.adapter.http.internal.*
</Private-Package>
<Export-Package>
!org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.internal,
!org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.internal.*,
org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.*
</Export-Package>
<Import-Package>
org.wso2.carbon.event.input.adapter.core,
org.wso2.carbon.event.input.adapter.core.*,
javax.xml.namespace; version=0.0.0,
org.jivesoftware.smack.*,
org.apache.log4j,
org.wso2.carbon.base,
org.wso2.carbon.core.util
</Import-Package>
<DynamicImport-Package>*</DynamicImport-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -57,16 +57,17 @@ public class XMPPEventAdapter implements InputEventAdapter {
String contentValidationParams = eventAdapterConfiguration.getProperties().get( String contentValidationParams = eventAdapterConfiguration.getProperties().get(
XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS); XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS);
String params[] = contentValidationParams.split(",");
Map<String, String> paramsMap = new HashMap<>(); Map<String, String> paramsMap = new HashMap<>();
for (String param : params) { if (contentValidationParams != null && !contentValidationParams.isEmpty()) {
String paramsKeyAndValue[] = splitOnFirst(param, ':'); String params[] = contentValidationParams.split(",");
if (paramsKeyAndValue.length != 2) { for (String param : params) {
throw new InputEventAdapterException("Invalid parameters for content validation - " + param); String paramsKeyAndValue[] = splitOnFirst(param, ':');
if (paramsKeyAndValue.length != 2) {
throw new InputEventAdapterException("Invalid parameters for content validation - " + param);
}
paramsMap.put(paramsKeyAndValue[0], paramsKeyAndValue[1]);
} }
paramsMap.put(paramsKeyAndValue[0], paramsKeyAndValue[1]);
} }
int xmppPort = XMPPEventAdapterConstants.DEFAULT_XMPP_PORT; int xmppPort = XMPPEventAdapterConstants.DEFAULT_XMPP_PORT;
String xmppPortString = eventAdapterConfiguration.getProperties() String xmppPortString = eventAdapterConfiguration.getProperties()
.get(XMPPEventAdapterConstants.ADAPTER_CONF_PORT); .get(XMPPEventAdapterConstants.ADAPTER_CONF_PORT);
@ -91,11 +92,12 @@ public class XMPPEventAdapter implements InputEventAdapter {
.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME), .ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME),
paramsMap, paramsMap,
eventAdapterConfiguration.getProperties().get(XMPPEventAdapterConstants.ADAPTER_CONF_RECIEVER_JID), eventAdapterConfiguration.getProperties().get(XMPPEventAdapterConstants.ADAPTER_CONF_RECIEVER_JID),
eventAdapterConfiguration.getProperties().get(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME) eventAdapterConfiguration.getProperties().get(XMPPEventAdapterConstants
.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME)
); );
xmppAdapterListener = new XMPPAdapterListener(xmppServerConnectionConfiguration, xmppAdapterListener = new XMPPAdapterListener(xmppServerConnectionConfiguration,
eventAdapterListener, PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId()); eventAdapterListener, PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true));
} catch (Throwable t) { } catch (Throwable t) {
throw new InputEventAdapterException(t.getMessage(), t); throw new InputEventAdapterException(t.getMessage(), t);

View File

@ -89,7 +89,7 @@ public class XMPPEventAdapterFactory extends InputEventAdapterFactory {
//Resource //Resource
Property resource = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE); Property resource = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE);
resource.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE)); resource.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE));
resource.setRequired(true); resource.setRequired(false);
resource.setHint(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE_HINT)); resource.setHint(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE_HINT));
//Content Validator details //Content Validator details
@ -99,7 +99,7 @@ public class XMPPEventAdapterFactory extends InputEventAdapterFactory {
contentValidator.setRequired(false); contentValidator.setRequired(false);
contentValidator.setHint( contentValidator.setHint(
resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT)); resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT));
contentValidator.setDefaultValue(org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.Constants.DEFAULT); contentValidator.setDefaultValue(XMPPEventAdapterConstants.DEFAULT);
//Content Validator Params details //Content Validator Params details
Property contentValidatorParams = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS); Property contentValidatorParams = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS);
@ -108,7 +108,7 @@ public class XMPPEventAdapterFactory extends InputEventAdapterFactory {
contentValidatorParams.setRequired(false); contentValidatorParams.setRequired(false);
contentValidatorParams.setHint( contentValidatorParams.setHint(
resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS_HINT)); resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS_HINT));
contentValidatorParams.setDefaultValue(Constants.XMPP_CONTENT_VALIDATION_DEFAULT_PARAMETERS); contentValidatorParams.setDefaultValue(XMPPEventAdapterConstants.XMPP_CONTENT_VALIDATION_DEFAULT_PARAMETERS);
Property jid = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_RECIEVER_JID); Property jid = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_RECIEVER_JID);
jid.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_RECIEVER_JID)); jid.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_RECIEVER_JID));
@ -122,7 +122,7 @@ public class XMPPEventAdapterFactory extends InputEventAdapterFactory {
contentTransformer.setRequired(false); contentTransformer.setRequired(false);
contentTransformer.setHint( contentTransformer.setHint(
resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT)); resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT));
contentTransformer.setDefaultValue(Constants.DEFAULT); contentTransformer.setDefaultValue(XMPPEventAdapterConstants.DEFAULT);
propertyList.add(host); propertyList.add(host);
propertyList.add(port); propertyList.add(port);

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.internal;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.http.HttpService;
import org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.XMPPEventAdapterFactory;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterFactory;
import org.wso2.carbon.user.core.service.RealmService;
/**
* @scr.component name="input.iot.xmpp.AdapterService.component" immediate="true"
* @scr.reference name="user.realmservice.default"
* interface="org.wso2.carbon.user.core.service.RealmService" cardinality="1..1"
* policy="dynamic" bind="setRealmService" unbind="unsetRealmService"
*/
public class InputAdapterServiceComponent {
private static final Log log = LogFactory.getLog(InputAdapterServiceComponent.class);
protected void activate(ComponentContext context) {
try {
InputEventAdapterFactory xmppEventEventAdapterFactory = new XMPPEventAdapterFactory();
context.getBundleContext().registerService(InputEventAdapterFactory.class.getName(),
xmppEventEventAdapterFactory, null);
if (log.isDebugEnabled()) {
log.debug("Successfully deployed the input adapter service");
}
} catch (RuntimeException e) {
log.error("Can not create the input adapter service ", e);
}
}
protected void setRealmService(RealmService realmService) {
InputAdapterServiceDataHolder.registerRealmService(realmService);
}
protected void unsetRealmService(RealmService realmService) {
InputAdapterServiceDataHolder.registerRealmService(null);
}
protected void setHttpService(HttpService httpService) {
InputAdapterServiceDataHolder.registerHTTPService(httpService);
}
protected void unsetHttpService(HttpService httpService) {
InputAdapterServiceDataHolder.registerHTTPService(null);
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.internal;
import org.osgi.service.http.HttpService;
import org.wso2.carbon.user.core.service.RealmService;
/**
* common place to hold some OSGI service references.
*/
public final class InputAdapterServiceDataHolder {
private static RealmService realmService;
private static HttpService httpService;
private InputAdapterServiceDataHolder() {
}
public static void registerRealmService(
RealmService realmService) {
InputAdapterServiceDataHolder.realmService = realmService;
}
public static RealmService getRealmService() {
return realmService;
}
public static void registerHTTPService(
HttpService httpService) {
InputAdapterServiceDataHolder.httpService = httpService;
}
public static HttpService getHTTPService() {
return httpService;
}
}

View File

@ -32,12 +32,11 @@ import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Packet;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.ServerStatus; 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.extension.ContentInfo;
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentTransformer; import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentTransformer;
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentValidator; import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentValidator;
import org.wso2.carbon.device.mgt.iot.input.adapter.DefaultContentTransformer; import org.wso2.carbon.device.mgt.iot.input.adapter.extension.DefaultContentTransformer;
import org.wso2.carbon.device.mgt.iot.input.adapter.DefaultContentValidator; import org.wso2.carbon.device.mgt.iot.input.adapter.extension.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.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.InputEventAdapterListener;
import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterRuntimeException; import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterRuntimeException;
@ -54,7 +53,6 @@ public class XMPPAdapterListener implements Runnable {
private ContentValidator contentValidator; private ContentValidator contentValidator;
private Map<String, String> contentValidationParams; private Map<String, String> contentValidationParams;
private ContentTransformer contentTransformer; private ContentTransformer contentTransformer;
private PacketFilter packetFilter;
private PacketListener packetListener; private PacketListener packetListener;
private InputEventAdapterListener eventAdapterListener = null; private InputEventAdapterListener eventAdapterListener = null;
@ -68,7 +66,7 @@ public class XMPPAdapterListener implements Runnable {
try { try {
String contentValidatorClassName = this.xmppServerConnectionConfiguration.getContentValidatorClassName(); String contentValidatorClassName = this.xmppServerConnectionConfiguration.getContentValidatorClassName();
if (contentValidatorClassName != null && contentValidatorClassName.equals(Constants.DEFAULT)) { if (contentValidatorClassName != null && contentValidatorClassName.equals(XMPPEventAdapterConstants.DEFAULT)) {
contentValidator = new DefaultContentValidator(); contentValidator = new DefaultContentValidator();
} else if (contentValidatorClassName != null && !contentValidatorClassName.isEmpty()) { } else if (contentValidatorClassName != null && !contentValidatorClassName.isEmpty()) {
try { try {
@ -88,7 +86,7 @@ public class XMPPAdapterListener implements Runnable {
contentValidationParams = xmppServerConnectionConfiguration.getContentValidatorParams(); contentValidationParams = xmppServerConnectionConfiguration.getContentValidatorParams();
String contentTransformerClassName = this.xmppServerConnectionConfiguration.getContentTransformerClassName(); String contentTransformerClassName = this.xmppServerConnectionConfiguration.getContentTransformerClassName();
if (contentTransformerClassName != null && contentTransformerClassName.equals(Constants.DEFAULT)) { if (contentTransformerClassName != null && contentTransformerClassName.equals(XMPPEventAdapterConstants.DEFAULT)) {
contentTransformer = new DefaultContentTransformer(); contentTransformer = new DefaultContentTransformer();
} else if (contentTransformerClassName != null && !contentTransformerClassName.isEmpty()) { } else if (contentTransformerClassName != null && !contentTransformerClassName.isEmpty()) {
try { try {
@ -151,7 +149,7 @@ public class XMPPAdapterListener implements Runnable {
} }
protected void setFilterOnReceiver(String receiverJID) { protected void setFilterOnReceiver(String receiverJID) {
packetFilter = new AndFilter(new PacketTypeFilter(Message.class), new ToContainsFilter( PacketFilter packetFilter = new AndFilter(new PacketTypeFilter(Message.class), new ToContainsFilter(
receiverJID)); receiverJID));
packetListener = new PacketListener() { packetListener = new PacketListener() {
@Override @Override
@ -187,12 +185,12 @@ public class XMPPAdapterListener implements Runnable {
if (contentValidator != null && contentTransformer != null) { if (contentValidator != null && contentTransformer != null) {
Map<String, String> dynamicParmaters = new HashMap<>(); Map<String, String> dynamicParmaters = new HashMap<>();
dynamicParmaters.put(Constants.FROM_KEY, from); dynamicParmaters.put(XMPPEventAdapterConstants.FROM_KEY, from);
dynamicParmaters.put(Constants.SUBJECT_KEY, subject); dynamicParmaters.put(XMPPEventAdapterConstants.SUBJECT_KEY, subject);
message = contentTransformer.transform(message, dynamicParmaters); message = (String) contentTransformer.transform(message, dynamicParmaters);
ContentInfo contentInfo = contentValidator.validate(message, contentValidationParams, dynamicParmaters); ContentInfo contentInfo = contentValidator.validate(message, contentValidationParams, dynamicParmaters);
if (contentInfo != null && contentInfo.isValidContent()) { if (contentInfo != null && contentInfo.isValidContent()) {
eventAdapterListener.onEvent(contentInfo.getMsgText()); eventAdapterListener.onEvent(contentInfo.getMessage());
} }
} else { } else {
eventAdapterListener.onEvent(message); eventAdapterListener.onEvent(message);

View File

@ -51,4 +51,10 @@ public class XMPPEventAdapterConstants {
public static int initialReconnectDuration = 10000; public static int initialReconnectDuration = 10000;
public static final int reconnectionProgressionFactor = 2; public static final int reconnectionProgressionFactor = 2;
public static final String DEFAULT = "default";
public static final String XMPP_CONTENT_VALIDATION_DEFAULT_PARAMETERS = "";
public static final String FROM_KEY = "from";
public static final String SUBJECT_KEY = "subject";
} }

View File

@ -17,9 +17,6 @@
*/ */
package org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.util; 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; import java.util.Map;
/** /**

View File

@ -1,8 +0,0 @@
package org.wso2.carbon.device.mgt.iot.input.adapter;
import java.util.Map;
public interface ContentTransformer {
String transform(String message, Map<String, String> dynamicProperties);
}

View File

@ -1,11 +0,0 @@
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<String, String> params, Map<String, String> dynamicPaarams) {
return new ContentInfo(true, msgPayload);
}
}

View File

@ -1,38 +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.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";
}

View File

@ -1,32 +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.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";
}

View File

@ -28,7 +28,7 @@
<packaging>bundle</packaging> <packaging>bundle</packaging>
<name>WSO2 Carbon - Device Mgt Output MQTT Adaptor Module</name> <name>WSO2 Carbon - Device Mgt Output MQTT Adaptor Module</name>
<description>org.wso2.carbon.device.mgt.iot.output.adapter.xmpp provides the back-end functionality of mqtt adaptor <description>org.wso2.carbon.device.mgt.iot.output.adapter.mqtt provides the back-end functionality of mqtt adaptor
</description> </description>
<url>http://wso2.org</url> <url>http://wso2.org</url>
@ -94,13 +94,13 @@
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name> <Bundle-Name>${project.artifactId}</Bundle-Name>
<Private-Package> <Private-Package>
org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.internal, org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.internal,
org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.internal.* org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.internal.*
</Private-Package> </Private-Package>
<Export-Package> <Export-Package>
!org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.internal, !org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.internal,
!org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.internal.*, !org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.internal.*,
org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.*, org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.*,
</Export-Package> </Export-Package>
<Import-Package> <Import-Package>
org.wso2.carbon.event.output.adapter.core, org.wso2.carbon.event.output.adapter.core,

View File

@ -15,14 +15,14 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n; package org.wso2.carbon.device.mgt.iot.output.adapter.mqtt;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.util.MQTTEventAdapterConstants; import org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.util.MQTTAdapterPublisher;
import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.util.MQTTAdapterPublisher; import org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.util.MQTTEventAdapterConstants;
import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.util.MQTTBrokerConnectionConfiguration; import org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.util.MQTTBrokerConnectionConfiguration;
import org.wso2.carbon.event.output.adapter.core.EventAdapterUtil; import org.wso2.carbon.event.output.adapter.core.EventAdapterUtil;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapter; 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.OutputEventAdapterConfiguration;
@ -68,7 +68,7 @@ public class MQTTEventAdapter implements OutputEventAdapter {
@Override @Override
public void init() throws OutputEventAdapterException { public void init() throws OutputEventAdapterException {
tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
//ThreadPoolExecutor will be assigned if it is null //ThreadPoolExecutor will be assigned if it is null
if (threadPoolExecutor == null) { if (threadPoolExecutor == null) {
int minThread; int minThread;
@ -191,7 +191,7 @@ public class MQTTEventAdapter implements OutputEventAdapter {
} }
} }
} }
if (qos == null) { if (qos == null || qos.trim().isEmpty()) {
mqttAdapterPublisher.publish(message.toString(), topic); mqttAdapterPublisher.publish(message.toString(), topic);
} else { } else {
mqttAdapterPublisher.publish(Integer.parseInt(qos), message.toString(), topic); mqttAdapterPublisher.publish(Integer.parseInt(qos), message.toString(), topic);

View File

@ -15,9 +15,9 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n; package org.wso2.carbon.device.mgt.iot.output.adapter.mqtt;
import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.util.MQTTEventAdapterConstants; import org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.util.MQTTEventAdapterConstants;
import org.wso2.carbon.event.output.adapter.core.*; import org.wso2.carbon.event.output.adapter.core.*;
import java.util.*; import java.util.*;

View File

@ -15,12 +15,12 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.internal; package org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.internal;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.osgi.service.component.ComponentContext; import org.osgi.service.component.ComponentContext;
import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.MQTTEventAdapterFactory; import org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.MQTTEventAdapterFactory;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterFactory; import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterFactory;

View File

@ -15,7 +15,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.util; package org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.util;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -81,7 +81,7 @@ public class MQTTAdapterPublisher {
connectionOptions.setUserName(getToken(mqttBrokerConnectionConfiguration.getBrokerUsername(), connectionOptions.setUserName(getToken(mqttBrokerConnectionConfiguration.getBrokerUsername(),
mqttBrokerConnectionConfiguration.getDcrUrl(), mqttBrokerConnectionConfiguration.getDcrUrl(),
mqttBrokerConnectionConfiguration.getScopes())); mqttBrokerConnectionConfiguration.getScopes()));
connectionOptions.setPassword(Constants.DEFAULT_PASSWORD.toCharArray()); connectionOptions.setPassword(MQTTEventAdapterConstants.DEFAULT_PASSWORD.toCharArray());
} }
// Construct an MQTT blocking mode client // Construct an MQTT blocking mode client
mqttClient = new MqttClient(mqttBrokerConnectionConfiguration.getBrokerUrl(), clientId, dataStore); mqttClient = new MqttClient(mqttBrokerConnectionConfiguration.getBrokerUrl(), clientId, dataStore);
@ -142,19 +142,16 @@ public class MQTTAdapterPublisher {
private String getToken(String username, String dcrUrlString, String scopes) { private String getToken(String username, String dcrUrlString, String scopes) {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
if (dcrUrlString != null && !dcrUrlString.isEmpty()) { if (dcrUrlString != null && !dcrUrlString.isEmpty()) {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true);
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(username);
try { try {
URL dcrUrl = new URL(dcrUrlString); URL dcrUrl = new URL(dcrUrlString);
HttpClient httpClient = MQTTUtil.getHttpClient(dcrUrl.getProtocol()); HttpClient httpClient = MQTTUtil.getHttpClient(dcrUrl.getProtocol());
HttpPost postMethod = new HttpPost(dcrUrlString); HttpPost postMethod = new HttpPost(dcrUrlString);
RegistrationProfile registrationProfile = new RegistrationProfile(); RegistrationProfile registrationProfile = new RegistrationProfile();
registrationProfile.setCallbackUrl(Constants.DEFAULT_CALLBACK); registrationProfile.setCallbackUrl(MQTTEventAdapterConstants.DEFAULT_CALLBACK);
registrationProfile.setGrantType(Constants.GRANT_TYPE); registrationProfile.setGrantType(MQTTEventAdapterConstants.GRANT_TYPE);
registrationProfile.setOwner(username); registrationProfile.setOwner(username);
registrationProfile.setTokenScope(Constants.TOKEN_SCOPE); registrationProfile.setTokenScope(MQTTEventAdapterConstants.TOKEN_SCOPE);
registrationProfile.setApplicationType(Constants.APPLICATION_TYPE); registrationProfile.setApplicationType(MQTTEventAdapterConstants.APPLICATION_TYPE);
registrationProfile.setClientName(username + "_" + tenantId); registrationProfile.setClientName(username + "_" + tenantId);
String jsonString = registrationProfile.toJSON(); String jsonString = registrationProfile.toJSON();
StringEntity requestEntity = new StringEntity(jsonString, ContentType.APPLICATION_JSON); StringEntity requestEntity = new StringEntity(jsonString, ContentType.APPLICATION_JSON);
@ -164,8 +161,8 @@ public class MQTTAdapterPublisher {
try { try {
JSONParser jsonParser = new JSONParser(); JSONParser jsonParser = new JSONParser();
JSONObject jsonPayload = (JSONObject) jsonParser.parse(response); JSONObject jsonPayload = (JSONObject) jsonParser.parse(response);
String clientId = (String) jsonPayload.get(Constants.CLIENT_ID); String clientId = (String) jsonPayload.get(MQTTEventAdapterConstants.CLIENT_ID);
String clientSecret = (String) jsonPayload.get(Constants.CLIENT_SECRET); String clientSecret = (String) jsonPayload.get(MQTTEventAdapterConstants.CLIENT_SECRET);
JWTClientManagerService jwtClientManagerService = MQTTUtil.getJWTClientManagerService(); JWTClientManagerService jwtClientManagerService = MQTTUtil.getJWTClientManagerService();
AccessTokenInfo accessTokenInfo = jwtClientManagerService.getJWTClient().getAccessToken( AccessTokenInfo accessTokenInfo = jwtClientManagerService.getJWTClient().getAccessToken(
clientId, clientSecret, username, scopes); clientId, clientSecret, username, scopes);
@ -181,8 +178,6 @@ public class MQTTAdapterPublisher {
throw new OutputEventAdapterRuntimeException("Invalid dcrUrl : " + dcrUrlString); throw new OutputEventAdapterRuntimeException("Invalid dcrUrl : " + dcrUrlString);
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | IOException e) { } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | IOException e) {
throw new OutputEventAdapterRuntimeException("Failed to create an https connection.", e); throw new OutputEventAdapterRuntimeException("Failed to create an https connection.", e);
} finally {
PrivilegedCarbonContext.endTenantFlow();
} }
} }
throw new OutputEventAdapterRuntimeException("Invalid configuration for mqtt publisher"); throw new OutputEventAdapterRuntimeException("Invalid configuration for mqtt publisher");

View File

@ -15,7 +15,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.util; package org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.util;
public class MQTTBrokerConnectionConfiguration { public class MQTTBrokerConnectionConfiguration {

View File

@ -15,7 +15,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.util; package org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.util;
public final class MQTTEventAdapterConstants { public final class MQTTEventAdapterConstants {
@ -51,4 +51,11 @@ public final class MQTTEventAdapterConstants {
public static final String ADAPTER_KEEP_ALIVE_TIME_NAME = "keepAliveTimeInMillis"; 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 ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME = "jobQueueSize";
public static final String DEFAULT_CALLBACK = "";
public static final String DEFAULT_PASSWORD = "";
public static final String GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer refresh_token";
public static final String TOKEN_SCOPE = "production";
public static final String APPLICATION_TYPE = "device";
public static final String CLIENT_ID = "client_id";
public static final String CLIENT_SECRET = "client_secret";
} }

View File

@ -16,7 +16,7 @@
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.util; package org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.util;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;

View File

@ -1,4 +1,4 @@
package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.util; package org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.util;
/** /**
* This class represents the data that are required to register * This class represents the data that are required to register

View File

@ -1,32 +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.output.adapter.xmpp.i18n.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";
}

View File

@ -15,14 +15,14 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n; package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.util.XMPPEventAdapterConstants; import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.util.XMPPEventAdapterConstants;
import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.util.XMPPAdapterPublisher; import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.util.XMPPAdapterPublisher;
import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.util.XMPPServerConnectionConfiguration; 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.EventAdapterUtil;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapter; 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.OutputEventAdapterConfiguration;

View File

@ -15,9 +15,9 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n; package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp;
import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.util.XMPPEventAdapterConstants; import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.util.XMPPEventAdapterConstants;
import org.wso2.carbon.event.output.adapter.core.*; import org.wso2.carbon.event.output.adapter.core.*;
import java.util.*; import java.util.*;
@ -80,7 +80,7 @@ public class XMPPEventAdapterFactory extends OutputEventAdapterFactory {
//Resource //Resource
Property resource = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE); Property resource = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE);
resource.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE)); resource.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE));
resource.setRequired(true); resource.setRequired(false);
resource.setHint(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE_HINT)); resource.setHint(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_RESOURCE_HINT));
staticPropertyList.add(host); staticPropertyList.add(host);

View File

@ -15,12 +15,12 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.internal; package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.internal;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.osgi.service.component.ComponentContext; import org.osgi.service.component.ComponentContext;
import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.XMPPEventAdapterFactory; import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.XMPPEventAdapterFactory;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterFactory; import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterFactory;

View File

@ -15,7 +15,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.util; package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.util;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;

View File

@ -15,7 +15,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.util; package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.util;
public final class XMPPEventAdapterConstants { public final class XMPPEventAdapterConstants {

View File

@ -15,7 +15,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.util; package org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.util;
public class XMPPServerConnectionConfiguration { public class XMPPServerConnectionConfiguration {

View File

@ -37,7 +37,10 @@
<module>org.wso2.carbon.device.mgt.iot.ui</module> <module>org.wso2.carbon.device.mgt.iot.ui</module>
<module>org.wso2.carbon.device.mgt.iot.output.adapter.mqtt</module> <module>org.wso2.carbon.device.mgt.iot.output.adapter.mqtt</module>
<module>org.wso2.carbon.device.mgt.iot.output.adapter.xmpp</module> <module>org.wso2.carbon.device.mgt.iot.output.adapter.xmpp</module>
<module>org.wso2.carbon.device.mgt.iot.input.adapter</module> <module>org.wso2.carbon.device.mgt.iot.input.adapter.extension</module>
<module>org.wso2.carbon.device.mgt.iot.input.adapter.http</module>
<module>org.wso2.carbon.device.mgt.iot.input.adapter.mqtt</module>
<module>org.wso2.carbon.device.mgt.iot.input.adapter.xmpp</module>
</modules> </modules>
<build> <build>

View File

@ -26,13 +26,9 @@ import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException
import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.dto.SensorRecord; import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.dto.SensorRecord;
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.transport.RaspberryPiMQTTConnector;
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util.APIUtil; import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants; import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants;
import org.wso2.carbon.device.mgt.iot.service.IoTServerStartupListener;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.GET; import javax.ws.rs.GET;
@ -43,14 +39,13 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam; import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.concurrent.ConcurrentHashMap; import java.util.Map;
public class RaspberryPiControllerServiceImpl implements RaspberryPiControllerService { public class RaspberryPiControllerServiceImpl implements RaspberryPiControllerService {
private static Log log = LogFactory.getLog(RaspberryPiControllerServiceImpl.class); private static Log log = LogFactory.getLog(RaspberryPiControllerServiceImpl.class);
private ConcurrentHashMap<String, String> deviceToIpMap = new ConcurrentHashMap<>();
private RaspberryPiMQTTConnector raspberryPiMQTTConnector;
@Path("device/{deviceId}/bulb") @Path("device/{deviceId}/bulb")
@POST @POST
@ -66,12 +61,14 @@ public class RaspberryPiControllerServiceImpl implements RaspberryPiControllerSe
log.error("The requested state change shoud be either - 'ON' or 'OFF'"); log.error("The requested state change shoud be either - 'ON' or 'OFF'");
return Response.status(Response.Status.BAD_REQUEST.getStatusCode()).build(); return Response.status(Response.Status.BAD_REQUEST.getStatusCode()).build();
} }
String mqttResource = RaspberrypiConstants.BULB_CONTEXT.replace("/", ""); String actualMessage = RaspberrypiConstants.BULB_CONTEXT + ":" + state;
raspberryPiMQTTConnector.publishDeviceData(deviceId, mqttResource, switchToState); Map<String, String> dynamicProperties = new HashMap<>();
String publishTopic = APIUtil.getTenantDomainOftheUser() + "/"
+ RaspberrypiConstants.DEVICE_TYPE + "/" + deviceId;
dynamicProperties.put(RaspberrypiConstants.ADAPTER_TOPIC_PROPERTY, publishTopic);
APIUtil.getOutputEventAdapterService().publish(RaspberrypiConstants.MQTT_ADAPTER_NAME,
dynamicProperties, actualMessage);
return Response.ok().build(); return Response.ok().build();
} catch (TransportHandlerException e) {
log.error("Failed to send switch-bulb request to device [" + deviceId + "]");
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (DeviceAccessAuthorizationException e) { } catch (DeviceAccessAuthorizationException e) {
log.error(e.getErrorMessage(), e); log.error(e.getErrorMessage(), e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
@ -109,44 +106,4 @@ public class RaspberryPiControllerServiceImpl implements RaspberryPiControllerSe
} }
} }
private boolean waitForServerStartup() {
while (!IoTServerStartupListener.isServerReady()) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
return true;
}
}
return false;
}
public RaspberryPiMQTTConnector getRaspberryPiMQTTConnector() {
return raspberryPiMQTTConnector;
}
public void setRaspberryPiMQTTConnector(
final RaspberryPiMQTTConnector raspberryPiMQTTConnector) {
Runnable connector = new Runnable() {
public void run() {
if (waitForServerStartup()) {
return;
}
//The delay is added for the server to starts up.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
RaspberryPiControllerServiceImpl.this.raspberryPiMQTTConnector = raspberryPiMQTTConnector;
if (MqttConfig.getInstance().isEnabled()) {
raspberryPiMQTTConnector.connect();
} else {
log.warn("MQTT disabled in 'devicemgt-config.xml'. Hence, RaspberryPiMQTTConnector not started.");
}
}
};
Thread connectorThread = new Thread(connector);
connectorThread.start();
}
} }

View File

@ -1,189 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.transport;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.json.JSONObject;
import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey;
import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.exception.RaspberrypiException;
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
import org.wso2.carbon.device.mgt.iot.transport.mqtt.MQTTTransportHandler;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.user.api.UserStoreException;
import java.nio.charset.StandardCharsets;
import java.security.PublicKey;
import java.util.UUID;
public class RaspberryPiMQTTConnector extends MQTTTransportHandler {
private static Log log = LogFactory.getLog(RaspberryPiMQTTConnector.class);
// subscribeTopic is not used for the RaspberryPi sample since the DAS device directly publishes to DAS MQTT receiver
private static final String subscribeTopic = "wso2/+/"+ RaspberrypiConstants.DEVICE_TYPE + "/+/publisher";
private static final String KEY_TYPE = "PRODUCTION";
private static final String EMPTY_STRING = "";
private static final String iotServerSubscriber = UUID.randomUUID().toString().substring(0, 5);
private RaspberryPiMQTTConnector() {
super(iotServerSubscriber, RaspberrypiConstants.DEVICE_TYPE,
MqttConfig.getInstance().getMqttQueueEndpoint(), subscribeTopic);
}
@Override
public void connect() {
Runnable connector = new Runnable() {
public void run() {
while (!isConnected()) {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
RaspberrypiConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true);
try {
String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
.getRealmConfiguration().getAdminUserName();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(applicationUsername);
APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
String[] tags = {RaspberrypiConstants.DEVICE_TYPE};
ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
RaspberrypiConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true);
JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
String scopes = "device_type_" + RaspberrypiConstants.DEVICE_TYPE + " device_mqtt_connector";
AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
apiApplicationKey.getConsumerSecret(), applicationUsername, scopes);
//create token
String accessToken = accessTokenInfo.getAccessToken();
setUsernameAndPassword(accessToken, EMPTY_STRING);
connectToQueue();
} catch (TransportHandlerException e) {
log.error("Connection/Subscription to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e);
try {
Thread.sleep(timeoutInterval);
} catch (InterruptedException ex) {
log.error("MQTT-Connector: Thread Sleep Interrupt Exception.", ex);
}
} catch (JWTClientException e) {
log.error("Failed to retrieve token from JWT Client.", e);
return;
} catch (UserStoreException e) {
log.error("Failed to retrieve the user.", e);
return;
} catch (APIManagerException e) {
log.error("Failed to create an application and generate keys.", e);
return;
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
}
};
Thread connectorThread = new Thread(connector);
connectorThread.start();
}
@Override
public void publishDeviceData(String... publishData) throws TransportHandlerException {
if (publishData.length != 3) {
String errorMsg = "Incorrect number of arguments received to SEND-MQTT Message. " +
"Need to be [owner, deviceId, resource{BULB/TEMP}, state{ON/OFF or null}]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg);
}
String deviceId = publishData[0];
String resource = publishData[1];
String state = publishData[2];
MqttMessage pushMessage = new MqttMessage();
String publishTopic = "wso2/" + APIUtil.getTenantDomainOftheUser() + "/"
+ RaspberrypiConstants.DEVICE_TYPE + "/" + deviceId;
String actualMessage = resource + ":" + state;
pushMessage.setPayload(actualMessage.getBytes(StandardCharsets.UTF_8));
pushMessage.setQos(DEFAULT_MQTT_QUALITY_OF_SERVICE);
pushMessage.setRetained(false);
publishToQueue(publishTopic, pushMessage);
}
@Override
public void disconnect() {
Runnable stopConnection = new Runnable() {
public void run() {
while (isConnected()) {
try {
closeConnection();
} catch (MqttException e) {
if (log.isDebugEnabled()) {
log.warn("Unable to 'STOP' MQTT connection at broker at: " + mqttBrokerEndPoint
+ " for device-type - " + RaspberrypiConstants.DEVICE_TYPE, e);
}
try {
Thread.sleep(timeoutInterval);
} catch (InterruptedException e1) {
log.error("MQTT-Terminator: Thread Sleep Interrupt Exception at device-type - " +
RaspberrypiConstants.DEVICE_TYPE, e1);
}
}
}
}
};
Thread terminatorThread = new Thread(stopConnection);
terminatorThread.start();
}
@Override
public void processIncomingMessage(MqttMessage mqttMessage, String... messageParams) throws TransportHandlerException {
}
@Override
public void processIncomingMessage() throws TransportHandlerException {
}
@Override
public void processIncomingMessage(MqttMessage message) throws TransportHandlerException {
}
@Override
public void publishDeviceData() throws TransportHandlerException {
}
@Override
public void publishDeviceData(MqttMessage publishData) throws TransportHandlerException {
}
}

View File

@ -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.common.authorization.DeviceAccessAuthorizationService;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.dto.SensorRecord; import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.dto.SensorRecord;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
import java.util.ArrayList; import java.util.ArrayList;
@ -168,5 +169,16 @@ public class APIUtil {
return deviceAccessAuthorizationService; 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;
}
} }

View File

@ -71,7 +71,13 @@
org.wso2.carbon.device.mgt.common, org.wso2.carbon.device.mgt.common,
org.wso2.carbon.device.mgt.iot.*, org.wso2.carbon.device.mgt.iot.*,
org.wso2.carbon.device.mgt.extensions.feature.mgt.*, org.wso2.carbon.device.mgt.extensions.feature.mgt.*,
org.wso2.carbon.utils.* org.wso2.carbon.utils.*,
org.wso2.carbon.base,
org.wso2.carbon.context,
org.wso2.carbon.core,
org.wso2.carbon.core.util,
org.wso2.carbon.event.output.adapter.core,
org.wso2.carbon.event.output.adapter.core.exception
</Import-Package> </Import-Package>
<Export-Package> <Export-Package>
!org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.internal, !org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.internal,
@ -112,5 +118,13 @@
<groupId>org.wso2.carbon</groupId> <groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.utils</artifactId> <artifactId>org.wso2.carbon.utils</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.output.adapter.core</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.input.adapter.core</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -27,7 +27,7 @@ public class RaspberrypiConstants {
public final static String STATE_OFF = "OFF"; public final static String STATE_OFF = "OFF";
public static final String URL_PREFIX = "http://"; public static final String URL_PREFIX = "http://";
public static final String BULB_CONTEXT = "/BULB/"; public static final String BULB_CONTEXT = "BULB";
public static final String TEMPERATURE_CONTEXT = "/TEMPERATURE/"; public static final String TEMPERATURE_CONTEXT = "/TEMPERATURE/";
//type of the sensor //type of the sensor
@ -37,4 +37,24 @@ public class RaspberrypiConstants {
public static final String DATA_SOURCE_NAME = "jdbc/RaspberryPiDM_DB"; public static final String DATA_SOURCE_NAME = "jdbc/RaspberryPiDM_DB";
public final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super"; public final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super";
//mqtt tranport related constants
public static final String MQTT_ADAPTER_NAME = "raspberrypi_mqtt";
public static final String MQTT_ADAPTER_TYPE = "oauth-mqtt";
public static final String ADAPTER_TOPIC_PROPERTY = "topic";
public static final String MQTT_PORT = "\\$\\{mqtt.broker.port\\}";
public static final String MQTT_BROKER_HOST = "\\$\\{mqtt.broker.host\\}";
public static final String CARBON_CONFIG_PORT_OFFSET = "Ports.Offset";
public static final String DEFAULT_CARBON_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";
public static final String TOPIC = "topic";
} }

View File

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

View File

@ -20,20 +20,33 @@ package org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl.util;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.util.Utils;
import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants; import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants;
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.exception.RaspberrypiDeviceMgtPluginException; import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.exception.RaspberrypiDeviceMgtPluginException;
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.internal.RaspberrypiManagementDataHolder;
import org.wso2.carbon.event.output.adapter.core.MessageType;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration;
import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException;
import org.wso2.carbon.utils.CarbonUtils;
import javax.naming.Context; import javax.naming.Context;
import javax.naming.InitialContext; import javax.naming.InitialContext;
import javax.naming.NamingException; import javax.naming.NamingException;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties;
/** /**
* Contains utility methods used by Raspberrypi plugin. * Contains utility methods used by Raspberrypi plugin.
@ -42,25 +55,9 @@ public class RaspberrypiUtils {
private static Log log = LogFactory.getLog(RaspberrypiUtils.class); private static Log log = LogFactory.getLog(RaspberrypiUtils.class);
public static String getDeviceProperty(List<Device.Property> deviceProperties, String propertyKey) { private static final String VIRTUAL_FIREALARM_CONFIG_LOCATION =
String deviceProperty = ""; CarbonUtils.getCarbonHome() + File.separator + "repository" + File.separator + "conf" +
for(Device.Property property :deviceProperties){ File.separator + "iot" + File.separator + "mqtt.properties";
if(propertyKey.equals(property.getName())){
deviceProperty = property.getValue();
}
}
return deviceProperty;
}
public static Device.Property getProperty(String property, String value) {
if (property != null) {
Device.Property prop = new Device.Property();
prop.setName(property);
prop.setValue(value);
return prop;
}
return null;
}
public static void cleanupResources(Connection conn, PreparedStatement stmt, ResultSet rs) { public static void cleanupResources(Connection conn, PreparedStatement stmt, ResultSet rs) {
if (rs != null) { if (rs != null) {
@ -108,4 +105,85 @@ public class RaspberrypiUtils {
"Management database schema", e); "Management database schema", e);
} }
} }
public static void setupMqttOutputAdapter() throws IOException {
OutputEventAdapterConfiguration outputEventAdapterConfiguration =
createMqttOutputEventAdapterConfiguration(RaspberrypiConstants.MQTT_ADAPTER_NAME,
RaspberrypiConstants.MQTT_ADAPTER_TYPE, MessageType.TEXT);
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
RaspberrypiConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true);
RaspberrypiManagementDataHolder.getInstance().getOutputEventAdapterService()
.create(outputEventAdapterConfiguration);
} catch (OutputEventAdapterException e) {
log.error("Unable to create Output Event Adapter : " + RaspberrypiConstants.MQTT_ADAPTER_NAME, e);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
/**
* Create Output Event Adapter Configuration for given configuration.
*
* @param name Output Event Adapter name
* @param type Output Event Adapter type
* @param msgFormat Output Event Adapter message format
* @return OutputEventAdapterConfiguration instance for given configuration
*/
private static OutputEventAdapterConfiguration createMqttOutputEventAdapterConfiguration(String name, String type,
String msgFormat) throws IOException {
OutputEventAdapterConfiguration outputEventAdapterConfiguration = new OutputEventAdapterConfiguration();
outputEventAdapterConfiguration.setName(name);
outputEventAdapterConfiguration.setType(type);
outputEventAdapterConfiguration.setMessageFormat(msgFormat);
File configFile = new File(VIRTUAL_FIREALARM_CONFIG_LOCATION);
if (configFile.exists()) {
Map<String, String> mqttAdapterProperties = new HashMap<>();
InputStream propertyStream = configFile.toURI().toURL().openStream();
Properties properties = new Properties();
properties.load(propertyStream);
mqttAdapterProperties.put(RaspberrypiConstants.USERNAME_PROPERTY_KEY, properties.getProperty(
RaspberrypiConstants.USERNAME_PROPERTY_KEY));
mqttAdapterProperties.put(RaspberrypiConstants.DCR_PROPERTY_KEY, Utils.replaceSystemProperty(
properties.getProperty(RaspberrypiConstants.DCR_PROPERTY_KEY)));
mqttAdapterProperties.put(RaspberrypiConstants.BROKER_URL_PROPERTY_KEY, replaceMqttProperty(
properties.getProperty(RaspberrypiConstants.BROKER_URL_PROPERTY_KEY)));
mqttAdapterProperties.put(RaspberrypiConstants.SCOPES_PROPERTY_KEY, properties.getProperty(
RaspberrypiConstants.SCOPES_PROPERTY_KEY));
mqttAdapterProperties.put(RaspberrypiConstants.CLEAR_SESSION_PROPERTY_KEY, properties.getProperty(
RaspberrypiConstants.CLEAR_SESSION_PROPERTY_KEY));
mqttAdapterProperties.put(RaspberrypiConstants.QOS_PROPERTY_KEY, properties.getProperty(
RaspberrypiConstants.QOS_PROPERTY_KEY));
mqttAdapterProperties.put(RaspberrypiConstants.CLIENT_ID_PROPERTY_KEY, "");
outputEventAdapterConfiguration.setStaticProperties(mqttAdapterProperties);
}
return outputEventAdapterConfiguration;
}
private static String replaceMqttProperty(String urlWithPlaceholders) {
urlWithPlaceholders = Utils.replaceSystemProperty(urlWithPlaceholders);
urlWithPlaceholders = urlWithPlaceholders.replaceAll(RaspberrypiConstants.MQTT_PORT, "" +
(RaspberrypiConstants.DEFAULT_MQTT_PORT + getPortOffset()));
urlWithPlaceholders = urlWithPlaceholders.replaceAll(RaspberrypiConstants.MQTT_BROKER_HOST,
System.getProperty(RaspberrypiConstants.DEFAULT_CARBON_SERVER_HOST_PROPERTY, "localhost"));
return urlWithPlaceholders;
}
private static int getPortOffset() {
ServerConfiguration carbonConfig = ServerConfiguration.getInstance();
String portOffset = System.getProperty("portOffset", carbonConfig.getFirstProperty(
RaspberrypiConstants.CARBON_CONFIG_PORT_OFFSET));
try {
if ((portOffset != null)) {
return Integer.parseInt(portOffset.trim());
} else {
return RaspberrypiConstants.CARBON_DEFAULT_PORT_OFFSET;
}
} catch (NumberFormatException e) {
return RaspberrypiConstants.CARBON_DEFAULT_PORT_OFFSET;
}
}
} }

View File

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

View File

@ -23,14 +23,23 @@ import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration; import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext; 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.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.exception.RaspberrypiDeviceMgtPluginException; import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.exception.RaspberrypiDeviceMgtPluginException;
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl.RaspberrypiManagerService; import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl.RaspberrypiManagerService;
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl.util.RaspberrypiStartupListener;
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl.util.RaspberrypiUtils; import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl.util.RaspberrypiUtils;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
/** /**
* @scr.component name="org.wso2.carbon.device.mgt.iot.raspberrypi.internal.RaspberrypiManagementServiceComponent" * @scr.component name="org.wso2.carbon.device.mgt.iot.raspberrypi.internal.RaspberrypiManagementServiceComponent"
* immediate="true" * immediate="true"
* @scr.reference name="event.output.adapter.service"
* interface="org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService"
* cardinality="1..1"
* policy="dynamic"
* bind="setOutputEventAdapterService"
* unbind="unsetOutputEventAdapterService"
*/ */
public class RaspberrypiManagementServiceComponent { public class RaspberrypiManagementServiceComponent {
@ -46,6 +55,8 @@ public class RaspberrypiManagementServiceComponent {
raspberrypiServiceRegRef = raspberrypiServiceRegRef =
bundleContext.registerService(DeviceManagementService.class.getName(), bundleContext.registerService(DeviceManagementService.class.getName(),
new RaspberrypiManagerService(), null); new RaspberrypiManagerService(), null);
bundleContext.registerService(ServerStartupObserver.class.getName(), new RaspberrypiStartupListener(),
null);
String setupOption = System.getProperty("setup"); String setupOption = System.getProperty("setup");
if (setupOption != null) { if (setupOption != null) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
@ -82,4 +93,20 @@ public class RaspberrypiManagementServiceComponent {
log.error("Error occurred while de-activating Raspberrypi Device Management bundle", e); log.error("Error occurred while de-activating Raspberrypi Device Management bundle", e);
} }
} }
/**
* Initialize the Output EventAdapter Service dependency
*
* @param outputEventAdapterService Output EventAdapter Service reference
*/
protected void setOutputEventAdapterService(OutputEventAdapterService outputEventAdapterService) {
RaspberrypiManagementDataHolder.getInstance().setOutputEventAdapterService(outputEventAdapterService);
}
/**
* De-reference the Output EventAdapter Service dependency.
*/
protected void unsetOutputEventAdapterService(OutputEventAdapterService outputEventAdapterService) {
RaspberrypiManagementDataHolder.getInstance().setOutputEventAdapterService(null);
}
} }

View File

@ -196,7 +196,7 @@ public class FireAlarmXMPPCommunicator extends XMPPTransportHandler {
String payLoad = AgentUtilOperations.prepareSecurePayLoad(message); String payLoad = AgentUtilOperations.prepareSecurePayLoad(message);
xmppMessage.setTo(xmppAdminJID); xmppMessage.setTo(xmppAdminJID);
xmppMessage.setSubject("PUBLISHER"); xmppMessage.setSubject(agentManager.getAgentConfigs().getTenantDomain());
xmppMessage.setBody(payLoad); xmppMessage.setBody(payLoad);
xmppMessage.setType(Message.Type.chat); xmppMessage.setType(Message.Type.chat);

View File

@ -57,8 +57,8 @@ public class AgentConstants {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
public static final int DEFAULT_MQTT_RECONNECTION_INTERVAL = 2; // time in seconds public static final int DEFAULT_MQTT_RECONNECTION_INTERVAL = 2; // time in seconds
public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0; public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0;
public static final String MQTT_SUBSCRIBE_TOPIC = "wso2/%s/" + DEVICE_TYPE + "/%s"; public static final String MQTT_SUBSCRIBE_TOPIC = "%s/" + DEVICE_TYPE + "/%s";
public static final String MQTT_PUBLISH_TOPIC = "wso2/%s/" + DEVICE_TYPE + "/%s/publisher"; public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/publisher";
/* --------------------------------------------------------------------------------------- /* ---------------------------------------------------------------------------------------
XMPP Connection specific information XMPP Connection specific information
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */

View File

@ -196,7 +196,7 @@ public class FireAlarmXMPPCommunicator extends XMPPTransportHandler {
String payLoad = AgentUtilOperations.prepareSecurePayLoad(message); String payLoad = AgentUtilOperations.prepareSecurePayLoad(message);
xmppMessage.setTo(xmppAdminJID); xmppMessage.setTo(xmppAdminJID);
xmppMessage.setSubject("PUBLISHER"); xmppMessage.setSubject(agentManager.getAgentConfigs().getTenantDomain());
xmppMessage.setBody(payLoad); xmppMessage.setBody(payLoad);
xmppMessage.setType(Message.Type.chat); xmppMessage.setType(Message.Type.chat);

View File

@ -56,8 +56,8 @@ public class AgentConstants {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
public static final int DEFAULT_MQTT_RECONNECTION_INTERVAL = 2; // time in seconds public static final int DEFAULT_MQTT_RECONNECTION_INTERVAL = 2; // time in seconds
public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0; public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0;
public static final String MQTT_SUBSCRIBE_TOPIC = "wso2/%s/" + DEVICE_TYPE + "/%s"; public static final String MQTT_SUBSCRIBE_TOPIC = "%s/" + DEVICE_TYPE + "/%s";
public static final String MQTT_PUBLISH_TOPIC = "wso2/%s/" + DEVICE_TYPE + "/%s/publisher"; public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/publisher";
/* --------------------------------------------------------------------------------------- /* ---------------------------------------------------------------------------------------
XMPP Connection specific information XMPP Connection specific information
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */

View File

@ -22,12 +22,8 @@ import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission; import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.DeviceType; import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.DeviceType;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.Feature; import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.Feature;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.DeviceData;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*; import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
/** /**

View File

@ -23,26 +23,16 @@ import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.analytics.dataservice.commons.SORT; import org.wso2.carbon.analytics.dataservice.commons.SORT;
import org.wso2.carbon.analytics.dataservice.commons.SortByField; import org.wso2.carbon.analytics.dataservice.commons.SortByField;
import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException; import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig;
import org.wso2.carbon.device.mgt.iot.service.IoTServerStartupListener;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.DeviceData; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util.VirtualFirealarmSecurityManager;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.SensorRecord; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.SensorRecord;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException; 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; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.SecurityManager;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.VirtualFireAlarmServiceUtils; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.VirtualFireAlarmServiceUtils;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam; import javax.ws.rs.FormParam;
import javax.ws.rs.GET; import javax.ws.rs.GET;
@ -52,31 +42,17 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam; import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@SuppressWarnings("Non-Annoted WebService")
public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmControllerService { public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmControllerService {
private static final String XMPP_PROTOCOL = "XMPP"; private static final String XMPP_PROTOCOL = "XMPP";
private static final String HTTP_PROTOCOL = "HTTP";
private static final String MQTT_PROTOCOL = "MQTT";
private static Log log = LogFactory.getLog(VirtualFireAlarmControllerServiceImpl.class); private static Log log = LogFactory.getLog(VirtualFireAlarmControllerServiceImpl.class);
// consists of utility methods related to encrypting and decrypting messages
private org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.SecurityManager securityManager;
// connects to the given MQTT broker and handles MQTT communication
private VirtualFireAlarmMQTTConnector virtualFireAlarmMQTTConnector;
// connects to the given XMPP server and handles XMPP communication
private VirtualFireAlarmXMPPConnector virtualFireAlarmXMPPConnector;
@POST @POST
@Path("device/{deviceId}/buzz") @Path("device/{deviceId}/buzz")
@ -89,7 +65,6 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
return Response.status(Response.Status.BAD_REQUEST).build(); return Response.status(Response.Status.BAD_REQUEST).build();
} }
String protocolString = protocol.toUpperCase(); String protocolString = protocol.toUpperCase();
String callUrlPattern = VirtualFireAlarmConstants.BULB_CONTEXT + switchToState;
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Sending request to switch-bulb of device [" + deviceId + "] via " + log.debug("Sending request to switch-bulb of device [" + deviceId + "] via " +
protocolString); protocolString);
@ -100,29 +75,31 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
DeviceGroupConstants.Permissions.DEFAULT_OPERATOR_PERMISSIONS)) { DeviceGroupConstants.Permissions.DEFAULT_OPERATOR_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
} }
String resource = VirtualFireAlarmConstants.BULB_CONTEXT.replace("/", "");
PrivateKey serverPrivateKey = VirtualFirealarmSecurityManager.getServerPrivateKey();
String actualMessage = resource + ":" + switchToState;
String encryptedMsg = VirtualFireAlarmServiceUtils.prepareSecurePayLoad(actualMessage,
serverPrivateKey);
Map<String, String> dynamicProperties = new HashMap<>();
switch (protocolString) { switch (protocolString) {
case XMPP_PROTOCOL: case XMPP_PROTOCOL:
String xmppResource = VirtualFireAlarmConstants.BULB_CONTEXT.replace("/", ""); dynamicProperties.put(VirtualFireAlarmConstants.JID_PROPERTY_KEY, deviceId);
virtualFireAlarmXMPPConnector.publishDeviceData(deviceId, xmppResource, switchToState); dynamicProperties.put(VirtualFireAlarmConstants.SUBJECT_PROPERTY_KEY, "CONTROL-REQUEST");
dynamicProperties.put(VirtualFireAlarmConstants.MESSAGE_TYPE_PROPERTY_KEY,
VirtualFireAlarmConstants.CHAT_PROPERTY_KEY);
APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.XMPP_ADAPTER_NAME,
dynamicProperties, encryptedMsg);
break; break;
default: default:
String mqttResource = VirtualFireAlarmConstants.BULB_CONTEXT.replace("/", "");
String publishTopic = "wso2/" + APIUtil.getTenantDomainOftheUser() + "/" String publishTopic = APIUtil.getTenantDomainOftheUser() + "/"
+ VirtualFireAlarmConstants.DEVICE_TYPE + "/" + deviceId; + VirtualFireAlarmConstants.DEVICE_TYPE + "/" + deviceId;
PrivateKey serverPrivateKey = SecurityManager.getServerPrivateKey();
String actualMessage = mqttResource + ":" + state.toUpperCase();
String encryptedMsg = VirtualFireAlarmServiceUtils.prepareSecurePayLoad(actualMessage,
serverPrivateKey);
Map<String, String> dynamicProperties = new HashMap<>();
dynamicProperties.put(VirtualFireAlarmConstants.ADAPTER_TOPIC_PROPERTY, publishTopic); dynamicProperties.put(VirtualFireAlarmConstants.ADAPTER_TOPIC_PROPERTY, publishTopic);
APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.ADAPTER_NAME, APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.MQTT_ADAPTER_NAME,
dynamicProperties, encryptedMsg); dynamicProperties, encryptedMsg);
break; break;
} }
return Response.ok().build(); return Response.ok().build();
} 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) { } catch (DeviceAccessAuthorizationException e) {
log.error(e.getErrorMessage(), e); log.error(e.getErrorMessage(), e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
@ -139,8 +116,7 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
@FormParam("policy") String policy) { @FormParam("policy") String policy) {
String protocolString = protocol.toUpperCase(); String protocolString = protocol.toUpperCase();
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Sending request to update-policy of device [" + deviceId + "] via " + log.debug("Sending request to update-policy of device [" + deviceId + "] via " + protocolString);
protocolString);
} }
try { try {
if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized( if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(
@ -148,23 +124,36 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
DeviceGroupConstants.Permissions.DEFAULT_MANAGE_POLICIES_PERMISSIONS)) { DeviceGroupConstants.Permissions.DEFAULT_MANAGE_POLICIES_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
} }
PrivateKey serverPrivateKey = VirtualFirealarmSecurityManager.getServerPrivateKey();
String actualMessage = VirtualFireAlarmConstants.POLICY_CONTEXT + ":" + policy;
String encryptedMsg = VirtualFireAlarmServiceUtils.prepareSecurePayLoad(actualMessage,
serverPrivateKey);
Map<String, String> dynamicProperties = new HashMap<>();
switch (protocolString) { switch (protocolString) {
case XMPP_PROTOCOL: case XMPP_PROTOCOL:
String xmppResource = VirtualFireAlarmConstants.POLICY_CONTEXT.replace("/", ""); dynamicProperties.put(VirtualFireAlarmConstants.JID_PROPERTY_KEY, deviceId);
virtualFireAlarmXMPPConnector.publishDeviceData(deviceId, xmppResource, policy); dynamicProperties.put(VirtualFireAlarmConstants.SUBJECT_PROPERTY_KEY, "POLICTY-REQUEST");
dynamicProperties.put(VirtualFireAlarmConstants.MESSAGE_TYPE_PROPERTY_KEY,
VirtualFireAlarmConstants.CHAT_PROPERTY_KEY);
APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.XMPP_ADAPTER_NAME,
dynamicProperties, encryptedMsg);
break; break;
default: default:
String mqttResource = VirtualFireAlarmConstants.POLICY_CONTEXT.replace("/", "");
virtualFireAlarmMQTTConnector.publishDeviceData(deviceId, mqttResource, policy); String publishTopic = APIUtil.getTenantDomainOftheUser() + "/"
+ VirtualFireAlarmConstants.DEVICE_TYPE + "/" + deviceId;
dynamicProperties.put(VirtualFireAlarmConstants.ADAPTER_TOPIC_PROPERTY, publishTopic);
APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.MQTT_ADAPTER_NAME,
dynamicProperties, encryptedMsg);
break; break;
} }
return Response.ok().build(); return Response.ok().build();
} catch (TransportHandlerException e) {
log.error("Failed to send update-policy request to device [" + deviceId + "] via " + protocolString);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (DeviceAccessAuthorizationException e) { } catch (DeviceAccessAuthorizationException e) {
log.error(e.getErrorMessage(), e); log.error(e.getErrorMessage(), e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} catch (VirtualFireAlarmException e) {
log.error(e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} }
} }
@ -186,13 +175,11 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) { DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
} }
if (sensorTableName != null) { List<SortByField> sortByFields = new ArrayList<>();
List<SortByField> sortByFields = new ArrayList<>(); SortByField sortByField = new SortByField("time", SORT.ASC, false);
SortByField sortByField = new SortByField("time", SORT.ASC, false); sortByFields.add(sortByField);
sortByFields.add(sortByField); List<SensorRecord> sensorRecords = APIUtil.getAllEventsForDevice(sensorTableName, query, sortByFields);
List<SensorRecord> sensorRecords = APIUtil.getAllEventsForDevice(sensorTableName, query, sortByFields); return Response.status(Response.Status.OK.getStatusCode()).entity(sensorRecords).build();
return Response.status(Response.Status.OK.getStatusCode()).entity(sensorRecords).build();
}
} catch (AnalyticsException e) { } catch (AnalyticsException e) {
String errorMsg = "Error on retrieving stats on table " + sensorTableName + " with query " + query; String errorMsg = "Error on retrieving stats on table " + sensorTableName + " with query " + query;
log.error(errorMsg); log.error(errorMsg);
@ -201,135 +188,6 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
log.error(e.getErrorMessage(), e); log.error(e.getErrorMessage(), e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
} }
return Response.status(Response.Status.BAD_REQUEST).build();
} }
private boolean waitForServerStartup() {
while (!IoTServerStartupListener.isServerReady()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
return true;
}
}
return false;
}
/**
* Fetches the `SecurityManager` specific to this VirtualFirealarm controller service.
*
* @return the 'SecurityManager' instance bound to the 'securityManager' variable of this service.
*/
@SuppressWarnings("Unused")
public SecurityManager getSecurityManager() {
return securityManager;
}
/**
* Sets the `securityManager` variable of this VirtualFirealarm controller service.
*
* @param securityManager a 'SecurityManager' object that handles the encryption, decryption, signing and validation
* of incoming messages from VirtualFirealarm device-types.
*/
@SuppressWarnings("Unused")
public void setSecurityManager(SecurityManager securityManager) {
this.securityManager = securityManager;
securityManager.initVerificationManager();
}
/**
* Fetches the `VirtualFireAlarmXMPPConnector` specific to this VirtualFirealarm controller service.
*
* @return the 'VirtualFireAlarmXMPPConnector' instance bound to the 'virtualFireAlarmXMPPConnector' variable of
* this service.
*/
@SuppressWarnings("Unused")
public VirtualFireAlarmXMPPConnector getVirtualFireAlarmXMPPConnector() {
return virtualFireAlarmXMPPConnector;
}
/**
* Sets the `virtualFireAlarmXMPPConnector` variable of this VirtualFirealarm controller service.
*
* @param virtualFireAlarmXMPPConnector a 'VirtualFireAlarmXMPPConnector' object that handles all XMPP related
* communications of any connected VirtualFirealarm device-type
*/
@SuppressWarnings("Unused")
public void setVirtualFireAlarmXMPPConnector(
final VirtualFireAlarmXMPPConnector virtualFireAlarmXMPPConnector) {
Runnable connector = new Runnable() {
public void run() {
if (waitForServerStartup()) {
return;
}
VirtualFireAlarmControllerServiceImpl.this.virtualFireAlarmXMPPConnector =
virtualFireAlarmXMPPConnector;
if (XmppConfig.getInstance().isEnabled()) {
Runnable xmppStarter = new Runnable() {
@Override
public void run() {
virtualFireAlarmXMPPConnector.initConnector();
virtualFireAlarmXMPPConnector.connect();
}
};
Thread xmppStarterThread = new Thread(xmppStarter);
xmppStarterThread.setDaemon(true);
xmppStarterThread.start();
} else {
log.warn(
"XMPP disabled in 'devicemgt-config.xml'. Hence, VirtualFireAlarmXMPPConnector not " +
"started.");
}
}
};
Thread connectorThread = new Thread(connector);
connectorThread.start();
}
/**
* Fetches the `VirtualFireAlarmMQTTConnector` specific to this VirtualFirealarm controller service.
*
* @return the 'VirtualFireAlarmMQTTConnector' instance bound to the 'virtualFireAlarmMQTTConnector' variable of
* this service.
*/
@SuppressWarnings("Unused")
public VirtualFireAlarmMQTTConnector getVirtualFireAlarmMQTTConnector() {
return virtualFireAlarmMQTTConnector;
}
/**
* Sets the `virtualFireAlarmMQTTConnector` variable of this VirtualFirealarm controller service.
*
* @param virtualFireAlarmMQTTConnector a 'VirtualFireAlarmMQTTConnector' object that handles all MQTT related
* communications of any connected VirtualFirealarm device-type
*/
@SuppressWarnings("Unused")
public void setVirtualFireAlarmMQTTConnector(
final VirtualFireAlarmMQTTConnector virtualFireAlarmMQTTConnector) {
Runnable connector = new Runnable() {
public void run() {
if (waitForServerStartup()) {
return;
}
//The delay is added for the server to starts up.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
VirtualFireAlarmControllerServiceImpl.this.virtualFireAlarmMQTTConnector =
virtualFireAlarmMQTTConnector;
if (MqttConfig.getInstance().isEnabled()) {
virtualFireAlarmMQTTConnector.connect();
} else {
log.warn(
"MQTT disabled in 'devicemgt-config.xml'. Hence, VirtualFireAlarmMQTTConnector not started.");
}
}
};
Thread connectorThread = new Thread(connector);
connectorThread.start();
}
} }

View File

@ -31,12 +31,13 @@ import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants;
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppAccount;
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig;
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppServerClient;
import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException; import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
import org.wso2.carbon.device.mgt.iot.util.ZipArchive; import org.wso2.carbon.device.mgt.iot.util.ZipArchive;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppAccount;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppConfig;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppServerClient;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.APIUtil; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.ZipUtil; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.ZipUtil;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient; import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
@ -207,6 +208,9 @@ public class VirtualFireAlarmManagerServiceImpl implements VirtualFireAlarmManag
} catch (UserStoreException ex) { } catch (UserStoreException ex) {
log.error(ex.getMessage(), ex); log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build(); return Response.status(500).entity(ex.getMessage()).build();
} catch (VirtualFirealarmDeviceMgtPluginException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} }
} }
@ -238,7 +242,7 @@ public class VirtualFireAlarmManagerServiceImpl implements VirtualFireAlarmManag
private ZipArchive createDownloadFile(String owner, String deviceName, String sketchType) private ZipArchive createDownloadFile(String owner, String deviceName, String sketchType)
throws DeviceManagementException, APIManagerException, JWTClientException, DeviceControllerException, throws DeviceManagementException, APIManagerException, JWTClientException, DeviceControllerException,
UserStoreException { UserStoreException, VirtualFirealarmDeviceMgtPluginException {
//create new device id //create new device id
String deviceId = shortUUID(); String deviceId = shortUUID();
if (apiApplicationKey == null) { if (apiApplicationKey == null) {
@ -259,15 +263,14 @@ public class VirtualFireAlarmManagerServiceImpl implements VirtualFireAlarmManag
String refreshToken = accessTokenInfo.getRefreshToken(); String refreshToken = accessTokenInfo.getRefreshToken();
//adding registering data //adding registering data
XmppAccount newXmppAccount = new XmppAccount(); XmppAccount newXmppAccount = new XmppAccount();
newXmppAccount.setAccountName(owner + "_" + deviceId); newXmppAccount.setAccountName(deviceId);
newXmppAccount.setUsername(deviceId); newXmppAccount.setUsername(deviceId);
newXmppAccount.setPassword(accessToken); newXmppAccount.setPassword(accessToken);
newXmppAccount.setEmail(deviceId + "@" + APIUtil.getTenantDomainOftheUser()); newXmppAccount.setEmail(deviceId + "@" + APIUtil.getTenantDomainOftheUser());
XmppServerClient xmppServerClient = new XmppServerClient(); XmppServerClient xmppServerClient = new XmppServerClient();
xmppServerClient.initControlQueue();
boolean status; boolean status;
if (XmppConfig.getInstance().isEnabled()) { if (XmppConfig.getInstance().isEnabled()) {
status = xmppServerClient.createXMPPAccount(newXmppAccount); status = xmppServerClient.createAccount(newXmppAccount);
if (!status) { 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" + ".XMPP might have been disabled in org.wso2.carbon.device.mgt.iot" +

View File

@ -1,36 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
@JsonIgnoreProperties(ignoreUnknown = true)
public class DeviceData {
@XmlElement(required = true) public String owner;
@XmlElement(required = true) public String deviceId;
@XmlElement(required = true) public String reply;
@XmlElement public Long time;
@XmlElement public String key;
@XmlElement public float value;
}

View File

@ -28,4 +28,8 @@ public class VirtualFireAlarmException extends Exception {
public VirtualFireAlarmException(String errorMessage, Throwable throwable) { public VirtualFireAlarmException(String errorMessage, Throwable throwable) {
super(errorMessage, throwable); super(errorMessage, throwable);
} }
public VirtualFireAlarmException(Throwable cause) {
super(cause);
}
} }

View File

@ -1,326 +0,0 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.transport;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.json.JSONObject;
import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey;
import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
import org.wso2.carbon.device.mgt.iot.transport.mqtt.MQTTTransportHandler;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.SecurityManager;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.VirtualFireAlarmServiceUtils;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.UUID;
/**
* This is an example for the use of the MQTT capabilities provided by the IoT-Server. This example depicts the use
* of MQTT Transport for the VirtualFirealarm device-type. This class extends the abstract class
* "MQTTTransportHandler". "MQTTTransportHandler" consists of the MQTT client specific functionality and implements
* the "TransportHandler" interface. The actual functionality related to the "TransportHandler" interface is
* implemented here, in this concrete class. Whilst the abstract class "MQTTTransportHandler" is intended to provide
* the common MQTT functionality, this class (which is its extension) provides the implementation specific to the
* MQTT communication of the Device-Type (VirtualFirealarm) in concern.
* <p/>
* Hence, the methods of this class are implementation of the "TransportHandler" interface which handles the device
* specific logic to connect-to, publish-to, process-incoming-messages-from and disconnect-from the MQTT broker
* listed in the configurations.
*/
@SuppressWarnings("no JAX-WS annotation")
public class VirtualFireAlarmMQTTConnector extends MQTTTransportHandler {
private static Log log = LogFactory.getLog(VirtualFireAlarmMQTTConnector.class);
// subscription topic: <SERVER_NAME>/+/virtual_firealarm/+/publisher
// wildcard (+) is in place for device_owner & device_id
private static final String subscribeTopic = "wso2/+/"+ VirtualFireAlarmConstants.DEVICE_TYPE + "/+/publisher";
private static String iotServerSubscriber = UUID.randomUUID().toString().substring(0, 5);
private static final String KEY_TYPE = "PRODUCTION";
private static final String EMPTY_STRING = "";
private static final String JSON_SERIAL_KEY = "SerialNumber";
private static final String JSON_TENANT_KEY = "Tenant";
/**
* Default constructor for the VirtualFirealarmMQTTConnector.
*/
private VirtualFireAlarmMQTTConnector() {
super(iotServerSubscriber, VirtualFireAlarmConstants.DEVICE_TYPE,
MqttConfig.getInstance().getMqttQueueEndpoint(), subscribeTopic);
}
/**
* {@inheritDoc}
* VirtualFirealarm device-type specific implementation to connect to the MQTT broker and subscribe to a topic.
* This method is called to initiate a MQTT communication.
*/
@Override
public void connect() {
Runnable connector = new Runnable() {
public void run() {
while (!isConnected()) {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
VirtualFireAlarmConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true);
try {
String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
.getRealmConfiguration().getAdminUserName();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(applicationUsername);
APIManagementProviderService apiManagementProviderService = APIUtil
.getAPIManagementProviderService();
String[] tags = {VirtualFireAlarmConstants.DEVICE_TYPE};
ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
VirtualFireAlarmConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true);
JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
String scopes = "device_type_" + VirtualFireAlarmConstants.DEVICE_TYPE + " device_mqtt_connector";
AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
apiApplicationKey.getConsumerSecret(), applicationUsername, scopes);
//create token
String accessToken = accessTokenInfo.getAccessToken();
setUsernameAndPassword(accessToken, EMPTY_STRING);
connectToQueue();
subscribeToQueue();
} catch (TransportHandlerException e) {
log.error("Connection/Subscription to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e);
try {
Thread.sleep(timeoutInterval);
} catch (InterruptedException ex) {
log.error("MQTT-Connector: Thread Sleep Interrupt Exception.", ex);
}
} catch (JWTClientException e) {
log.error("Failed to retrieve token from JWT Client.", e);
return;
} catch (UserStoreException e) {
log.error("Failed to retrieve the user.", e);
return;
} catch (APIManagerException e) {
log.error("Failed to create an application and generate keys.", e);
return;
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
}
};
Thread connectorThread = new Thread(connector);
connectorThread.start();
}
/**
* {@inheritDoc}
* VirtualFirealarm device-type specific implementation to process incoming messages. This is the specific
* method signature of the overloaded "processIncomingMessage" method that gets called from the messageArrived()
* callback of the "MQTTTransportHandler".
*/
@Override
public void processIncomingMessage(MqttMessage mqttMessage, String... messageParams) {
if (messageParams.length != 0) {
// owner and the deviceId are extracted from the MQTT topic to which the message was received.
// <Topic> = [ServerName/Owner/DeviceType/DeviceId/"publisher"]
String topic = messageParams[0];
String[] topicParams = topic.split("/");
String tenantDomain = topicParams[1];
String deviceId = topicParams[3];
if (log.isDebugEnabled()) {
log.debug("Received MQTT message for: [DEVICE.ID-" + deviceId + "]");
}
JSONObject jsonPayload = new JSONObject(mqttMessage.toString());
String actualMessage;
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
DeviceManagementProviderService deviceManagementProviderService =
(DeviceManagementProviderService) ctx.getOSGiService(DeviceManagementProviderService.class,
null);
ctx.setTenantDomain(tenantDomain, true);
if (deviceManagementProviderService != null) {
DeviceIdentifier identifier = new DeviceIdentifier(deviceId,
VirtualFireAlarmConstants.DEVICE_TYPE);
Device device = deviceManagementProviderService.getDevice(identifier);
if (device != null) {
String owner = device.getEnrolmentInfo().getOwner();
ctx.setUsername(owner);
} else {
return;
}
}
Long serialNo = (Long)jsonPayload.get(JSON_SERIAL_KEY);
// the hash-code of the deviceId is used as the alias for device certificates during SCEP enrollment.
// hence, the same is used here to fetch the device-specific-certificate from the key store.
PublicKey clientPublicKey = VirtualFireAlarmServiceUtils.getDevicePublicKey("" + serialNo);
// the MQTT-messages from VirtualFireAlarm devices are in the form {"Msg":<MESSAGE>, "Sig":<SIGNATURE>}
actualMessage = VirtualFireAlarmServiceUtils.extractMessageFromPayload(mqttMessage.toString(),
clientPublicKey);
if (log.isDebugEnabled()) {
log.debug("MQTT: Received Message [" + actualMessage + "] topic: [" + topic + "]");
}
if (actualMessage.contains("PUBLISHER")) {
float temperature = Float.parseFloat(actualMessage.split(":")[2]);
if (!VirtualFireAlarmServiceUtils.publishToDAS(deviceId, temperature)) {
log.error("MQTT Subscriber: Publishing data to DAS failed.");
}
if (log.isDebugEnabled()) {
log.debug("MQTT Subscriber: Published data to DAS successfully.");
}
} else if (actualMessage.contains("TEMPERATURE")) {
String temperatureValue = actualMessage.split(":")[1];
}
} catch (VirtualFireAlarmException e) {
String errorMsg =
"CertificateManagementService failure oo Signature-Verification/Decryption was unsuccessful.";
log.error(errorMsg, e);
} catch (DeviceManagementException e) {
log.error("Failed to retreive the device managment service for device type " +
VirtualFireAlarmConstants.DEVICE_TYPE, e);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
} else {
String errorMsg =
"MQTT message [" + mqttMessage.toString() + "] was received without the topic information.";
log.warn(errorMsg);
}
}
/**
* {@inheritDoc}
* VirtualFirealarm device-type specific implementation to publish data to the device. This method calls the
* {@link #publishToQueue(String, MqttMessage)} method of the "MQTTTransportHandler" class.
*/
@Override
public void publishDeviceData(String... publishData) throws TransportHandlerException {
if (publishData.length != 3) {
String errorMsg = "Incorrect number of arguments received to SEND-MQTT Message. " +
"Need to be [owner, deviceId, resource{BULB/TEMP}, state{ON/OFF or null}]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg);
}
String deviceId = publishData[0];
String resource = publishData[1];
String state = publishData[2];
MqttMessage pushMessage = new MqttMessage();
String publishTopic = "wso2/" + APIUtil.getTenantDomainOftheUser() + "/"
+ VirtualFireAlarmConstants.DEVICE_TYPE + "/" + deviceId;
try {
PrivateKey serverPrivateKey = SecurityManager.getServerPrivateKey();
String actualMessage = resource + ":" + state;
String encryptedMsg = VirtualFireAlarmServiceUtils.prepareSecurePayLoad(actualMessage, serverPrivateKey);
pushMessage.setPayload(encryptedMsg.getBytes(StandardCharsets.UTF_8));
pushMessage.setQos(DEFAULT_MQTT_QUALITY_OF_SERVICE);
pushMessage.setRetained(false);
publishToQueue(publishTopic, pushMessage);
} catch (VirtualFireAlarmException e) {
String errorMsg = "Preparing Secure payload failed for device - [" + deviceId + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
}
}
/**
* {@inheritDoc}
* VirtualFirealarm device-type specific implementation to disconnect from the MQTT broker.
*/
@Override
public void disconnect() {
Runnable stopConnection = new Runnable() {
public void run() {
while (isConnected()) {
try {
closeConnection();
} catch (MqttException e) {
if (log.isDebugEnabled()) {
log.warn("Unable to 'STOP' MQTT connection at broker at: " + mqttBrokerEndPoint
+ " for device-type - " + VirtualFireAlarmConstants.DEVICE_TYPE, e);
}
try {
Thread.sleep(timeoutInterval);
} catch (InterruptedException e1) {
log.error("MQTT-Terminator: Thread Sleep Interrupt Exception at device-type - " +
VirtualFireAlarmConstants.DEVICE_TYPE, e1);
}
}
}
}
};
Thread terminatorThread = new Thread(stopConnection);
terminatorThread.start();
}
/**
* {@inheritDoc}
*/
@Override
public void publishDeviceData() {
// nothing to do
}
/**
* {@inheritDoc}
*/
@Override
public void publishDeviceData(MqttMessage publishData) throws TransportHandlerException {
// nothing to do
}
/**
* {@inheritDoc}
*/
@Override
public void processIncomingMessage() {
// nothing to do
}
/**
* {@inheritDoc}
*/
@Override
public void processIncomingMessage(MqttMessage message) throws TransportHandlerException {
// nothing to do
}
}

View File

@ -1,285 +0,0 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.transport;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jivesoftware.smack.packet.Message;
import org.json.JSONObject;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppAccount;
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig;
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppServerClient;
import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
import org.wso2.carbon.device.mgt.iot.transport.xmpp.XMPPTransportHandler;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.SecurityManager;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.VirtualFireAlarmServiceUtils;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import java.io.File;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@SuppressWarnings("no JAX-WS annotation")
public class VirtualFireAlarmXMPPConnector extends XMPPTransportHandler {
private static Log log = LogFactory.getLog(VirtualFireAlarmXMPPConnector.class);
private static String xmppServerIP;
private static String xmppVFireAlarmAdminUsername;
private static String xmppVFireAlarmAdminAccountJID;
private static final String V_FIREALARM_XMPP_PASSWORD = "vfirealarm@123";
private static final String DEVICEMGT_CONFIG_FILE = "devicemgt-config.xml";
private static final String JSON_SERIAL_KEY = "SerialNumber";
private ScheduledFuture<?> connectorServiceHandler;
private ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
private VirtualFireAlarmXMPPConnector() {
super(XmppConfig.getInstance().getXmppServerIP(), XmppConfig.getInstance().getSERVER_CONNECTION_PORT());
}
public void initConnector() {
xmppVFireAlarmAdminUsername = "wso2admin_" + VirtualFireAlarmConstants.DEVICE_TYPE;
xmppServerIP = XmppConfig.getInstance().getXmppServerIP();
xmppVFireAlarmAdminAccountJID = xmppVFireAlarmAdminUsername + "@" + xmppServerIP;
createXMPPAccountForDeviceType();
}
public void createXMPPAccountForDeviceType() {
boolean accountExists;
XmppServerClient xmppServerClient = new XmppServerClient();
xmppServerClient.initControlQueue();
try {
accountExists = xmppServerClient.doesXMPPUserAccountExist(xmppVFireAlarmAdminUsername);
if (!accountExists) {
XmppAccount xmppAccount = new XmppAccount();
xmppAccount.setAccountName(xmppVFireAlarmAdminUsername);
xmppAccount.setUsername(xmppVFireAlarmAdminUsername);
xmppAccount.setPassword(V_FIREALARM_XMPP_PASSWORD);
xmppAccount.setEmail("");
try {
boolean xmppCreated = xmppServerClient.createXMPPAccount(xmppAccount);
if (!xmppCreated) {
log.warn("Server XMPP Account was not created for device-type - " +
VirtualFireAlarmConstants.DEVICE_TYPE +
". Check whether XMPP is enabled in \"devicemgt-config.xml\" & restart.");
} else {
log.info("Server XMPP Account [" + xmppVFireAlarmAdminUsername +
"] was not created for device - " + VirtualFireAlarmConstants.DEVICE_TYPE);
}
} catch (DeviceControllerException e) {
String errorMsg =
"An error was encountered whilst trying to create Server XMPP account for device-type - "
+ VirtualFireAlarmConstants.DEVICE_TYPE;
log.error(errorMsg, e);
}
}
} catch (DeviceControllerException e) {
if (e.getMessage().contains(DEVICEMGT_CONFIG_FILE)) {
log.warn("XMPP not Enabled");
} else {
String errorMsg = "An error was encountered whilst trying to check whether Server XMPP account " +
"exists for device-type - " + VirtualFireAlarmConstants.DEVICE_TYPE ;
log.error(errorMsg, e);
}
}
}
@Override
public void connect() {
Runnable connector = new Runnable() {
public void run() {
if (!isConnected()) {
try {
connectToServer();
loginToServer(xmppVFireAlarmAdminUsername, V_FIREALARM_XMPP_PASSWORD, null);
setFilterOnReceiver(xmppVFireAlarmAdminAccountJID);
} catch (TransportHandlerException e) {
if (log.isDebugEnabled()) {
log.warn("Connection/Login to XMPP server at: " + server + " as " +
xmppVFireAlarmAdminUsername + " failed for device-type [" +
VirtualFireAlarmConstants.DEVICE_TYPE + "].", e);
}
}
}
}
};
connectorServiceHandler = service.scheduleAtFixedRate(connector, 0, timeoutInterval, TimeUnit.MILLISECONDS);
}
@Override
public void processIncomingMessage(Message xmppMessage) throws TransportHandlerException {
String from = xmppMessage.getFrom();
String subject = xmppMessage.getSubject();
String message = xmppMessage.getBody();
int indexOfAt = from.indexOf("@");
int indexOfSlash = from.indexOf("/");
if (indexOfAt != -1 && indexOfSlash != -1) {
String deviceId = from.substring(0, indexOfAt);
String owner = from.substring(indexOfSlash + 1, from.length());
if (log.isDebugEnabled()) {
log.debug("Received XMPP message for: [OWNER-" + owner + "] & [DEVICE.ID-" + deviceId + "]");
}
try {
PrivilegedCarbonContext.startTenantFlow();
String tenantDomain = MultitenantUtils.getTenantDomain(owner);
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain);
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(owner);
JSONObject jsonPayload = new JSONObject(message);
Long serialNo = (Long)jsonPayload.get(JSON_SERIAL_KEY);
PublicKey clientPublicKey = VirtualFireAlarmServiceUtils.getDevicePublicKey("" + serialNo);
String actualMessage = VirtualFireAlarmServiceUtils.extractMessageFromPayload(message,
clientPublicKey);
if (log.isDebugEnabled()) {
log.debug("XMPP: Received Message [" + actualMessage + "] from: [" + from + "]");
}
if (subject != null) {
switch (subject) {
case "PUBLISHER":
float temperature = Float.parseFloat(actualMessage.split(":")[1]);
if (!VirtualFireAlarmServiceUtils.publishToDAS(deviceId, temperature)) {
log.error("XMPP Connector: Publishing VirtualFirealarm data to DAS failed.");
}
PrivilegedCarbonContext.endTenantFlow();
if (log.isDebugEnabled()) {
log.debug("XMPP: Publisher Message [" + actualMessage + "] from [" + from + "] " +
"was successfully published to DAS");
}
break;
case "CONTROL-REPLY":
String tempVal = actualMessage.split(":")[1];
break;
default:
if (log.isDebugEnabled()) {
log.warn("Unknown XMPP Message [" + actualMessage + "] from [" + from + "] received");
}
break;
}
}
} catch (VirtualFireAlarmException e) {
String errorMsg =
"CertificateManagementService failure oo Signature-Verification/Decryption was unsuccessful.";
log.error(errorMsg, e);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
} else {
log.warn("Received XMPP message from client with unexpected JID [" + from + "].");
}
}
@Override
public void publishDeviceData(String... publishData) throws TransportHandlerException {
if (publishData.length != 4) {
String errorMsg = "Incorrect number of arguments received to SEND-MQTT Message. " +
"Need to be [owner, deviceId, resource{BULB/TEMP}, state{ON/OFF or null}]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg);
}
String deviceOwner = publishData[0];
String deviceId = publishData[1];
String resource = publishData[2];
String state = publishData[3];
try {
PrivateKey serverPrivateKey = SecurityManager.getServerPrivateKey();
String actualMessage = resource + ":" + state;
String encryptedMsg = VirtualFireAlarmServiceUtils.prepareSecurePayLoad(actualMessage, serverPrivateKey);
String clientToConnect = deviceId + "@" + xmppServerIP + File.separator + deviceOwner;
sendXMPPMessage(clientToConnect, encryptedMsg, "CONTROL-REQUEST");
} catch (VirtualFireAlarmException e) {
String errorMsg = "Preparing Secure payload failed for device - [" + deviceId + "] of owner - " +
"[" + deviceOwner + "].";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
}
}
@Override
public void disconnect() {
Runnable stopConnection = new Runnable() {
public void run() {
while (isConnected()) {
connectorServiceHandler.cancel(true);
closeConnection();
if (log.isDebugEnabled()) {
log.warn("Unable to 'STOP' connection to XMPP server at: " + server +
" for user - " + xmppVFireAlarmAdminUsername);
}
try {
Thread.sleep(timeoutInterval);
} catch (InterruptedException e1) {
log.error("XMPP-Terminator: Thread Sleep Interrupt Exception for "
+ VirtualFireAlarmConstants.DEVICE_TYPE + " type.", e1);
}
}
}
};
Thread terminatorThread = new Thread(stopConnection);
terminatorThread.start();
}
@Override
public void processIncomingMessage(Message message, String... messageParams) throws TransportHandlerException {
// nothing to do
}
@Override
public void processIncomingMessage() throws TransportHandlerException {
// nothing to do
}
@Override
public void publishDeviceData() throws TransportHandlerException {
// nothing to do
}
@Override
public void publishDeviceData(Message publishData) throws TransportHandlerException {
// nothing to do
}
}

View File

@ -21,333 +21,33 @@ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.json.JSONObject; import org.json.JSONObject;
import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException;
import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util.VirtualFirealarmSecurityManager;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException;
import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException;
import javax.ws.rs.HttpMethod;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.*; import java.lang.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.security.Key;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
/** /**
* *
*/ */
public class VirtualFireAlarmServiceUtils { public class VirtualFireAlarmServiceUtils {
private static final Log log = LogFactory.getLog(VirtualFireAlarmServiceUtils.class);
private static final String TEMPERATURE_STREAM_DEFINITION = "org.wso2.iot.devices.temperature";
private static final String JSON_MESSAGE_KEY = "Msg"; private static final String JSON_MESSAGE_KEY = "Msg";
private static final String JSON_SIGNATURE_KEY = "Sig"; private static final String JSON_SIGNATURE_KEY = "Sig";
/**
*
* @return
* @throws VirtualFireAlarmException
*/
public static CertificateManagementService getCertificateManagementService() throws VirtualFireAlarmException {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
CertificateManagementService certificateManagementService = (CertificateManagementService)
ctx.getOSGiService(CertificateManagementService.class, null);
if (certificateManagementService == null) {
String msg = "EnrollmentService is not initialized";
log.error(msg);
throw new VirtualFireAlarmException(msg);
}
return certificateManagementService;
}
/**
*
* @param deviceHTTPEndpoint
* @param urlContext
* @param fireAndForgot
* @return
* @throws DeviceManagementException
*/
public static String sendCommandViaHTTP(final String deviceHTTPEndpoint, String urlContext, boolean fireAndForgot)
throws DeviceManagementException {
String responseMsg = "";
String urlString = VirtualFireAlarmConstants.URL_PREFIX + deviceHTTPEndpoint + urlContext;
if (log.isDebugEnabled()) {
log.debug(urlString);
}
if (!fireAndForgot) {
HttpURLConnection httpConnection = getHttpConnection(urlString);
try {
httpConnection.setRequestMethod(HttpMethod.GET);
} catch (ProtocolException e) {
String errorMsg =
"Protocol specific error occurred when trying to set method to GET" +
" for:" + urlString;
log.error(errorMsg);
throw new DeviceManagementException(errorMsg, e);
}
responseMsg = readResponseFromGetRequest(httpConnection);
} else {
CloseableHttpAsyncClient httpclient = null;
try {
httpclient = HttpAsyncClients.createDefault();
httpclient.start();
HttpGet request = new HttpGet(urlString);
final CountDownLatch latch = new CountDownLatch(1);
Future<HttpResponse> future = httpclient.execute(
request, new FutureCallback<HttpResponse>() {
@Override
public void completed(HttpResponse httpResponse) {
latch.countDown();
}
@Override
public void failed(Exception e) {
latch.countDown();
}
@Override
public void cancelled() {
latch.countDown();
}
});
latch.await();
} catch (InterruptedException e) {
if (log.isDebugEnabled()) {
log.debug("Sync Interrupted");
}
} finally {
try {
if (httpclient != null) {
httpclient.close();
}
} catch (IOException e) {
if (log.isDebugEnabled()) {
log.debug("Failed on close");
}
}
}
}
return responseMsg;
}
/* ---------------------------------------------------------------------------------------
Utility methods relevant to creating and sending http requests
--------------------------------------------------------------------------------------- */
/* This methods creates and returns a http connection object */
/**
*
* @param urlString
* @return
* @throws DeviceManagementException
*/
public static HttpURLConnection getHttpConnection(String urlString) throws DeviceManagementException {
URL connectionUrl = null;
HttpURLConnection httpConnection;
try {
connectionUrl = new URL(urlString);
httpConnection = (HttpURLConnection) connectionUrl.openConnection();
} catch (MalformedURLException e) {
String errorMsg =
"Error occured whilst trying to form HTTP-URL from string: " + urlString;
log.error(errorMsg);
throw new DeviceManagementException(errorMsg, e);
} catch (IOException e) {
String errorMsg = "Error occured whilst trying to open a connection to: " +
connectionUrl.toString();
log.error(errorMsg);
throw new DeviceManagementException(errorMsg, e);
}
return httpConnection;
}
/* This methods reads and returns the response from the connection */
public static String readResponseFromGetRequest(HttpURLConnection httpConnection)
throws DeviceManagementException {
BufferedReader bufferedReader;
try {
bufferedReader = new BufferedReader(new InputStreamReader(
httpConnection.getInputStream()));
} catch (IOException e) {
String errorMsg =
"There is an issue with connecting the reader to the input stream at: " +
httpConnection.getURL();
log.error(errorMsg);
throw new DeviceManagementException(errorMsg, e);
}
String responseLine;
StringBuilder completeResponse = new StringBuilder();
try {
while ((responseLine = bufferedReader.readLine()) != null) {
completeResponse.append(responseLine);
}
} catch (IOException e) {
String errorMsg =
"Error occured whilst trying read from the connection stream at: " +
httpConnection.getURL();
log.error(errorMsg);
throw new DeviceManagementException(errorMsg, e);
}
try {
bufferedReader.close();
} catch (IOException e) {
log.error(
"Could not succesfully close the bufferedReader to the connection at: " +
httpConnection.getURL());
}
return completeResponse.toString();
}
public static boolean publishToDAS(String deviceId, float temperature) {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
EventsPublisherService deviceAnalyticsService = (EventsPublisherService) ctx.getOSGiService(
EventsPublisherService.class, null);
if (deviceAnalyticsService != null) {
String owner = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
Object metdaData[] = {owner, VirtualFireAlarmConstants.DEVICE_TYPE, deviceId, System.currentTimeMillis()};
Object payloadData[] = {temperature};
try {
deviceAnalyticsService.publishEvent(TEMPERATURE_STREAM_DEFINITION, "1.0.0", metdaData, new Object[0],
payloadData);
} catch (DataPublisherConfigurationException e) {
return false;
}
return true;
}
return false;
}
/**
*
* @param message
* @param signatureKey
* @return
* @throws VirtualFireAlarmException
*/
public static String prepareSecurePayLoad(String message, PrivateKey signatureKey) throws VirtualFireAlarmException { public static String prepareSecurePayLoad(String message, PrivateKey signatureKey) throws VirtualFireAlarmException {
message = Base64.encodeBase64String(message.getBytes());
String signedPayload = SecurityManager.signMessage(message, signatureKey);
JSONObject jsonPayload = new JSONObject();
jsonPayload.put(JSON_MESSAGE_KEY, message);
jsonPayload.put(JSON_SIGNATURE_KEY, signedPayload);
return jsonPayload.toString();
}
/**
*
* @param message
* @param verifySignatureKey
* @return
* @throws VirtualFireAlarmException
*/
public static String extractMessageFromPayload(String message, PublicKey verifySignatureKey)
throws VirtualFireAlarmException {
String actualMessage;
JSONObject jsonPayload = new JSONObject(message);
Object encodedMessage = jsonPayload.get(JSON_MESSAGE_KEY);
Object signedPayload = jsonPayload.get(JSON_SIGNATURE_KEY);
if (encodedMessage != null && signedPayload != null) {
if (SecurityManager.verifySignature(
encodedMessage.toString(), signedPayload.toString(), verifySignatureKey)) {
actualMessage = new String(Base64.decodeBase64(encodedMessage.toString()));
//SecurityManager.decryptMessage(encryptedMessage.toString(), decryptionKey);
} else {
String errorMsg = "The message was not signed by a valid client. Could not verify signature on payload";
throw new VirtualFireAlarmException(errorMsg);
}
} else {
String errorMsg = "The received message is in an INVALID format. " +
"Need to be JSON - {\"Msg\":\"<ENCRYPTED_MSG>\", \"Sig\":\"<SIGNED_MSG>\"}.";
throw new VirtualFireAlarmException(errorMsg);
}
return actualMessage;
}
/**
*
* @param alias
* @return
* @throws VirtualFireAlarmException
*/
public static PublicKey getDevicePublicKey(String alias) throws VirtualFireAlarmException {
PublicKey clientPublicKey;
try { try {
CertificateManagementService certificateManagementService = message = Base64.encodeBase64String(message.getBytes());
VirtualFireAlarmServiceUtils.getCertificateManagementService(); String signedPayload = VirtualFirealarmSecurityManager.signMessage(message, signatureKey);
X509Certificate clientCertificate = (X509Certificate) certificateManagementService.getCertificateByAlias( JSONObject jsonPayload = new JSONObject();
alias); jsonPayload.put(JSON_MESSAGE_KEY, message);
clientPublicKey = clientCertificate.getPublicKey(); jsonPayload.put(JSON_SIGNATURE_KEY, signedPayload);
return jsonPayload.toString();
} catch (VirtualFireAlarmException e) { } catch (VirtualFirealarmDeviceMgtPluginException e) {
String errorMsg = "Could not retrieve CertificateManagementService from the runtime."; throw new VirtualFireAlarmException(e);
if(log.isDebugEnabled()){
log.debug(errorMsg);
}
throw new VirtualFireAlarmException(errorMsg, e);
} catch (KeystoreException e) {
String errorMsg;
if (e.getMessage().contains("NULL_CERT")) {
errorMsg = "The Device-View page might have been accessed prior to the device being started.";
if(log.isDebugEnabled()){
log.debug(errorMsg);
}
throw new VirtualFireAlarmException(errorMsg, e);
} else {
errorMsg = "An error occurred whilst trying to retrieve certificate for alias [" + alias +
"] with alias: [" + alias + "]";
if(log.isDebugEnabled()){
log.debug(errorMsg);
}
throw new VirtualFireAlarmException(errorMsg, e);
}
} }
return clientPublicKey;
}
}
} }

View File

@ -44,7 +44,7 @@
</Permission> </Permission>
<Permission> <Permission>
<name>Download device</name> <name>Download device</name>
<path>/device-mgt/user</path> <path>/device-mgt/virtual_firealarm/user</path>
<url>/enrollment/devices/download</url> <url>/enrollment/devices/download</url>
<method>GET</method> <method>GET</method>
<scope>virtual_firealarm_user</scope> <scope>virtual_firealarm_user</scope>

View File

@ -27,9 +27,6 @@
<jaxrs:serviceBeans> <jaxrs:serviceBeans>
<bean id="VirtualFireAlarmControllerService" <bean id="VirtualFireAlarmControllerService"
class="org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.VirtualFireAlarmControllerServiceImpl"> class="org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.VirtualFireAlarmControllerServiceImpl">
<property name="securityManager" ref="securityManagerBean"/>
<property name="virtualFireAlarmMQTTConnector" ref="mqttConnectorBean"/>
<property name="virtualFireAlarmXMPPConnector" ref="xmppConnectorBean"/>
</bean> </bean>
<bean id="VirtualFireAlarmManagerService" <bean id="VirtualFireAlarmManagerService"
class="org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.VirtualFireAlarmManagerServiceImpl"> class="org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.VirtualFireAlarmManagerServiceImpl">
@ -40,15 +37,5 @@
</jaxrs:providers> </jaxrs:providers>
</jaxrs:server> </jaxrs:server>
<bean id="securityManagerBean"
class="org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.SecurityManager">
</bean>
<bean id="mqttConnectorBean"
class="org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.transport.VirtualFireAlarmMQTTConnector">
</bean>
<bean id="xmppConnectorBean"
class="org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.transport.VirtualFireAlarmXMPPConnector">
</bean>
</beans> </beans>

View File

@ -77,7 +77,18 @@
org.wso2.carbon.base, org.wso2.carbon.base,
org.wso2.carbon.core.util, org.wso2.carbon.core.util,
org.wso2.carbon.context, org.wso2.carbon.context,
org.wso2.carbon.core org.wso2.carbon.core,
javax.crypto,
org.apache.commons.codec.binary,
org.json.*;version="${commons-json.version.range}",
org.wso2.carbon.certificate.mgt.core.exception,
org.wso2.carbon.certificate.mgt.core.service,
org.wso2.carbon.certificate.mgt.core.util,
org.wso2.carbon.device.mgt.analytics.data.publisher.exception,
org.wso2.carbon.device.mgt.analytics.data.publisher.service,
org.wso2.carbon.event.input.adapter.core,
org.wso2.carbon.event.input.adapter.core.exception,
org.jivesoftware.smack.*
</Import-Package> </Import-Package>
<Export-Package> <Export-Package>
!org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.internal, !org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.internal,
@ -90,6 +101,10 @@
</build> </build>
<dependencies> <dependencies>
<dependency>
<groupId>commons-codec.wso2</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.eclipse.osgi</groupId> <groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi</artifactId> <artifactId>org.eclipse.osgi</artifactId>
@ -106,6 +121,10 @@
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.common</artifactId> <artifactId>org.wso2.carbon.device.mgt.common</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.wso2.carbon</groupId> <groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.ndatasource.core</artifactId> <artifactId>org.wso2.carbon.ndatasource.core</artifactId>
@ -122,6 +141,33 @@
<groupId>org.wso2.carbon.analytics-common</groupId> <groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.output.adapter.core</artifactId> <artifactId>org.wso2.carbon.event.output.adapter.core</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.event.input.adapter.core</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>org.wso2.carbon.device.mgt.iot.input.adapter.extension</artifactId>
</dependency>
<dependency>
<groupId>org.json.wso2</groupId>
<artifactId>json</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.certificate.mgt.core</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.analytics.data.publisher</artifactId>
</dependency>
<dependency>
<groupId>org.igniterealtime.smack.wso2</groupId>
<artifactId>smack</artifactId>
</dependency>
<dependency>
<groupId>org.igniterealtime.smack.wso2</groupId>
<artifactId>smackx</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -26,17 +26,17 @@ public class VirtualFireAlarmConstants {
public final static String STATE_OFF = "OFF"; public final static String STATE_OFF = "OFF";
public static final String URL_PREFIX = "http://"; public static final String URL_PREFIX = "http://";
public static final String BULB_CONTEXT = "/BULB/"; public static final String BULB_CONTEXT = "BULB";
public static final String POLICY_CONTEXT = "/POLICY/"; public static final String POLICY_CONTEXT = "POLICY";
//sensor events sumerized table name for temperature //sensor events sumerized table name for temperature
public static final String TEMPERATURE_EVENT_TABLE = "DEVICE_TEMPERATURE_SUMMARY"; public static final String TEMPERATURE_EVENT_TABLE = "DEVICE_TEMPERATURE_SUMMARY";
public static final String DATA_SOURCE_NAME = "jdbc/VirtualFireAlarmDM_DB"; public static final String DATA_SOURCE_NAME = "jdbc/VirtualFireAlarmDM_DB";
public final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super"; public final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super";
//tranport related constants //mqtt tranport related constants
public static final String ADAPTER_NAME = "virtual_firealarm_mqtt"; public static final String MQTT_ADAPTER_NAME = "virtual_firealarm_mqtt";
public static final String ADAPTER_TYPE = "oauth-mqtt"; public static final String MQTT_ADAPTER_TYPE = "oauth-mqtt";
public static final String ADAPTER_TOPIC_PROPERTY = "topic"; public static final String ADAPTER_TOPIC_PROPERTY = "topic";
public static final String MQTT_PORT = "\\$\\{mqtt.broker.port\\}"; public static final String MQTT_PORT = "\\$\\{mqtt.broker.port\\}";
public static final String MQTT_BROKER_HOST = "\\$\\{mqtt.broker.host\\}"; public static final String MQTT_BROKER_HOST = "\\$\\{mqtt.broker.host\\}";
@ -45,6 +45,15 @@ public class VirtualFireAlarmConstants {
public static final int CARBON_DEFAULT_PORT_OFFSET = 0; public static final int CARBON_DEFAULT_PORT_OFFSET = 0;
public static final int DEFAULT_MQTT_PORT = 1883; public static final int DEFAULT_MQTT_PORT = 1883;
//xmpp transport related constants
public static final String XMPP_ADAPTER_NAME = "virtual_firealarm_xmpp";
public static final String XMPP_ADAPTER_TYPE = "xmpp";
public static final String PASSWORD_PROPERTY_KEY = "password";
public static final String JID_PROPERTY_KEY = "jid";
public static final String SUBJECT_PROPERTY_KEY = "subject";
public static final String MESSAGE_TYPE_PROPERTY_KEY = "messageType";
public static final String CHAT_PROPERTY_KEY = "chat";
public static final String USERNAME_PROPERTY_KEY = "username"; public static final String USERNAME_PROPERTY_KEY = "username";
public static final String DCR_PROPERTY_KEY = "dcrUrl"; public static final String DCR_PROPERTY_KEY = "dcrUrl";
public static final String BROKER_URL_PROPERTY_KEY = "url"; public static final String BROKER_URL_PROPERTY_KEY = "url";
@ -52,4 +61,22 @@ public class VirtualFireAlarmConstants {
public static final String QOS_PROPERTY_KEY = "qos"; public static final String QOS_PROPERTY_KEY = "qos";
public static final String CLIENT_ID_PROPERTY_KEY = "qos"; public static final String CLIENT_ID_PROPERTY_KEY = "qos";
public static final String CLEAR_SESSION_PROPERTY_KEY = "clearSession"; public static final String CLEAR_SESSION_PROPERTY_KEY = "clearSession";
public static final String TOPIC = "topic";
public static final String SUBSCRIBED_TOPIC = "carbon.super/virtual_firealarm/+/publisher";
public static final String CONTENT_VALIDATION = "contentValidation";
public static final String CONTENT_TRANSFORMATION = "contentTransformer";
public static final String JSON_SERIAL_KEY = "SerialNumber";
public static final String TEMPERATURE_STREAM_DEFINITION = "org.wso2.iot.devices.temperature";
public static final String JSON_MESSAGE_KEY = "Msg";
public static final String JSON_SIGNATURE_KEY = "Sig";
public static final String IS_ENABLED_KEY = "enabled";
public static final String HOST_KEY = "host";
public static final String PORT_KEY = "port";
public static final String CONNECTION_PORT = "connection.port";
public static final String ADMIN_USERNAME = "admin.username";
public static final String ADMIN_PASSWORD = "admin.password";
public static final String XMPP_SERVER_PASSWORD = "admin@123456789";
} }

View File

@ -18,19 +18,27 @@
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util; package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.base.ServerConfiguration; import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException;
import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.util.Utils; import org.wso2.carbon.core.util.Utils;
import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException;
import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.internal.VirtualFirealarmManagementDataHolder; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.internal.VirtualFirealarmManagementDataHolder;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppConfig;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration;
import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterException;
import org.wso2.carbon.event.output.adapter.core.MessageType; import org.wso2.carbon.event.output.adapter.core.MessageType;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration; 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.OutputEventAdapterException;
import org.wso2.carbon.utils.CarbonUtils; import org.wso2.carbon.utils.CarbonUtils;
import org.json.JSONObject;
import javax.naming.Context; import javax.naming.Context;
import javax.naming.InitialContext; import javax.naming.InitialContext;
import javax.naming.NamingException; import javax.naming.NamingException;
@ -38,6 +46,8 @@ import javax.sql.DataSource;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -53,8 +63,8 @@ public class VirtualFireAlarmUtils {
private static Log log = LogFactory.getLog(VirtualFireAlarmUtils.class); private static Log log = LogFactory.getLog(VirtualFireAlarmUtils.class);
private static final String VIRTUAL_FIREALARM_CONFIG_LOCATION = private static final String VIRTUAL_FIREALARM_CONFIG_LOCATION =
CarbonUtils.getCarbonHome() + File.separator + "repository" + File.separator + "resources" + CarbonUtils.getCarbonHome() + File.separator + "repository" + File.separator + "conf" +
File.separator + "device-types" + File.separator + "virtual-firealarm.properties"; File.separator + "iot" + File.separator + "mqtt.properties";
public static void cleanupResources(Connection conn, PreparedStatement stmt, ResultSet rs) { public static void cleanupResources(Connection conn, PreparedStatement stmt, ResultSet rs) {
if (rs != null) { if (rs != null) {
@ -103,10 +113,10 @@ public class VirtualFireAlarmUtils {
} }
} }
public static void setupOutputAdapter() throws IOException { public static void setupMqttOutputAdapter() throws IOException {
OutputEventAdapterConfiguration outputEventAdapterConfiguration = OutputEventAdapterConfiguration outputEventAdapterConfiguration =
createOutputEventAdapterConfiguration(VirtualFireAlarmConstants.ADAPTER_NAME, createMqttOutputEventAdapterConfiguration(VirtualFireAlarmConstants.MQTT_ADAPTER_NAME,
VirtualFireAlarmConstants.ADAPTER_TYPE, MessageType.TEXT); VirtualFireAlarmConstants.MQTT_ADAPTER_TYPE, MessageType.TEXT);
try { try {
PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain( PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
@ -114,7 +124,24 @@ public class VirtualFireAlarmUtils {
VirtualFirealarmManagementDataHolder.getInstance().getOutputEventAdapterService() VirtualFirealarmManagementDataHolder.getInstance().getOutputEventAdapterService()
.create(outputEventAdapterConfiguration); .create(outputEventAdapterConfiguration);
} catch (OutputEventAdapterException e) { } catch (OutputEventAdapterException e) {
log.error("Unable to create Output Event Adapter : " + VirtualFireAlarmConstants.ADAPTER_NAME, e); log.error("Unable to create Output Event Adapter : " + VirtualFireAlarmConstants.MQTT_ADAPTER_NAME, e);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
public static void setupMqttInputAdapter() throws IOException {
InputEventAdapterConfiguration inputEventAdapterConfiguration =
createMqttInputEventAdapterConfiguration(VirtualFireAlarmConstants.MQTT_ADAPTER_NAME,
VirtualFireAlarmConstants.MQTT_ADAPTER_TYPE, MessageType.TEXT);
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
VirtualFireAlarmConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true);
VirtualFirealarmManagementDataHolder.getInstance().getInputEventAdapterService()
.create(inputEventAdapterConfiguration, new VirtualFirealarmEventAdapterSubscription());
} catch (InputEventAdapterException e) {
log.error("Unable to create Input Event Adapter : " + VirtualFireAlarmConstants.MQTT_ADAPTER_NAME, e);
} finally { } finally {
PrivilegedCarbonContext.endTenantFlow(); PrivilegedCarbonContext.endTenantFlow();
} }
@ -128,9 +155,8 @@ public class VirtualFireAlarmUtils {
* @param msgFormat Output Event Adapter message format * @param msgFormat Output Event Adapter message format
* @return OutputEventAdapterConfiguration instance for given configuration * @return OutputEventAdapterConfiguration instance for given configuration
*/ */
private static OutputEventAdapterConfiguration createOutputEventAdapterConfiguration(String name, String type, private static OutputEventAdapterConfiguration createMqttOutputEventAdapterConfiguration(String name, String type,
String msgFormat) String msgFormat) throws IOException {
throws IOException {
OutputEventAdapterConfiguration outputEventAdapterConfiguration = new OutputEventAdapterConfiguration(); OutputEventAdapterConfiguration outputEventAdapterConfiguration = new OutputEventAdapterConfiguration();
outputEventAdapterConfiguration.setName(name); outputEventAdapterConfiguration.setName(name);
outputEventAdapterConfiguration.setType(type); outputEventAdapterConfiguration.setType(type);
@ -153,14 +179,55 @@ public class VirtualFireAlarmUtils {
VirtualFireAlarmConstants.CLEAR_SESSION_PROPERTY_KEY)); VirtualFireAlarmConstants.CLEAR_SESSION_PROPERTY_KEY));
mqttAdapterProperties.put(VirtualFireAlarmConstants.QOS_PROPERTY_KEY, properties.getProperty( mqttAdapterProperties.put(VirtualFireAlarmConstants.QOS_PROPERTY_KEY, properties.getProperty(
VirtualFireAlarmConstants.QOS_PROPERTY_KEY)); VirtualFireAlarmConstants.QOS_PROPERTY_KEY));
mqttAdapterProperties.put(VirtualFireAlarmConstants.CLIENT_ID_PROPERTY_KEY, properties.getProperty( mqttAdapterProperties.put(VirtualFireAlarmConstants.CLIENT_ID_PROPERTY_KEY, "");
VirtualFireAlarmConstants.CLIENT_ID_PROPERTY_KEY));
outputEventAdapterConfiguration.setStaticProperties(mqttAdapterProperties); outputEventAdapterConfiguration.setStaticProperties(mqttAdapterProperties);
} }
return outputEventAdapterConfiguration; return outputEventAdapterConfiguration;
} }
public static String replaceMqttProperty(String urlWithPlaceholders) { /**
* Create Output Event Adapter Configuration for given configuration.
*
* @param name Input Event Adapter name
* @param type Input Event Adapter type
* @param msgFormat Input Event Adapter message format
* @return InputEventAdapterConfiguration instance for given configuration
*/
private static InputEventAdapterConfiguration createMqttInputEventAdapterConfiguration(String name, String type,
String msgFormat) throws IOException {
InputEventAdapterConfiguration inputEventAdapterConfiguration = new InputEventAdapterConfiguration();
inputEventAdapterConfiguration.setName(name);
inputEventAdapterConfiguration.setType(type);
inputEventAdapterConfiguration.setMessageFormat(msgFormat);
File configFile = new File(VIRTUAL_FIREALARM_CONFIG_LOCATION);
if (configFile.exists()) {
Map<String, String> mqttAdapterProperties = new HashMap<>();
InputStream propertyStream = configFile.toURI().toURL().openStream();
Properties properties = new Properties();
properties.load(propertyStream);
mqttAdapterProperties.put(VirtualFireAlarmConstants.USERNAME_PROPERTY_KEY, properties.getProperty(
VirtualFireAlarmConstants.USERNAME_PROPERTY_KEY));
mqttAdapterProperties.put(VirtualFireAlarmConstants.DCR_PROPERTY_KEY, Utils.replaceSystemProperty(
properties.getProperty(VirtualFireAlarmConstants.DCR_PROPERTY_KEY)));
mqttAdapterProperties.put(VirtualFireAlarmConstants.BROKER_URL_PROPERTY_KEY, replaceMqttProperty(
properties.getProperty(VirtualFireAlarmConstants.BROKER_URL_PROPERTY_KEY)));
mqttAdapterProperties.put(VirtualFireAlarmConstants.SCOPES_PROPERTY_KEY, properties.getProperty(
VirtualFireAlarmConstants.SCOPES_PROPERTY_KEY));
mqttAdapterProperties.put(VirtualFireAlarmConstants.CLEAR_SESSION_PROPERTY_KEY, properties.getProperty(
VirtualFireAlarmConstants.CLEAR_SESSION_PROPERTY_KEY));
mqttAdapterProperties.put(VirtualFireAlarmConstants.QOS_PROPERTY_KEY, properties.getProperty(
VirtualFireAlarmConstants.QOS_PROPERTY_KEY));
mqttAdapterProperties.put(VirtualFireAlarmConstants.CLIENT_ID_PROPERTY_KEY, "");
mqttAdapterProperties.put(VirtualFireAlarmConstants.TOPIC, VirtualFireAlarmConstants.SUBSCRIBED_TOPIC);
mqttAdapterProperties.put(VirtualFireAlarmConstants.CONTENT_TRANSFORMATION,
VirtualFirealarmMqttContentTransformer.class.getName());
mqttAdapterProperties.put(VirtualFireAlarmConstants.CONTENT_VALIDATION, "default");
inputEventAdapterConfiguration.setProperties(mqttAdapterProperties);
}
return inputEventAdapterConfiguration;
}
private static String replaceMqttProperty(String urlWithPlaceholders) {
urlWithPlaceholders = Utils.replaceSystemProperty(urlWithPlaceholders); urlWithPlaceholders = Utils.replaceSystemProperty(urlWithPlaceholders);
urlWithPlaceholders = urlWithPlaceholders.replaceAll(VirtualFireAlarmConstants.MQTT_PORT, "" + urlWithPlaceholders = urlWithPlaceholders.replaceAll(VirtualFireAlarmConstants.MQTT_PORT, "" +
(VirtualFireAlarmConstants.DEFAULT_MQTT_PORT + getPortOffset())); (VirtualFireAlarmConstants.DEFAULT_MQTT_PORT + getPortOffset()));
@ -184,4 +251,156 @@ public class VirtualFireAlarmUtils {
} }
} }
public static String extractMessageFromPayload(String message, PublicKey verifySignatureKey)
throws VirtualFirealarmDeviceMgtPluginException {
String actualMessage;
JSONObject jsonPayload = new JSONObject(message);
Object encodedMessage = jsonPayload.get(VirtualFireAlarmConstants.JSON_MESSAGE_KEY);
Object signedPayload = jsonPayload.get(VirtualFireAlarmConstants.JSON_SIGNATURE_KEY);
if (encodedMessage != null && signedPayload != null) {
if (VirtualFirealarmSecurityManager.verifySignature(
encodedMessage.toString(), signedPayload.toString(), verifySignatureKey)) {
actualMessage = new String(Base64.decodeBase64(encodedMessage.toString()));
//VirtualFirealarmSecurityManager.decryptMessage(encryptedMessage.toString(), decryptionKey);
} else {
String errorMsg = "The message was not signed by a valid client. Could not verify signature on payload";
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg);
}
} else {
String errorMsg = "The received message is in an INVALID format. " +
"Need to be JSON - {\"Msg\":\"<ENCRYPTED_MSG>\", \"Sig\":\"<SIGNED_MSG>\"}.";
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg);
}
return actualMessage;
}
public static PublicKey getDevicePublicKey(String alias) throws VirtualFirealarmDeviceMgtPluginException {
PublicKey clientPublicKey;
try {
CertificateManagementService certificateManagementService =
VirtualFirealarmManagementDataHolder.getInstance().getCertificateManagementService();
X509Certificate clientCertificate = (X509Certificate) certificateManagementService.getCertificateByAlias(
alias);
clientPublicKey = clientCertificate.getPublicKey();
} catch (KeystoreException e) {
String errorMsg;
if (e.getMessage().contains("NULL_CERT")) {
errorMsg = "The Device-View page might have been accessed prior to the device being started.";
if(log.isDebugEnabled()){
log.debug(errorMsg);
}
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} else {
errorMsg = "An error occurred whilst trying to retrieve certificate for alias [" + alias +
"] with alias: [" + alias + "]";
if(log.isDebugEnabled()){
log.debug(errorMsg);
}
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
}
}
return clientPublicKey;
}
public static boolean publishToDAS(String deviceId, float temperature) {
EventsPublisherService deviceAnalyticsService =
VirtualFirealarmManagementDataHolder.getInstance().getEventsPublisherService();
if (deviceAnalyticsService != null) {
String owner = "";
Object metdaData[] = {owner, VirtualFireAlarmConstants.DEVICE_TYPE, deviceId, System.currentTimeMillis()};
Object payloadData[] = {temperature};
try {
deviceAnalyticsService.publishEvent(VirtualFireAlarmConstants.TEMPERATURE_STREAM_DEFINITION,
"1.0.0", metdaData, new Object[0], payloadData);
} catch (DataPublisherConfigurationException e) {
return false;
}
return true;
}
return false;
}
public static void setupXmppInputAdapter() throws IOException {
if (!XmppConfig.getInstance().isEnabled()) return;
InputEventAdapterConfiguration inputEventAdapterConfiguration =
createXmppInputEventAdapterConfiguration(VirtualFireAlarmConstants.XMPP_ADAPTER_NAME,
VirtualFireAlarmConstants.XMPP_ADAPTER_TYPE, MessageType.TEXT);
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
VirtualFireAlarmConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true);
VirtualFirealarmManagementDataHolder.getInstance().getInputEventAdapterService()
.create(inputEventAdapterConfiguration, new VirtualFirealarmEventAdapterSubscription());
} catch (InputEventAdapterException e) {
log.error("Unable to create Input Event Adapter : " + VirtualFireAlarmConstants.MQTT_ADAPTER_NAME, e);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
/**
* Create Input Event Adapter Configuration for given configuration.
*
* @param name Input Event Adapter name
* @param type Input Event Adapter type
* @param msgFormat Input Event Adapter message format
* @return InputEventAdapterConfiguration instance for given configuration
*/
private static InputEventAdapterConfiguration createXmppInputEventAdapterConfiguration(String name, String type,
String msgFormat) throws IOException {
InputEventAdapterConfiguration inputEventAdapterConfiguration = new InputEventAdapterConfiguration();
inputEventAdapterConfiguration.setName(name);
inputEventAdapterConfiguration.setType(type);
inputEventAdapterConfiguration.setMessageFormat(msgFormat);
Map<String, String> xmppAdapterProperties = new HashMap<>();
XmppConfig xmppConfig = XmppConfig.getInstance();
xmppAdapterProperties.put(VirtualFireAlarmConstants.HOST_KEY, xmppConfig.getXmppServerIP());
xmppAdapterProperties.put(VirtualFireAlarmConstants.PORT_KEY, String.valueOf(xmppConfig.getXmppServerPort()));
xmppAdapterProperties.put(VirtualFireAlarmConstants.USERNAME_PROPERTY_KEY, xmppConfig.getVirtualFirealarmAdminUsername());
xmppAdapterProperties.put(VirtualFireAlarmConstants.PASSWORD_PROPERTY_KEY, xmppConfig.getVirtualFirealarmAdminPassword());
xmppAdapterProperties.put(VirtualFireAlarmConstants.JID_PROPERTY_KEY, xmppConfig.getVirtualFirealarmAdminJID());
xmppAdapterProperties.put(VirtualFireAlarmConstants.CONTENT_TRANSFORMATION,
VirtualFirealarmXmppContentTransformer.class.getName());
xmppAdapterProperties.put(VirtualFireAlarmConstants.CONTENT_VALIDATION, "default");
inputEventAdapterConfiguration.setProperties(xmppAdapterProperties);
return inputEventAdapterConfiguration;
}
public static void setupXmppOutputAdapter() throws IOException {
if(!XmppConfig.getInstance().isEnabled()) return;
OutputEventAdapterConfiguration outputEventAdapterConfiguration =
createXmppOutputEventAdapterConfiguration(VirtualFireAlarmConstants.XMPP_ADAPTER_NAME,
VirtualFireAlarmConstants.XMPP_ADAPTER_TYPE, MessageType.TEXT);
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
VirtualFireAlarmConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true);
VirtualFirealarmManagementDataHolder.getInstance().getOutputEventAdapterService()
.create(outputEventAdapterConfiguration);
} catch (OutputEventAdapterException e) {
log.error("Unable to create Output Event Adapter : " + VirtualFireAlarmConstants.MQTT_ADAPTER_NAME, e);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
private static OutputEventAdapterConfiguration createXmppOutputEventAdapterConfiguration(String name, String type,
String msgFormat) throws IOException {
OutputEventAdapterConfiguration outputEventAdapterConfiguration = new OutputEventAdapterConfiguration();
outputEventAdapterConfiguration.setName(name);
outputEventAdapterConfiguration.setType(type);
outputEventAdapterConfiguration.setMessageFormat(msgFormat);
Map<String, String> xmppAdapterProperties = new HashMap<>();
XmppConfig xmppConfig = XmppConfig.getInstance();
xmppAdapterProperties.put(VirtualFireAlarmConstants.HOST_KEY, xmppConfig.getXmppServerIP());
xmppAdapterProperties.put(VirtualFireAlarmConstants.PORT_KEY, String.valueOf(xmppConfig.getXmppServerPort()));
xmppAdapterProperties.put(VirtualFireAlarmConstants.USERNAME_PROPERTY_KEY, xmppConfig.getVirtualFirealarmAdminUsername());
xmppAdapterProperties.put(VirtualFireAlarmConstants.PASSWORD_PROPERTY_KEY, xmppConfig.getVirtualFirealarmAdminPassword());
xmppAdapterProperties.put(VirtualFireAlarmConstants.JID_PROPERTY_KEY, xmppConfig.getVirtualFirealarmAdminJID());
outputEventAdapterConfiguration.setStaticProperties(xmppAdapterProperties);
return outputEventAdapterConfiguration;
}
} }

View File

@ -0,0 +1,20 @@
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util;
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterSubscription;
public class VirtualFirealarmEventAdapterSubscription implements InputEventAdapterSubscription {
@Override
public void onEvent(Object o) {
String msg = (String) o;
if (msg != null && !msg.isEmpty()) {
String[] messages = (msg).split(",");
String deviceId = messages[0];
String actualMessage = messages[1];
if (actualMessage.contains("PUBLISHER")) {
float temperature = Float.parseFloat(actualMessage.split(":")[2]);
VirtualFireAlarmUtils.publishToDAS(deviceId, temperature);
}
}
}
}

View File

@ -0,0 +1,39 @@
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util;
import org.json.JSONObject;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentTransformer;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException;
import java.security.PublicKey;
import java.util.Map;
public class VirtualFirealarmMqttContentTransformer implements ContentTransformer {
@Override
public Object transform(Object message, Map<String, String> dynamicProperties) {
String topic = dynamicProperties.get("topic");
String[] topicParams = topic.split("/");
String tenantDomain = topicParams[0];
String deviceId = topicParams[2];
JSONObject jsonPayload = new JSONObject((String) message);
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
ctx.setTenantDomain(tenantDomain, true);
Long serialNo = (Long) jsonPayload.get(VirtualFireAlarmConstants.JSON_SERIAL_KEY);
// the hash-code of the deviceId is used as the alias for device certificates during SCEP enrollment.
// hence, the same is used here to fetch the device-specific-certificate from the key store.
PublicKey clientPublicKey = VirtualFireAlarmUtils.getDevicePublicKey("" + serialNo);
// the MQTT-messages from VirtualFireAlarm devices are in the form {"Msg":<MESSAGE>, "Sig":<SIGNATURE>}
String actualMessage = VirtualFireAlarmUtils.extractMessageFromPayload((String) message, clientPublicKey);
return deviceId + "," + actualMessage;
} catch (VirtualFirealarmDeviceMgtPluginException e) {
return "";
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
}

View File

@ -16,14 +16,14 @@
* under the License. * under the License.
*/ */
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util; package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException; import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException;
import org.wso2.carbon.certificate.mgt.core.util.ConfigurationUtil; import org.wso2.carbon.certificate.mgt.core.util.ConfigurationUtil;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException;
import javax.crypto.BadPaddingException; import javax.crypto.BadPaddingException;
import javax.crypto.Cipher; import javax.crypto.Cipher;
@ -47,18 +47,18 @@ import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
public class SecurityManager { public class VirtualFirealarmSecurityManager {
private static final Log log = LogFactory.getLog(SecurityManager.class); private static final Log log = LogFactory.getLog(VirtualFirealarmSecurityManager.class);
private static PrivateKey serverPrivateKey; private static PrivateKey serverPrivateKey;
private static final String SIGNATURE_ALG = "SHA1withRSA"; private static final String SIGNATURE_ALG = "SHA1withRSA";
private static final String CIPHER_PADDING = "RSA/ECB/PKCS1Padding"; private static final String CIPHER_PADDING = "RSA/ECB/PKCS1Padding";
private SecurityManager() { private VirtualFirealarmSecurityManager() {
} }
public void initVerificationManager() { public static void initVerificationManager() {
serverPrivateKey = retrievePrivateKey(ConfigurationUtil.CA_CERT_ALIAS, serverPrivateKey = retrievePrivateKey(ConfigurationUtil.CA_CERT_ALIAS,
ConfigurationUtil.KEYSTORE_CA_CERT_PRIV_PASSWORD); ConfigurationUtil.KEYSTORE_CA_CERT_PRIV_PASSWORD);
} }
@ -117,7 +117,8 @@ public class SecurityManager {
return serverPrivateKey; return serverPrivateKey;
} }
public static String encryptMessage(String message, Key encryptionKey) throws VirtualFireAlarmException { public static String encryptMessage(String message, Key encryptionKey) throws
VirtualFirealarmDeviceMgtPluginException {
Cipher encrypter; Cipher encrypter;
byte[] cipherData; byte[] cipherData;
@ -129,30 +130,29 @@ public class SecurityManager {
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
String errorMsg = "Algorithm not found exception occurred for Cipher instance of [" + CIPHER_PADDING + "]"; String errorMsg = "Algorithm not found exception occurred for Cipher instance of [" + CIPHER_PADDING + "]";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFireAlarmException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (NoSuchPaddingException e) { } catch (NoSuchPaddingException e) {
String errorMsg = "No Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]"; String errorMsg = "No Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFireAlarmException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (InvalidKeyException e) { } catch (InvalidKeyException e) {
String errorMsg = "InvalidKey exception occurred for encryptionKey \n[\n" + encryptionKey + "\n]\n"; String errorMsg = "InvalidKey exception occurred for encryptionKey \n[\n" + encryptionKey + "\n]\n";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFireAlarmException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (BadPaddingException e) { } catch (BadPaddingException e) {
String errorMsg = "Bad Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]"; String errorMsg = "Bad Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFireAlarmException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (IllegalBlockSizeException e) { } catch (IllegalBlockSizeException e) {
String errorMsg = "Illegal blockSize error occurred for Cipher instance of [" + CIPHER_PADDING + "]"; String errorMsg = "Illegal blockSize error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFireAlarmException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} }
return Base64.encodeBase64String(cipherData); return Base64.encodeBase64String(cipherData);
} }
public static String signMessage(String encryptedData, PrivateKey signatureKey) throws VirtualFirealarmDeviceMgtPluginException {
public static String signMessage(String encryptedData, PrivateKey signatureKey) throws VirtualFireAlarmException {
Signature signature; Signature signature;
String signedEncodedString; String signedEncodedString;
@ -168,23 +168,22 @@ public class SecurityManager {
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
String errorMsg = "Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; String errorMsg = "Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFireAlarmException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (SignatureException e) { } catch (SignatureException e) {
String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFireAlarmException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (InvalidKeyException e) { } catch (InvalidKeyException e) {
String errorMsg = "InvalidKey exception occurred for signatureKey \n[\n" + signatureKey + "\n]\n"; String errorMsg = "InvalidKey exception occurred for signatureKey \n[\n" + signatureKey + "\n]\n";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFireAlarmException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} }
return signedEncodedString; return signedEncodedString;
} }
public static boolean verifySignature(String data, String signedData, PublicKey verificationKey) public static boolean verifySignature(String data, String signedData, PublicKey verificationKey)
throws VirtualFireAlarmException { throws VirtualFirealarmDeviceMgtPluginException {
Signature signature; Signature signature;
boolean verified; boolean verified;
@ -199,22 +198,21 @@ public class SecurityManager {
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
String errorMsg = "Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; String errorMsg = "Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFireAlarmException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (SignatureException e) { } catch (SignatureException e) {
String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFireAlarmException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (InvalidKeyException e) { } catch (InvalidKeyException e) {
String errorMsg = "InvalidKey exception occurred for signatureKey \n[\n" + verificationKey + "\n]\n"; String errorMsg = "InvalidKey exception occurred for signatureKey \n[\n" + verificationKey + "\n]\n";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFireAlarmException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} }
return verified; return verified;
} }
public static String decryptMessage(String encryptedMessage, Key decryptKey) throws VirtualFirealarmDeviceMgtPluginException {
public static String decryptMessage(String encryptedMessage, Key decryptKey) throws VirtualFireAlarmException {
Cipher decrypter; Cipher decrypter;
String decryptedMessage; String decryptedMessage;
@ -228,23 +226,23 @@ public class SecurityManager {
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
String errorMsg = "Algorithm not found exception occurred for Cipher instance of [" + CIPHER_PADDING + "]"; String errorMsg = "Algorithm not found exception occurred for Cipher instance of [" + CIPHER_PADDING + "]";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFireAlarmException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (NoSuchPaddingException e) { } catch (NoSuchPaddingException e) {
String errorMsg = "No Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]"; String errorMsg = "No Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFireAlarmException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (InvalidKeyException e) { } catch (InvalidKeyException e) {
String errorMsg = "InvalidKey exception occurred for encryptionKey \n[\n" + decryptKey + "\n]\n"; String errorMsg = "InvalidKey exception occurred for encryptionKey \n[\n" + decryptKey + "\n]\n";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFireAlarmException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (BadPaddingException e) { } catch (BadPaddingException e) {
String errorMsg = "Bad Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]"; String errorMsg = "Bad Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFireAlarmException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (IllegalBlockSizeException e) { } catch (IllegalBlockSizeException e) {
String errorMsg = "Illegal blockSize error occurred for Cipher instance of [" + CIPHER_PADDING + "]"; String errorMsg = "Illegal blockSize error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFireAlarmException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} }
return decryptedMessage; return decryptedMessage;

View File

@ -21,6 +21,7 @@ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.core.ServerStartupObserver; import org.wso2.carbon.core.ServerStartupObserver;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppUtil;
import java.io.IOException; import java.io.IOException;
@ -34,7 +35,12 @@ public class VirtualFirealarmStartupListener implements ServerStartupObserver {
@Override @Override
public void completedServerStartup() { public void completedServerStartup() {
try { try {
VirtualFireAlarmUtils.setupOutputAdapter(); XmppUtil.createXMPPAccountForDeviceType();
VirtualFireAlarmUtils.setupMqttOutputAdapter();
VirtualFireAlarmUtils.setupMqttInputAdapter();
VirtualFireAlarmUtils.setupXmppInputAdapter();
VirtualFireAlarmUtils.setupXmppOutputAdapter();
} catch (IOException e) { } catch (IOException e) {
log.error("Failed to intilaize the virtual firealarm output adapter", e); log.error("Failed to intilaize the virtual firealarm output adapter", e);
} }

View File

@ -0,0 +1,46 @@
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util;
import org.json.JSONObject;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentTransformer;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException;
import java.security.PublicKey;
import java.util.Map;
public class VirtualFirealarmXmppContentTransformer implements ContentTransformer {
@Override
public Object transform(Object message, Map<String, String> dynamicProperties) {
String from = dynamicProperties.get("from");
String subject = dynamicProperties.get("subject");
int indexOfAt = from.indexOf("@");
int indexOfSlash = from.indexOf("/");
if (indexOfAt != -1 && indexOfSlash != -1) {
String deviceId = from.substring(0, indexOfAt);
JSONObject jsonPayload = new JSONObject((String) message);
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
ctx.setTenantDomain(subject, true);
Long serialNo = (Long) jsonPayload.get(VirtualFireAlarmConstants.JSON_SERIAL_KEY);
// the hash-code of the deviceId is used as the alias for device certificates during SCEP enrollment.
// hence, the same is used here to fetch the device-specific-certificate from the key store.
PublicKey clientPublicKey = VirtualFireAlarmUtils.getDevicePublicKey("" + serialNo);
// the MQTT-messages from VirtualFireAlarm devices are in the form {"Msg":<MESSAGE>, "Sig":<SIGNATURE>}
String actualMessage = VirtualFireAlarmUtils.extractMessageFromPayload((String) message,
clientPublicKey);
return deviceId + "," + actualMessage;
} catch (VirtualFirealarmDeviceMgtPluginException e) {
return "";
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
return "";
}
}

Some files were not shown because too many files have changed in this diff Show More