mirror of
https://repository.entgra.net/community/device-mgt-plugins.git
synced 2025-09-16 23:42:15 +00:00
added input and output adapters as transport
This commit is contained in:
parent
edaacd4989
commit
44fa7aa486
@ -19,9 +19,9 @@
|
||||
|
||||
<eventReceiver name="EventReceiver_AndroidSense" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver">
|
||||
<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="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="dcrUrl">https://${server.host}:${mgt.transport.https.port}/dynamic-client-web/register</property>
|
||||
<property name="url">tcp://${mqtt.broker.host}:${mqtt.broker.port}</property>
|
||||
|
||||
@ -55,8 +55,7 @@ public class ArduinoControllerServiceImpl implements ArduinoControllerService {
|
||||
public Response switchBulb(@PathParam("deviceId") String deviceId, @QueryParam("state") String state) {
|
||||
try {
|
||||
if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(new DeviceIdentifier(deviceId,
|
||||
ArduinoConstants.DEVICE_TYPE),
|
||||
DeviceGroupConstants.Permissions.DEFAULT_OPERATOR_PERMISSIONS)) {
|
||||
ArduinoConstants.DEVICE_TYPE), DeviceGroupConstants.Permissions.DEFAULT_OPERATOR_PERMISSIONS)) {
|
||||
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
|
||||
}
|
||||
LinkedList<String> deviceControlList = internalControlsQueue.get(deviceId);
|
||||
|
||||
@ -19,9 +19,9 @@
|
||||
|
||||
<eventReceiver name="temperature-mqtt" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver">
|
||||
<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="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="dcrUrl">https://${server.host}:${mgt.transport.https.port}/dynamic-client-web/register</property>
|
||||
<property name="clientId">temperatureMqttClient</property>
|
||||
|
||||
@ -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>
|
||||
@ -16,7 +16,7 @@
|
||||
* 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.
|
||||
@ -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
|
||||
* return it.
|
||||
*/
|
||||
private String msgText;
|
||||
private Object message;
|
||||
|
||||
public ContentInfo(boolean isValidContent, String msgText) {
|
||||
public ContentInfo(boolean isValidContent, Object message) {
|
||||
this.isValidContent = isValidContent;
|
||||
this.msgText = msgText;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public boolean isValidContent() {
|
||||
@ -45,11 +45,11 @@ public class ContentInfo {
|
||||
this.isValidContent = isValidContent;
|
||||
}
|
||||
|
||||
public String getMsgText() {
|
||||
return msgText;
|
||||
public Object getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMsgText(String msgText) {
|
||||
this.msgText = msgText;
|
||||
public void setMessage(Object message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
@ -16,7 +16,7 @@
|
||||
* 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;
|
||||
|
||||
@ -29,5 +29,5 @@ public interface ContentValidator {
|
||||
* @param dynamicParameter that message.
|
||||
* @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);
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -8,7 +8,7 @@ import java.util.Map;
|
||||
public class DefaultContentTransformer implements ContentTransformer{
|
||||
|
||||
@Override
|
||||
public String transform(String message, Map<String, String> dynamicProperties) {
|
||||
public Object transform(Object message, Map<String, String> dynamicProperties) {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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>
|
||||
@ -20,7 +20,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.osgi.service.http.HttpService;
|
||||
import org.osgi.service.http.NamespaceException;
|
||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.internal.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.InputEventAdapterConfiguration;
|
||||
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener;
|
||||
@ -14,9 +14,6 @@
|
||||
*/
|
||||
package org.wso2.carbon.device.mgt.iot.input.adapter.http;
|
||||
|
||||
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.Constants;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.util.MQTTEventAdapterConstants;
|
||||
import org.wso2.carbon.event.input.adapter.core.InputEventAdapter;
|
||||
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration;
|
||||
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterFactory;
|
||||
@ -40,10 +37,9 @@ public class HTTPEventAdapterFactory extends InputEventAdapterFactory {
|
||||
ResourceBundle.getBundle("org.wso2.carbon.device.mgt.iot.input.adapter.http.i18n.Resources", Locale.getDefault());
|
||||
private int httpPort;
|
||||
private int httpsPort;
|
||||
private int portOffset;
|
||||
|
||||
public HTTPEventAdapterFactory() {
|
||||
portOffset = getPortOffset();
|
||||
int portOffset = getPortOffset();
|
||||
httpPort = HTTPEventAdapterConstants.DEFAULT_HTTP_PORT + portOffset;
|
||||
httpsPort = HTTPEventAdapterConstants.DEFAULT_HTTPS_PORT + portOffset;
|
||||
}
|
||||
@ -55,7 +51,7 @@ public class HTTPEventAdapterFactory extends InputEventAdapterFactory {
|
||||
|
||||
@Override
|
||||
public List<String> getSupportedMessageFormats() {
|
||||
List<String> supportInputMessageTypes = new ArrayList<String>();
|
||||
List<String> supportInputMessageTypes = new ArrayList<>();
|
||||
supportInputMessageTypes.add(MessageType.JSON);
|
||||
supportInputMessageTypes.add(MessageType.TEXT);
|
||||
supportInputMessageTypes.add(MessageType.XML);
|
||||
@ -66,7 +62,7 @@ public class HTTPEventAdapterFactory extends InputEventAdapterFactory {
|
||||
@Override
|
||||
public List<Property> getPropertyList() {
|
||||
|
||||
List<Property> propertyList = new ArrayList<Property>();
|
||||
List<Property> propertyList = new ArrayList<>();
|
||||
|
||||
// Transport Exposed
|
||||
Property exposedTransportsProperty = new Property(HTTPEventAdapterConstants.EXPOSED_TRANSPORTS);
|
||||
@ -135,7 +131,7 @@ public class HTTPEventAdapterFactory extends InputEventAdapterFactory {
|
||||
contentValidatorParams.setRequired(false);
|
||||
contentValidatorParams.setHint(
|
||||
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);
|
||||
|
||||
//Content Transformer details
|
||||
@ -145,7 +141,7 @@ public class HTTPEventAdapterFactory extends InputEventAdapterFactory {
|
||||
contentTransformer.setRequired(false);
|
||||
contentTransformer.setHint(
|
||||
resourceBundle.getString(HTTPEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT));
|
||||
contentTransformer.setDefaultValue(Constants.DEFAULT);
|
||||
contentTransformer.setDefaultValue(HTTPEventAdapterConstants.DEFAULT);
|
||||
propertyList.add(contentTransformer);
|
||||
return propertyList;
|
||||
}
|
||||
@ -15,33 +15,21 @@
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.input.adapter.http;
|
||||
|
||||
import org.apache.axis2.context.ServiceContext;
|
||||
import org.apache.axis2.transport.http.HTTPConstants;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.commons.pool.impl.GenericObjectPool;
|
||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentInfo;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentTransformer;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.DefaultContentTransformer;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.DefaultContentValidator;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentInfo;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentTransformer;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.DefaultContentTransformer;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.DefaultContentValidator;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.http.exception.HTTPContentInitializationException;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.http.jwt.JWTAuthenticator;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.http.oauth.OAuthAuthenticator;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.http.oauth.OAuthTokenValidaterStubFactory;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.http.util.AuthenticationInfo;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.http.util.HTTPEventAdapterConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.internal.InputAdapterServiceDataHolder;
|
||||
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration;
|
||||
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentValidator;
|
||||
import org.wso2.carbon.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 org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentValidator;
|
||||
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@ -49,12 +37,9 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* This will act as the event reciver.
|
||||
@ -206,11 +191,11 @@ public class HTTPMessageServlet extends HttpServlet {
|
||||
paramMap.put(HTTPEventAdapterConstants.USERNAME_TAG, authenticationInfo.getUsername());
|
||||
paramMap.put(HTTPEventAdapterConstants.TENANT_DOMAIN_TAG, authenticationInfo.getTenantDomain());
|
||||
if (contentValidator != null && contentTransformer != null) {
|
||||
data = contentTransformer.transform(data, paramMap);
|
||||
data = (String) contentTransformer.transform(data, paramMap);
|
||||
ContentInfo contentInfo = contentValidator.validate(data, contentValidationProperties, paramMap);
|
||||
if (contentInfo != null && contentInfo.isValidContent()) {
|
||||
HTTPEventAdapter.executorService.submit(new HTTPRequestProcessor(eventAdaptorListener,
|
||||
contentInfo.getMsgText(), tenantId));
|
||||
(String) contentInfo.getMessage(), tenantId));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -237,11 +222,11 @@ public class HTTPMessageServlet extends HttpServlet {
|
||||
public void run() {
|
||||
try {
|
||||
PrivilegedCarbonContext.startTenantFlow();
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId);
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Event received in HTTP Event Adapter - " + payload);
|
||||
}
|
||||
if (payload.trim() != null) {
|
||||
if (payload != null) {
|
||||
inputEventAdapterListener.onEvent(payload);
|
||||
} else {
|
||||
log.warn("Dropping the empty/null event received through http adapter");
|
||||
@ -15,24 +15,18 @@
|
||||
* 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.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.osgi.service.component.ComponentContext;
|
||||
import org.osgi.service.http.HttpService;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.http.HTTPEventAdapterFactory;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.MQTTEventAdapterFactory;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.XMPPEventAdapterFactory;
|
||||
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterFactory;
|
||||
import org.wso2.carbon.user.core.service.RealmService;
|
||||
|
||||
/**
|
||||
* @scr.component component.name="input.iot.Mqtt.AdapterService.component" immediate="true"
|
||||
*/
|
||||
|
||||
/**
|
||||
* @scr.component name="org.wso2.carbon.event.input.adapter.extension.InputAdapterServiceComponent" immediate="true"
|
||||
* @scr.component name="input.iot.http.AdapterService.component" immediate="true"
|
||||
* @scr.reference name="user.realmservice.default"
|
||||
* interface="org.wso2.carbon.user.core.service.RealmService" cardinality="1..1"
|
||||
* policy="dynamic" bind="setRealmService" unbind="unsetRealmService"
|
||||
@ -41,19 +35,14 @@ import org.wso2.carbon.user.core.service.RealmService;
|
||||
*/
|
||||
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) {
|
||||
try {
|
||||
InputEventAdapterFactory mqttEventAdapterFactory = new MQTTEventAdapterFactory();
|
||||
context.getBundleContext().registerService(InputEventAdapterFactory.class.getName(),
|
||||
mqttEventAdapterFactory, null);
|
||||
InputEventAdapterFactory httpEventEventAdapterFactory = new HTTPEventAdapterFactory();
|
||||
context.getBundleContext().registerService(InputEventAdapterFactory.class.getName(),
|
||||
httpEventEventAdapterFactory, null);
|
||||
InputEventAdapterFactory xmppEventEventAdapterFactory = new XMPPEventAdapterFactory();
|
||||
context.getBundleContext().registerService(InputEventAdapterFactory.class.getName(),
|
||||
xmppEventEventAdapterFactory, null);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Successfully deployed the input adapter service");
|
||||
}
|
||||
@ -12,7 +12,7 @@
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
package org.wso2.carbon.device.mgt.iot.input.adapter.internal;
|
||||
package org.wso2.carbon.device.mgt.iot.input.adapter.http.internal;
|
||||
|
||||
import org.osgi.service.http.HttpService;
|
||||
import org.wso2.carbon.user.core.service.RealmService;
|
||||
@ -27,8 +27,8 @@ import org.apache.axis2.transport.http.HTTPConstants;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.core.util.KeyStoreManager;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.http.internal.InputAdapterServiceDataHolder;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.http.util.AuthenticationInfo;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.internal.InputAdapterServiceDataHolder;
|
||||
import org.wso2.carbon.user.api.TenantManager;
|
||||
import org.wso2.carbon.user.api.UserStoreException;
|
||||
import org.wso2.carbon.user.api.UserStoreManager;
|
||||
@ -23,8 +23,8 @@ import org.apache.axis2.transport.http.HTTPConstants;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.commons.pool.impl.GenericObjectPool;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.http.internal.InputAdapterServiceDataHolder;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.http.util.AuthenticationInfo;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.internal.InputAdapterServiceDataHolder;
|
||||
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration;
|
||||
import org.wso2.carbon.identity.oauth2.stub.OAuth2TokenValidationServiceStub;
|
||||
import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationRequestDTO;
|
||||
@ -24,8 +24,8 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentInfo;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentValidator;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentInfo;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentValidator;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@ -34,10 +34,10 @@ public class HTTPContentValidator implements ContentValidator {
|
||||
private static String JSON_ARRAY_START_CHAR = "[";
|
||||
|
||||
@Override
|
||||
public ContentInfo validate(String msgPayload, Map<String, String> contentValidationParams,
|
||||
public ContentInfo validate(Object msgPayload, Map<String, String> contentValidationParams,
|
||||
Map<String, String> dynamicParams) {
|
||||
String deviceId = dynamicParams.get("deviceId");
|
||||
String msg = msgPayload;
|
||||
String msg = (String) msgPayload;
|
||||
String deviceIdJsonPath = contentValidationParams.get(HTTPEventAdapterConstants.DEVICE_ID_JSON_PATH);
|
||||
boolean status;
|
||||
if (msg.startsWith(JSON_ARRAY_START_CHAR)) {
|
||||
@ -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_HINT = "contentValidationParams.hint";
|
||||
public static final String DEFAULT = "default";
|
||||
public static final String MQTT_CONTENT_VALIDATION_DEFAULT_PARAMETERS =
|
||||
"device_id_json_path:meta_deviceId";
|
||||
public static final String HTTP_CONTENT_VALIDATION_DEFAULT_PARAMETERS = "";
|
||||
public static final String ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME = "contentTransformer";
|
||||
public static final String ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT = "contentTransformer.hint";
|
||||
}
|
||||
@ -25,9 +25,9 @@
|
||||
</parent>
|
||||
<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>
|
||||
<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>
|
||||
<url>http://wso2.org</url>
|
||||
|
||||
@ -73,12 +73,8 @@
|
||||
<artifactId>org.wso2.carbon.identity.oauth.stub</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.igniterealtime.smack.wso2</groupId>
|
||||
<artifactId>smack</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.igniterealtime.smack.wso2</groupId>
|
||||
<artifactId>smackx</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
|
||||
<artifactId>org.wso2.carbon.device.mgt.iot.input.adapter.extension</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@ -109,13 +105,13 @@
|
||||
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||
<Bundle-Name>${project.artifactId}</Bundle-Name>
|
||||
<Private-Package>
|
||||
org.wso2.carbon.device.mgt.iot.input.adapter.internal,
|
||||
org.wso2.carbon.device.mgt.iot.input.adapter.internal.*
|
||||
org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.internal,
|
||||
org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.internal.*
|
||||
</Private-Package>
|
||||
<Export-Package>
|
||||
!org.wso2.carbon.device.mgt.iot.input.adapter.internal,
|
||||
!org.wso2.carbon.device.mgt.iot.input.adapter.internal.*,
|
||||
org.wso2.carbon.device.mgt.iot.input.adapter.*
|
||||
!org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.internal,
|
||||
!org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.internal.*,
|
||||
org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.*
|
||||
</Export-Package>
|
||||
<Import-Package>
|
||||
org.wso2.carbon.event.input.adapter.core,
|
||||
@ -133,39 +129,7 @@
|
||||
org.apache.http.impl.client;version="${httpclient.version.range}",
|
||||
org.json.simple.*,
|
||||
org.wso2.carbon.identity.jwt.client.extension.*,
|
||||
com.jayway.jsonpath.*,
|
||||
javax.net.ssl,
|
||||
org.apache.commons.logging,
|
||||
org.apache.http.entity,
|
||||
org.osgi.framework,
|
||||
org.osgi.service.component,
|
||||
org.wso2.carbon.context,
|
||||
org.wso2.carbon.core,
|
||||
javax.servlet,
|
||||
javax.servlet.http,
|
||||
org.apache.axiom.om.util,
|
||||
org.osgi.service.http,
|
||||
org.wso2.carbon.user.api,
|
||||
org.wso2.carbon.user.core.service,
|
||||
org.wso2.carbon.user.core.tenant,
|
||||
org.wso2.carbon.utils,
|
||||
org.wso2.carbon.utils.multitenancy,
|
||||
org.wso2.carbon.identity.oauth2.stub;version="${carbon.identity.version.range}",
|
||||
org.wso2.carbon.identity.oauth2.stub.dto;version="${carbon.identity.version.range}",
|
||||
org.apache.axis2,
|
||||
org.apache.axis2.client,
|
||||
org.apache.axis2.context,
|
||||
org.apache.axis2.transport.http,
|
||||
org.apache.commons.httpclient,
|
||||
org.apache.commons.httpclient.contrib.ssl,
|
||||
org.apache.commons.httpclient.params,
|
||||
org.apache.commons.httpclient.protocol,
|
||||
org.apache.commons.pool,
|
||||
org.apache.commons.pool.impl,
|
||||
org.jivesoftware.smack.*,
|
||||
org.apache.log4j,
|
||||
org.wso2.carbon.base,
|
||||
org.wso2.carbon.core.util
|
||||
com.jayway.jsonpath.*
|
||||
</Import-Package>
|
||||
<DynamicImport-Package>*</DynamicImport-Package>
|
||||
</instructions>
|
||||
@ -63,8 +63,9 @@ public class MQTTEventAdapter implements InputEventAdapter {
|
||||
keepAlive = MQTTEventAdapterConstants.ADAPTER_CONF_DEFAULT_KEEP_ALIVE;
|
||||
}
|
||||
String contentValidationParams = eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS);
|
||||
String params[] = contentValidationParams.split(",");
|
||||
Map<String, String> paramsMap = new HashMap<>();
|
||||
if (contentValidationParams != null && !contentValidationParams.isEmpty()) {
|
||||
String params[] = contentValidationParams.split(",");
|
||||
for (String param : params) {
|
||||
String paramsKeyAndValue[] = splitOnFirst(param, ':');
|
||||
if (paramsKeyAndValue.length != 2) {
|
||||
@ -72,7 +73,7 @@ public class MQTTEventAdapter implements InputEventAdapter {
|
||||
}
|
||||
paramsMap.put(paramsKeyAndValue[0], paramsKeyAndValue[1]);
|
||||
}
|
||||
|
||||
}
|
||||
mqttBrokerConnectionConfiguration = new MQTTBrokerConnectionConfiguration(
|
||||
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_URL),
|
||||
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_USERNAME),
|
||||
@ -82,7 +83,7 @@ public class MQTTEventAdapter implements InputEventAdapter {
|
||||
keepAlive,
|
||||
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME),
|
||||
paramsMap,
|
||||
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME)
|
||||
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME)
|
||||
);
|
||||
mqttAdapterListener = new MQTTAdapterListener(mqttBrokerConnectionConfiguration,
|
||||
eventAdapterConfiguration.getProperties().get(MQTTEventAdapterConstants.ADAPTER_MESSAGE_TOPIC),
|
||||
@ -17,7 +17,6 @@
|
||||
*/
|
||||
package org.wso2.carbon.device.mgt.iot.input.adapter.mqtt;
|
||||
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.util.XMPPEventAdapterConstants;
|
||||
import org.wso2.carbon.event.input.adapter.core.*;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.util.MQTTEventAdapterConstants;
|
||||
|
||||
@ -78,7 +77,7 @@ public class MQTTEventAdapterFactory extends InputEventAdapterFactory {
|
||||
contentValidator.setRequired(false);
|
||||
contentValidator.setHint(
|
||||
resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT));
|
||||
contentValidator.setDefaultValue(Constants.DEFAULT);
|
||||
contentValidator.setDefaultValue(MQTTEventAdapterConstants.DEFAULT);
|
||||
propertyList.add(contentValidator);
|
||||
|
||||
//Content Validator Params details
|
||||
@ -88,7 +87,7 @@ public class MQTTEventAdapterFactory extends InputEventAdapterFactory {
|
||||
contentValidatorParams.setRequired(false);
|
||||
contentValidatorParams.setHint(
|
||||
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);
|
||||
|
||||
//Broker Username
|
||||
@ -123,7 +122,7 @@ public class MQTTEventAdapterFactory extends InputEventAdapterFactory {
|
||||
contentTransformer.setRequired(false);
|
||||
contentTransformer.setHint(
|
||||
resourceBundle.getString(MQTTEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT));
|
||||
contentTransformer.setDefaultValue(Constants.DEFAULT);
|
||||
contentTransformer.setDefaultValue(MQTTEventAdapterConstants.DEFAULT);
|
||||
propertyList.add(contentTransformer);
|
||||
|
||||
// set clientId
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -31,14 +31,13 @@ import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
import org.wso2.carbon.core.ServerStatus;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentInfo;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentTransformer;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.DefaultContentTransformer;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.DefaultContentValidator;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentInfo;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentTransformer;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentValidator;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.DefaultContentTransformer;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.DefaultContentValidator;
|
||||
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener;
|
||||
import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterRuntimeException;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentValidator;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.Constants;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.exception.MQTTContentInitializationException;
|
||||
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
|
||||
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
|
||||
@ -59,10 +58,8 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
|
||||
private MqttClient mqttClient;
|
||||
private MqttConnectOptions connectionOptions;
|
||||
private boolean cleanSession;
|
||||
private int keepAlive;
|
||||
|
||||
private MQTTBrokerConnectionConfiguration mqttBrokerConnectionConfiguration;
|
||||
private String mqttClientId;
|
||||
private String topic;
|
||||
private int tenantId;
|
||||
private boolean connectionSucceeded = false;
|
||||
@ -80,11 +77,9 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
|
||||
if(mqttClientId == null || mqttClientId.trim().isEmpty()){
|
||||
mqttClientId = MqttClient.generateClientId();
|
||||
}
|
||||
|
||||
this.mqttClientId = mqttClientId;
|
||||
this.mqttBrokerConnectionConfiguration = mqttBrokerConnectionConfiguration;
|
||||
this.cleanSession = mqttBrokerConnectionConfiguration.isCleanSession();
|
||||
this.keepAlive = mqttBrokerConnectionConfiguration.getKeepAlive();
|
||||
int keepAlive = mqttBrokerConnectionConfiguration.getKeepAlive();
|
||||
this.topic = topic;
|
||||
this.eventAdapterListener = inputEventAdapterListener;
|
||||
this.tenantId = tenantId;
|
||||
@ -95,21 +90,19 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
|
||||
|
||||
|
||||
try {
|
||||
// Construct the connection options object that contains connection parameters
|
||||
// such as cleanSession and LWT
|
||||
connectionOptions = new MqttConnectOptions();
|
||||
connectionOptions.setCleanSession(cleanSession);
|
||||
connectionOptions.setKeepAliveInterval(keepAlive);
|
||||
|
||||
// Construct an MQTT blocking mode client
|
||||
mqttClient = new MqttClient(this.mqttBrokerConnectionConfiguration.getBrokerUrl(), this.mqttClientId,
|
||||
mqttClient = new MqttClient(this.mqttBrokerConnectionConfiguration.getBrokerUrl(), mqttClientId,
|
||||
dataStore);
|
||||
|
||||
// Set this wrapper as the callback handler
|
||||
mqttClient.setCallback(this);
|
||||
String contentValidatorClassName = this.mqttBrokerConnectionConfiguration.getContentValidatorClassName();
|
||||
|
||||
if (contentValidatorClassName != null && contentValidatorClassName.equals(Constants.DEFAULT)) {
|
||||
if (contentValidatorClassName != null && contentValidatorClassName.equals(MQTTEventAdapterConstants.DEFAULT)) {
|
||||
contentValidator = new DefaultContentValidator();
|
||||
} else if (contentValidatorClassName != null && !contentValidatorClassName.isEmpty()) {
|
||||
try {
|
||||
@ -130,7 +123,7 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
|
||||
contentValidationParams = mqttBrokerConnectionConfiguration.getContentValidatorParams();
|
||||
|
||||
String contentTransformerClassName = this.mqttBrokerConnectionConfiguration.getContentTransformerClassName();
|
||||
if (contentTransformerClassName != null && contentTransformerClassName.equals(Constants.DEFAULT)) {
|
||||
if (contentTransformerClassName != null && contentTransformerClassName.equals(MQTTEventAdapterConstants.DEFAULT)) {
|
||||
contentTransformer = new DefaultContentTransformer();
|
||||
} else if (contentTransformerClassName != null && !contentTransformerClassName.isEmpty()) {
|
||||
try {
|
||||
@ -151,16 +144,12 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
|
||||
log.error("Exception occurred while subscribing to MQTT broker at "
|
||||
+ mqttBrokerConnectionConfiguration.getBrokerUrl());
|
||||
throw new InputEventAdapterRuntimeException(e);
|
||||
} catch (Throwable e) {
|
||||
log.error("Exception occurred while subscribing to MQTT broker at "
|
||||
+ mqttBrokerConnectionConfiguration.getBrokerUrl());
|
||||
throw new InputEventAdapterRuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void startListener() throws MqttException {
|
||||
if (this.mqttBrokerConnectionConfiguration.getBrokerUsername() != null && this.mqttBrokerConnectionConfiguration.getDcrUrl() != null) {
|
||||
if (this.mqttBrokerConnectionConfiguration.getBrokerUsername() != null &&
|
||||
this.mqttBrokerConnectionConfiguration.getDcrUrl() != null) {
|
||||
String username = this.mqttBrokerConnectionConfiguration.getBrokerUsername();
|
||||
String dcrUrlString = this.mqttBrokerConnectionConfiguration.getDcrUrl();
|
||||
String scopes = this.mqttBrokerConnectionConfiguration.getBrokerScopes();
|
||||
@ -174,11 +163,11 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
|
||||
HttpClient httpClient = MQTTUtil.getHttpClient(dcrUrl.getProtocol());
|
||||
HttpPost postMethod = new HttpPost(dcrUrlString);
|
||||
RegistrationProfile registrationProfile = new RegistrationProfile();
|
||||
registrationProfile.setCallbackUrl(Constants.EMPTY_STRING);
|
||||
registrationProfile.setGrantType(Constants.GRANT_TYPE);
|
||||
registrationProfile.setCallbackUrl(MQTTEventAdapterConstants.EMPTY_STRING);
|
||||
registrationProfile.setGrantType(MQTTEventAdapterConstants.GRANT_TYPE);
|
||||
registrationProfile.setOwner(username);
|
||||
registrationProfile.setTokenScope(Constants.TOKEN_SCOPE);
|
||||
registrationProfile.setApplicationType(Constants.APPLICATION_TYPE);
|
||||
registrationProfile.setTokenScope(MQTTEventAdapterConstants.TOKEN_SCOPE);
|
||||
registrationProfile.setApplicationType(MQTTEventAdapterConstants.APPLICATION_TYPE);
|
||||
registrationProfile.setClientName(username + "_" + tenantId);
|
||||
String jsonString = registrationProfile.toJSON();
|
||||
StringEntity requestEntity = new StringEntity(jsonString, ContentType.APPLICATION_JSON);
|
||||
@ -188,8 +177,8 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
|
||||
try {
|
||||
JSONParser jsonParser = new JSONParser();
|
||||
JSONObject jsonPayload = (JSONObject) jsonParser.parse(response);
|
||||
String clientId = (String) jsonPayload.get(Constants.CLIENT_ID);
|
||||
String clientSecret = (String) jsonPayload.get(Constants.CLIENT_SECRET);
|
||||
String clientId = (String) jsonPayload.get(MQTTEventAdapterConstants.CLIENT_ID);
|
||||
String clientSecret = (String) jsonPayload.get(MQTTEventAdapterConstants.CLIENT_SECRET);
|
||||
JWTClientManagerService jwtClientManagerService = MQTTUtil.getJWTClientManagerService();
|
||||
AccessTokenInfo accessTokenInfo = jwtClientManagerService.getJWTClient().getAccessToken(
|
||||
clientId, clientSecret, username, scopes);
|
||||
@ -210,31 +199,22 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Connect to the MQTT server
|
||||
mqttClient.connect(connectionOptions);
|
||||
|
||||
// Subscribe to the requested topic
|
||||
// The QoS specified is the maximum level that messages will be sent to the client at.
|
||||
// For instance if QoS 1 is specified, any messages originally published at QoS 2 will
|
||||
// be downgraded to 1 when delivering to the client but messages published at 1 and 0
|
||||
// will be received at the same level they were published at.
|
||||
mqttClient.subscribe(topic);
|
||||
}
|
||||
|
||||
public void stopListener(String adapterName) {
|
||||
if (connectionSucceeded) {
|
||||
try {
|
||||
// Un-subscribe accordingly and disconnect from the MQTT server.
|
||||
if (!ServerStatus.getCurrentStatus().equals(ServerStatus.STATUS_SHUTTING_DOWN) || cleanSession) {
|
||||
mqttClient.unsubscribe(topic);
|
||||
}
|
||||
mqttClient.disconnect(3000);
|
||||
} catch (MqttException e) {
|
||||
log.error("Can not unsubscribe from the destination " + topic
|
||||
+ " with the event adapter " + adapterName, e);
|
||||
log.error("Can not unsubscribe from the destination " + topic +
|
||||
" with the event adapter " + adapterName, e);
|
||||
}
|
||||
}
|
||||
//This is to stop all running reconnection threads
|
||||
connectionSucceeded = true;
|
||||
}
|
||||
|
||||
@ -262,11 +242,11 @@ public class MQTTAdapterListener implements MqttCallback, Runnable {
|
||||
if (contentValidator != null && contentTransformer != null) {
|
||||
ContentInfo contentInfo;
|
||||
Map<String, String> dynamicProperties = new HashMap<>();
|
||||
dynamicProperties.put(Constants.TOPIC, topic);
|
||||
msgText = contentTransformer.transform(msgText, dynamicProperties);
|
||||
dynamicProperties.put(MQTTEventAdapterConstants.TOPIC, topic);
|
||||
msgText = (String) contentTransformer.transform(msgText, dynamicProperties);
|
||||
contentInfo = contentValidator.validate(msgText,contentValidationParams, dynamicProperties);
|
||||
if (contentInfo != null && contentInfo.isValidContent()) {
|
||||
eventAdapterListener.onEvent(contentInfo.getMsgText());
|
||||
eventAdapterListener.onEvent(contentInfo.getMessage());
|
||||
}
|
||||
} else {
|
||||
eventAdapterListener.onEvent(msgText);
|
||||
@ -17,9 +17,6 @@
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -41,23 +38,10 @@ public class MQTTBrokerConnectionConfiguration {
|
||||
return brokerScopes;
|
||||
}
|
||||
|
||||
public void setBrokerScopes(String brokerScopes) {
|
||||
this.brokerScopes = brokerScopes;
|
||||
}
|
||||
|
||||
public String getBrokerUsername() {
|
||||
return brokerUsername;
|
||||
}
|
||||
|
||||
public void setBrokerUsername(String brokerUsername) {
|
||||
this.brokerUsername = brokerUsername;
|
||||
}
|
||||
|
||||
public void setCleanSession(boolean cleanSession) {
|
||||
this.cleanSession = cleanSession;
|
||||
}
|
||||
|
||||
|
||||
public boolean isCleanSession() {
|
||||
return cleanSession;
|
||||
}
|
||||
@ -66,42 +50,22 @@ public class MQTTBrokerConnectionConfiguration {
|
||||
return brokerUrl;
|
||||
}
|
||||
|
||||
public void setBrokerUrl(String brokerUrl) {
|
||||
this.brokerUrl = brokerUrl;
|
||||
}
|
||||
|
||||
public String getDcrUrl() {
|
||||
return dcrUrl;
|
||||
}
|
||||
|
||||
public void setDcrUrl(String dcrUrl) {
|
||||
this.dcrUrl = dcrUrl;
|
||||
}
|
||||
|
||||
public int getKeepAlive() {
|
||||
return keepAlive;
|
||||
}
|
||||
|
||||
public void setKeepAlive(int keepAlive) {
|
||||
this.keepAlive = keepAlive;
|
||||
}
|
||||
|
||||
public String getContentValidatorClassName() {
|
||||
return contentValidatorClassName;
|
||||
}
|
||||
|
||||
public void setContentValidatorClassName(String contentValidatorClassName) {
|
||||
this.contentValidatorClassName = contentValidatorClassName;
|
||||
}
|
||||
|
||||
public Map<String, String> getContentValidatorParams() {
|
||||
return contentValidatorParams;
|
||||
}
|
||||
|
||||
public void setContentValidatorParams(Map<String, String> contentValidatorParams) {
|
||||
this.contentValidatorParams = contentValidatorParams;
|
||||
}
|
||||
|
||||
public String getContentTransformerClassName() {
|
||||
return contentTransformerClassName;
|
||||
}
|
||||
@ -113,7 +77,7 @@ public class MQTTBrokerConnectionConfiguration {
|
||||
this.brokerUsername = brokerUsername;
|
||||
this.brokerScopes = brokerScopes;
|
||||
if (brokerScopes == null) {
|
||||
this.brokerScopes = Constants.EMPTY_STRING;
|
||||
this.brokerScopes = MQTTEventAdapterConstants.EMPTY_STRING;
|
||||
}
|
||||
this.brokerUrl = PropertyUtils.replaceMqttProperty(brokerUrl);
|
||||
this.dcrUrl = PropertyUtils.replaceMqttProperty(dcrUrl);
|
||||
@ -125,7 +89,6 @@ public class MQTTBrokerConnectionConfiguration {
|
||||
if (contentValidatorParams != null) {
|
||||
this.contentValidatorParams = contentValidatorParams;
|
||||
}
|
||||
|
||||
this.contentTransformerClassName = contentTransformerClassName;
|
||||
}
|
||||
}
|
||||
@ -22,40 +22,38 @@ import com.jayway.jsonpath.JsonPath;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentInfo;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentValidator;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.Constants;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentInfo;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentValidator;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class MQTTContentValidator implements ContentValidator {
|
||||
private static String JSON_ARRAY_START_CHAR = "[";
|
||||
private static final String JSON_ARRAY_START_CHAR = "[";
|
||||
private static final Log log = LogFactory.getLog(MQTTContentValidator.class);
|
||||
|
||||
@Override
|
||||
public ContentInfo validate(String msgPayload, Map<String, String> contentValidationParams,
|
||||
public ContentInfo validate(Object msgPayload, Map<String, String> contentValidationParams,
|
||||
Map<String, String> dynamicParams) {
|
||||
String topic = dynamicParams.get(Constants.TOPIC);
|
||||
String topic = dynamicParams.get(MQTTEventAdapterConstants.TOPIC);
|
||||
String topics[] = topic.split("/");
|
||||
|
||||
String msg = msgPayload;
|
||||
String deviceIdJsonPath = contentValidationParams.get(Constants.DEVICE_ID_JSON_PATH);
|
||||
String deviceIdInTopicHierarchyLevel = contentValidationParams.get(Constants.DEVICE_ID_TOPIC_HIERARCHY_INDEX);
|
||||
String deviceIdJsonPath = contentValidationParams.get(MQTTEventAdapterConstants.DEVICE_ID_JSON_PATH);
|
||||
String deviceIdInTopicHierarchyLevel = contentValidationParams.get(
|
||||
MQTTEventAdapterConstants.DEVICE_ID_TOPIC_HIERARCHY_INDEX);
|
||||
int deviceIdInTopicHierarchyLevelIndex = 0;
|
||||
if (deviceIdInTopicHierarchyLevel != null && !deviceIdInTopicHierarchyLevel.isEmpty()) {
|
||||
deviceIdInTopicHierarchyLevelIndex = Integer.parseInt(deviceIdInTopicHierarchyLevel);
|
||||
}
|
||||
String deviceIdFromTopic = topics[deviceIdInTopicHierarchyLevelIndex];
|
||||
boolean status;
|
||||
if (msg.startsWith(JSON_ARRAY_START_CHAR)) {
|
||||
status = processMultipleEvents(msg, deviceIdFromTopic, deviceIdJsonPath);
|
||||
String message = (String) msgPayload;
|
||||
if (message.startsWith(JSON_ARRAY_START_CHAR)) {
|
||||
status = processMultipleEvents(message, deviceIdFromTopic, deviceIdJsonPath);
|
||||
} 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) {
|
||||
@ -75,7 +73,7 @@ public class MQTTContentValidator implements ContentValidator {
|
||||
for (int i = 0; i < jsonArray.size(); i++) {
|
||||
status = processSingleEvent(jsonArray.get(i).toString(), deviceIdFromTopic, deviceIdJsonPath);
|
||||
if (!status) {
|
||||
return status;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
@ -49,4 +49,18 @@ public class MQTTEventAdapterConstants {
|
||||
|
||||
public static int initialReconnectDuration = 10000;
|
||||
public static final int reconnectionProgressionFactor = 2;
|
||||
|
||||
public static final String EMPTY_STRING = "";
|
||||
public static final String GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer refresh_token";
|
||||
public static final String TOKEN_SCOPE = "production";
|
||||
public static final String APPLICATION_TYPE = "device";
|
||||
public static final String CLIENT_ID = "client_id";
|
||||
public static final String CLIENT_SECRET = "client_secret";
|
||||
public static final String CLIENT_NAME = "client_name";
|
||||
public static final String DEFAULT = "default";
|
||||
public static final String MQTT_CONTENT_VALIDATION_DEFAULT_PARAMETERS = "";
|
||||
public static final String TOPIC = "topic";
|
||||
public static final String PAYLOAD = "payload";
|
||||
public static final String DEVICE_ID_JSON_PATH = "device_id_json_path";
|
||||
public static final String DEVICE_ID_TOPIC_HIERARCHY_INDEX = "device_id_topic_hierarchy_index";
|
||||
}
|
||||
@ -16,7 +16,7 @@
|
||||
* 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.core.util.Utils;
|
||||
@ -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>
|
||||
@ -57,8 +57,9 @@ public class XMPPEventAdapter implements InputEventAdapter {
|
||||
|
||||
String contentValidationParams = eventAdapterConfiguration.getProperties().get(
|
||||
XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS);
|
||||
String params[] = contentValidationParams.split(",");
|
||||
Map<String, String> paramsMap = new HashMap<>();
|
||||
if (contentValidationParams != null && !contentValidationParams.isEmpty()) {
|
||||
String params[] = contentValidationParams.split(",");
|
||||
for (String param : params) {
|
||||
String paramsKeyAndValue[] = splitOnFirst(param, ':');
|
||||
if (paramsKeyAndValue.length != 2) {
|
||||
@ -66,7 +67,7 @@ public class XMPPEventAdapter implements InputEventAdapter {
|
||||
}
|
||||
paramsMap.put(paramsKeyAndValue[0], paramsKeyAndValue[1]);
|
||||
}
|
||||
|
||||
}
|
||||
int xmppPort = XMPPEventAdapterConstants.DEFAULT_XMPP_PORT;
|
||||
String xmppPortString = eventAdapterConfiguration.getProperties()
|
||||
.get(XMPPEventAdapterConstants.ADAPTER_CONF_PORT);
|
||||
@ -91,11 +92,12 @@ public class XMPPEventAdapter implements InputEventAdapter {
|
||||
.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME),
|
||||
paramsMap,
|
||||
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,
|
||||
eventAdapterListener, PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId());
|
||||
eventAdapterListener, PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true));
|
||||
|
||||
} catch (Throwable t) {
|
||||
throw new InputEventAdapterException(t.getMessage(), t);
|
||||
@ -89,7 +89,7 @@ public class XMPPEventAdapterFactory extends InputEventAdapterFactory {
|
||||
//Resource
|
||||
Property resource = new Property(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));
|
||||
|
||||
//Content Validator details
|
||||
@ -99,7 +99,7 @@ public class XMPPEventAdapterFactory extends InputEventAdapterFactory {
|
||||
contentValidator.setRequired(false);
|
||||
contentValidator.setHint(
|
||||
resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_CLASSNAME_HINT));
|
||||
contentValidator.setDefaultValue(org.wso2.carbon.device.mgt.iot.input.adapter.mqtt.Constants.DEFAULT);
|
||||
contentValidator.setDefaultValue(XMPPEventAdapterConstants.DEFAULT);
|
||||
|
||||
//Content Validator Params details
|
||||
Property contentValidatorParams = new Property(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_VALIDATOR_PARAMS);
|
||||
@ -108,7 +108,7 @@ public class XMPPEventAdapterFactory extends InputEventAdapterFactory {
|
||||
contentValidatorParams.setRequired(false);
|
||||
contentValidatorParams.setHint(
|
||||
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);
|
||||
jid.setDisplayName(resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_RECIEVER_JID));
|
||||
@ -122,7 +122,7 @@ public class XMPPEventAdapterFactory extends InputEventAdapterFactory {
|
||||
contentTransformer.setRequired(false);
|
||||
contentTransformer.setHint(
|
||||
resourceBundle.getString(XMPPEventAdapterConstants.ADAPTER_CONF_CONTENT_TRANSFORMER_CLASSNAME_HINT));
|
||||
contentTransformer.setDefaultValue(Constants.DEFAULT);
|
||||
contentTransformer.setDefaultValue(XMPPEventAdapterConstants.DEFAULT);
|
||||
|
||||
propertyList.add(host);
|
||||
propertyList.add(port);
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -32,12 +32,11 @@ import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
import org.wso2.carbon.core.ServerStatus;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentInfo;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentTransformer;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.ContentValidator;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.DefaultContentTransformer;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.DefaultContentValidator;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.Constants;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentInfo;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentTransformer;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentValidator;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.DefaultContentTransformer;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.extension.DefaultContentValidator;
|
||||
import org.wso2.carbon.device.mgt.iot.input.adapter.xmpp.exception.XMPPContentInitializationException;
|
||||
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterListener;
|
||||
import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterRuntimeException;
|
||||
@ -54,7 +53,6 @@ public class XMPPAdapterListener implements Runnable {
|
||||
private ContentValidator contentValidator;
|
||||
private Map<String, String> contentValidationParams;
|
||||
private ContentTransformer contentTransformer;
|
||||
private PacketFilter packetFilter;
|
||||
private PacketListener packetListener;
|
||||
|
||||
private InputEventAdapterListener eventAdapterListener = null;
|
||||
@ -68,7 +66,7 @@ public class XMPPAdapterListener implements Runnable {
|
||||
|
||||
try {
|
||||
String contentValidatorClassName = this.xmppServerConnectionConfiguration.getContentValidatorClassName();
|
||||
if (contentValidatorClassName != null && contentValidatorClassName.equals(Constants.DEFAULT)) {
|
||||
if (contentValidatorClassName != null && contentValidatorClassName.equals(XMPPEventAdapterConstants.DEFAULT)) {
|
||||
contentValidator = new DefaultContentValidator();
|
||||
} else if (contentValidatorClassName != null && !contentValidatorClassName.isEmpty()) {
|
||||
try {
|
||||
@ -88,7 +86,7 @@ public class XMPPAdapterListener implements Runnable {
|
||||
contentValidationParams = xmppServerConnectionConfiguration.getContentValidatorParams();
|
||||
|
||||
String contentTransformerClassName = this.xmppServerConnectionConfiguration.getContentTransformerClassName();
|
||||
if (contentTransformerClassName != null && contentTransformerClassName.equals(Constants.DEFAULT)) {
|
||||
if (contentTransformerClassName != null && contentTransformerClassName.equals(XMPPEventAdapterConstants.DEFAULT)) {
|
||||
contentTransformer = new DefaultContentTransformer();
|
||||
} else if (contentTransformerClassName != null && !contentTransformerClassName.isEmpty()) {
|
||||
try {
|
||||
@ -151,7 +149,7 @@ public class XMPPAdapterListener implements Runnable {
|
||||
}
|
||||
|
||||
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));
|
||||
packetListener = new PacketListener() {
|
||||
@Override
|
||||
@ -187,12 +185,12 @@ public class XMPPAdapterListener implements Runnable {
|
||||
|
||||
if (contentValidator != null && contentTransformer != null) {
|
||||
Map<String, String> dynamicParmaters = new HashMap<>();
|
||||
dynamicParmaters.put(Constants.FROM_KEY, from);
|
||||
dynamicParmaters.put(Constants.SUBJECT_KEY, subject);
|
||||
message = contentTransformer.transform(message, dynamicParmaters);
|
||||
dynamicParmaters.put(XMPPEventAdapterConstants.FROM_KEY, from);
|
||||
dynamicParmaters.put(XMPPEventAdapterConstants.SUBJECT_KEY, subject);
|
||||
message = (String) contentTransformer.transform(message, dynamicParmaters);
|
||||
ContentInfo contentInfo = contentValidator.validate(message, contentValidationParams, dynamicParmaters);
|
||||
if (contentInfo != null && contentInfo.isValidContent()) {
|
||||
eventAdapterListener.onEvent(contentInfo.getMsgText());
|
||||
eventAdapterListener.onEvent(contentInfo.getMessage());
|
||||
}
|
||||
} else {
|
||||
eventAdapterListener.onEvent(message);
|
||||
@ -51,4 +51,10 @@ public class XMPPEventAdapterConstants {
|
||||
|
||||
public static int initialReconnectDuration = 10000;
|
||||
public static final int reconnectionProgressionFactor = 2;
|
||||
|
||||
public static final String DEFAULT = "default";
|
||||
|
||||
public static final String XMPP_CONTENT_VALIDATION_DEFAULT_PARAMETERS = "";
|
||||
public static final String FROM_KEY = "from";
|
||||
public static final String SUBJECT_KEY = "subject";
|
||||
}
|
||||
@ -17,9 +17,6 @@
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -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);
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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";
|
||||
}
|
||||
@ -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";
|
||||
}
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
<packaging>bundle</packaging>
|
||||
<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>
|
||||
<url>http://wso2.org</url>
|
||||
|
||||
@ -94,13 +94,13 @@
|
||||
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||
<Bundle-Name>${project.artifactId}</Bundle-Name>
|
||||
<Private-Package>
|
||||
org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.internal,
|
||||
org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.internal.*
|
||||
org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.internal,
|
||||
org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.internal.*
|
||||
</Private-Package>
|
||||
<Export-Package>
|
||||
!org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.internal,
|
||||
!org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.internal.*,
|
||||
org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.*,
|
||||
!org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.internal,
|
||||
!org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.internal.*,
|
||||
org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.*,
|
||||
</Export-Package>
|
||||
<Import-Package>
|
||||
org.wso2.carbon.event.output.adapter.core,
|
||||
|
||||
@ -15,14 +15,14 @@
|
||||
* specific language governing permissions and limitations
|
||||
* 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.LogFactory;
|
||||
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.xmpp.i18n.util.MQTTAdapterPublisher;
|
||||
import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.i18n.util.MQTTBrokerConnectionConfiguration;
|
||||
import org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.util.MQTTAdapterPublisher;
|
||||
import org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.util.MQTTEventAdapterConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.output.adapter.mqtt.util.MQTTBrokerConnectionConfiguration;
|
||||
import org.wso2.carbon.event.output.adapter.core.EventAdapterUtil;
|
||||
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapter;
|
||||
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration;
|
||||
@ -68,7 +68,7 @@ public class MQTTEventAdapter implements OutputEventAdapter {
|
||||
|
||||
@Override
|
||||
public void init() throws OutputEventAdapterException {
|
||||
tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
|
||||
tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
|
||||
//ThreadPoolExecutor will be assigned if it is null
|
||||
if (threadPoolExecutor == null) {
|
||||
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);
|
||||
} else {
|
||||
mqttAdapterPublisher.publish(Integer.parseInt(qos), message.toString(), topic);
|
||||
@ -15,9 +15,9 @@
|
||||
* specific language governing permissions and limitations
|
||||
* 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 java.util.*;
|
||||
@ -15,12 +15,12 @@
|
||||
* specific language governing permissions and limitations
|
||||
* 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.LogFactory;
|
||||
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;
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* 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.LogFactory;
|
||||
@ -81,7 +81,7 @@ public class MQTTAdapterPublisher {
|
||||
connectionOptions.setUserName(getToken(mqttBrokerConnectionConfiguration.getBrokerUsername(),
|
||||
mqttBrokerConnectionConfiguration.getDcrUrl(),
|
||||
mqttBrokerConnectionConfiguration.getScopes()));
|
||||
connectionOptions.setPassword(Constants.DEFAULT_PASSWORD.toCharArray());
|
||||
connectionOptions.setPassword(MQTTEventAdapterConstants.DEFAULT_PASSWORD.toCharArray());
|
||||
}
|
||||
// Construct an MQTT blocking mode client
|
||||
mqttClient = new MqttClient(mqttBrokerConnectionConfiguration.getBrokerUrl(), clientId, dataStore);
|
||||
@ -142,19 +142,16 @@ public class MQTTAdapterPublisher {
|
||||
private String getToken(String username, String dcrUrlString, String scopes) {
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
|
||||
if (dcrUrlString != null && !dcrUrlString.isEmpty()) {
|
||||
PrivilegedCarbonContext.startTenantFlow();
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true);
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(username);
|
||||
try {
|
||||
URL dcrUrl = new URL(dcrUrlString);
|
||||
HttpClient httpClient = MQTTUtil.getHttpClient(dcrUrl.getProtocol());
|
||||
HttpPost postMethod = new HttpPost(dcrUrlString);
|
||||
RegistrationProfile registrationProfile = new RegistrationProfile();
|
||||
registrationProfile.setCallbackUrl(Constants.DEFAULT_CALLBACK);
|
||||
registrationProfile.setGrantType(Constants.GRANT_TYPE);
|
||||
registrationProfile.setCallbackUrl(MQTTEventAdapterConstants.DEFAULT_CALLBACK);
|
||||
registrationProfile.setGrantType(MQTTEventAdapterConstants.GRANT_TYPE);
|
||||
registrationProfile.setOwner(username);
|
||||
registrationProfile.setTokenScope(Constants.TOKEN_SCOPE);
|
||||
registrationProfile.setApplicationType(Constants.APPLICATION_TYPE);
|
||||
registrationProfile.setTokenScope(MQTTEventAdapterConstants.TOKEN_SCOPE);
|
||||
registrationProfile.setApplicationType(MQTTEventAdapterConstants.APPLICATION_TYPE);
|
||||
registrationProfile.setClientName(username + "_" + tenantId);
|
||||
String jsonString = registrationProfile.toJSON();
|
||||
StringEntity requestEntity = new StringEntity(jsonString, ContentType.APPLICATION_JSON);
|
||||
@ -164,8 +161,8 @@ public class MQTTAdapterPublisher {
|
||||
try {
|
||||
JSONParser jsonParser = new JSONParser();
|
||||
JSONObject jsonPayload = (JSONObject) jsonParser.parse(response);
|
||||
String clientId = (String) jsonPayload.get(Constants.CLIENT_ID);
|
||||
String clientSecret = (String) jsonPayload.get(Constants.CLIENT_SECRET);
|
||||
String clientId = (String) jsonPayload.get(MQTTEventAdapterConstants.CLIENT_ID);
|
||||
String clientSecret = (String) jsonPayload.get(MQTTEventAdapterConstants.CLIENT_SECRET);
|
||||
JWTClientManagerService jwtClientManagerService = MQTTUtil.getJWTClientManagerService();
|
||||
AccessTokenInfo accessTokenInfo = jwtClientManagerService.getJWTClient().getAccessToken(
|
||||
clientId, clientSecret, username, scopes);
|
||||
@ -181,8 +178,6 @@ public class MQTTAdapterPublisher {
|
||||
throw new OutputEventAdapterRuntimeException("Invalid dcrUrl : " + dcrUrlString);
|
||||
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | IOException e) {
|
||||
throw new OutputEventAdapterRuntimeException("Failed to create an https connection.", e);
|
||||
} finally {
|
||||
PrivilegedCarbonContext.endTenantFlow();
|
||||
}
|
||||
}
|
||||
throw new OutputEventAdapterRuntimeException("Invalid configuration for mqtt publisher");
|
||||
@ -15,7 +15,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* 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 {
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* 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 {
|
||||
@ -51,4 +51,11 @@ public final class MQTTEventAdapterConstants {
|
||||
public static final String ADAPTER_KEEP_ALIVE_TIME_NAME = "keepAliveTimeInMillis";
|
||||
public static final String ADAPTER_EXECUTOR_JOB_QUEUE_SIZE_NAME = "jobQueueSize";
|
||||
|
||||
public static final String DEFAULT_CALLBACK = "";
|
||||
public static final String DEFAULT_PASSWORD = "";
|
||||
public static final String GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer refresh_token";
|
||||
public static final String TOKEN_SCOPE = "production";
|
||||
public static final String APPLICATION_TYPE = "device";
|
||||
public static final String CLIENT_ID = "client_id";
|
||||
public static final String CLIENT_SECRET = "client_secret";
|
||||
}
|
||||
@ -16,7 +16,7 @@
|
||||
* 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.LogFactory;
|
||||
@ -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
|
||||
@ -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";
|
||||
|
||||
}
|
||||
@ -15,14 +15,14 @@
|
||||
* specific language governing permissions and limitations
|
||||
* 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.LogFactory;
|
||||
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.i18n.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.XMPPEventAdapterConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.util.XMPPAdapterPublisher;
|
||||
import org.wso2.carbon.device.mgt.iot.output.adapter.xmpp.util.XMPPServerConnectionConfiguration;
|
||||
import org.wso2.carbon.event.output.adapter.core.EventAdapterUtil;
|
||||
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapter;
|
||||
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration;
|
||||
@ -15,9 +15,9 @@
|
||||
* specific language governing permissions and limitations
|
||||
* 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 java.util.*;
|
||||
@ -80,7 +80,7 @@ public class XMPPEventAdapterFactory extends OutputEventAdapterFactory {
|
||||
//Resource
|
||||
Property resource = new Property(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));
|
||||
|
||||
staticPropertyList.add(host);
|
||||
@ -15,12 +15,12 @@
|
||||
* specific language governing permissions and limitations
|
||||
* 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.LogFactory;
|
||||
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;
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* 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.LogFactory;
|
||||
@ -15,7 +15,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* 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 {
|
||||
@ -15,7 +15,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* 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 {
|
||||
|
||||
@ -37,7 +37,10 @@
|
||||
<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.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>
|
||||
|
||||
<build>
|
||||
|
||||
@ -26,13 +26,9 @@ import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException
|
||||
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
||||
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
|
||||
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
|
||||
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.dto.SensorRecord;
|
||||
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.transport.RaspberryPiMQTTConnector;
|
||||
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util.APIUtil;
|
||||
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.service.IoTServerStartupListener;
|
||||
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
@ -43,14 +39,13 @@ import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class RaspberryPiControllerServiceImpl implements RaspberryPiControllerService {
|
||||
|
||||
private static Log log = LogFactory.getLog(RaspberryPiControllerServiceImpl.class);
|
||||
private ConcurrentHashMap<String, String> deviceToIpMap = new ConcurrentHashMap<>();
|
||||
private RaspberryPiMQTTConnector raspberryPiMQTTConnector;
|
||||
|
||||
@Path("device/{deviceId}/bulb")
|
||||
@POST
|
||||
@ -66,12 +61,14 @@ public class RaspberryPiControllerServiceImpl implements RaspberryPiControllerSe
|
||||
log.error("The requested state change shoud be either - 'ON' or 'OFF'");
|
||||
return Response.status(Response.Status.BAD_REQUEST.getStatusCode()).build();
|
||||
}
|
||||
String mqttResource = RaspberrypiConstants.BULB_CONTEXT.replace("/", "");
|
||||
raspberryPiMQTTConnector.publishDeviceData(deviceId, mqttResource, switchToState);
|
||||
String actualMessage = RaspberrypiConstants.BULB_CONTEXT + ":" + state;
|
||||
Map<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();
|
||||
} catch (TransportHandlerException e) {
|
||||
log.error("Failed to send switch-bulb request to device [" + deviceId + "]");
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
|
||||
} catch (DeviceAccessAuthorizationException e) {
|
||||
log.error(e.getErrorMessage(), e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
|
||||
@ -109,44 +106,4 @@ public class RaspberryPiControllerServiceImpl implements RaspberryPiControllerSe
|
||||
}
|
||||
}
|
||||
|
||||
private boolean waitForServerStartup() {
|
||||
while (!IoTServerStartupListener.isServerReady()) {
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public RaspberryPiMQTTConnector getRaspberryPiMQTTConnector() {
|
||||
return raspberryPiMQTTConnector;
|
||||
}
|
||||
|
||||
public void setRaspberryPiMQTTConnector(
|
||||
final RaspberryPiMQTTConnector raspberryPiMQTTConnector) {
|
||||
Runnable connector = new Runnable() {
|
||||
public void run() {
|
||||
if (waitForServerStartup()) {
|
||||
return;
|
||||
}
|
||||
//The delay is added for the server to starts up.
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
RaspberryPiControllerServiceImpl.this.raspberryPiMQTTConnector = raspberryPiMQTTConnector;
|
||||
if (MqttConfig.getInstance().isEnabled()) {
|
||||
raspberryPiMQTTConnector.connect();
|
||||
} else {
|
||||
log.warn("MQTT disabled in 'devicemgt-config.xml'. Hence, RaspberryPiMQTTConnector not started.");
|
||||
}
|
||||
}
|
||||
};
|
||||
Thread connectorThread = new Thread(connector);
|
||||
connectorThread.start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService;
|
||||
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
|
||||
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.dto.SensorRecord;
|
||||
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
|
||||
import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -168,5 +169,16 @@ public class APIUtil {
|
||||
return deviceAccessAuthorizationService;
|
||||
}
|
||||
|
||||
public static OutputEventAdapterService getOutputEventAdapterService() {
|
||||
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
||||
OutputEventAdapterService outputEventAdapterService =
|
||||
(OutputEventAdapterService) ctx.getOSGiService(OutputEventAdapterService.class, null);
|
||||
if (outputEventAdapterService == null) {
|
||||
String msg = "Device Authorization service has not initialized.";
|
||||
log.error(msg);
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
return outputEventAdapterService;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -71,7 +71,13 @@
|
||||
org.wso2.carbon.device.mgt.common,
|
||||
org.wso2.carbon.device.mgt.iot.*,
|
||||
org.wso2.carbon.device.mgt.extensions.feature.mgt.*,
|
||||
org.wso2.carbon.utils.*
|
||||
org.wso2.carbon.utils.*,
|
||||
org.wso2.carbon.base,
|
||||
org.wso2.carbon.context,
|
||||
org.wso2.carbon.core,
|
||||
org.wso2.carbon.core.util,
|
||||
org.wso2.carbon.event.output.adapter.core,
|
||||
org.wso2.carbon.event.output.adapter.core.exception
|
||||
</Import-Package>
|
||||
<Export-Package>
|
||||
!org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.internal,
|
||||
@ -112,5 +118,13 @@
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.utils</artifactId>
|
||||
</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>
|
||||
</project>
|
||||
@ -27,7 +27,7 @@ public class RaspberrypiConstants {
|
||||
public final static String STATE_OFF = "OFF";
|
||||
|
||||
public static final String URL_PREFIX = "http://";
|
||||
public static final String BULB_CONTEXT = "/BULB/";
|
||||
public static final String BULB_CONTEXT = "BULB";
|
||||
public static final String TEMPERATURE_CONTEXT = "/TEMPERATURE/";
|
||||
|
||||
//type of the sensor
|
||||
@ -37,4 +37,24 @@ public class RaspberrypiConstants {
|
||||
public static final String DATA_SOURCE_NAME = "jdbc/RaspberryPiDM_DB";
|
||||
public final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super";
|
||||
|
||||
//mqtt tranport related constants
|
||||
public static final String MQTT_ADAPTER_NAME = "raspberrypi_mqtt";
|
||||
public static final String MQTT_ADAPTER_TYPE = "oauth-mqtt";
|
||||
public static final String ADAPTER_TOPIC_PROPERTY = "topic";
|
||||
public static final String MQTT_PORT = "\\$\\{mqtt.broker.port\\}";
|
||||
public static final String MQTT_BROKER_HOST = "\\$\\{mqtt.broker.host\\}";
|
||||
public static final String CARBON_CONFIG_PORT_OFFSET = "Ports.Offset";
|
||||
public static final String DEFAULT_CARBON_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";
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -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.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.iot.raspberrypi.plugin.constants.RaspberrypiConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.exception.RaspberrypiDeviceMgtPluginException;
|
||||
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.internal.RaspberrypiManagementDataHolder;
|
||||
import org.wso2.carbon.event.output.adapter.core.MessageType;
|
||||
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration;
|
||||
import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException;
|
||||
import org.wso2.carbon.utils.CarbonUtils;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NamingException;
|
||||
import javax.sql.DataSource;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Contains utility methods used by Raspberrypi plugin.
|
||||
@ -42,25 +55,9 @@ public class RaspberrypiUtils {
|
||||
|
||||
private static Log log = LogFactory.getLog(RaspberrypiUtils.class);
|
||||
|
||||
public static String getDeviceProperty(List<Device.Property> deviceProperties, String propertyKey) {
|
||||
String deviceProperty = "";
|
||||
for(Device.Property property :deviceProperties){
|
||||
if(propertyKey.equals(property.getName())){
|
||||
deviceProperty = property.getValue();
|
||||
}
|
||||
}
|
||||
return deviceProperty;
|
||||
}
|
||||
|
||||
public static Device.Property getProperty(String property, String value) {
|
||||
if (property != null) {
|
||||
Device.Property prop = new Device.Property();
|
||||
prop.setName(property);
|
||||
prop.setValue(value);
|
||||
return prop;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private static final String VIRTUAL_FIREALARM_CONFIG_LOCATION =
|
||||
CarbonUtils.getCarbonHome() + File.separator + "repository" + File.separator + "conf" +
|
||||
File.separator + "iot" + File.separator + "mqtt.properties";
|
||||
|
||||
public static void cleanupResources(Connection conn, PreparedStatement stmt, ResultSet rs) {
|
||||
if (rs != null) {
|
||||
@ -108,4 +105,85 @@ public class RaspberrypiUtils {
|
||||
"Management database schema", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setupMqttOutputAdapter() throws IOException {
|
||||
OutputEventAdapterConfiguration outputEventAdapterConfiguration =
|
||||
createMqttOutputEventAdapterConfiguration(RaspberrypiConstants.MQTT_ADAPTER_NAME,
|
||||
RaspberrypiConstants.MQTT_ADAPTER_TYPE, MessageType.TEXT);
|
||||
try {
|
||||
PrivilegedCarbonContext.startTenantFlow();
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
|
||||
RaspberrypiConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true);
|
||||
RaspberrypiManagementDataHolder.getInstance().getOutputEventAdapterService()
|
||||
.create(outputEventAdapterConfiguration);
|
||||
} catch (OutputEventAdapterException e) {
|
||||
log.error("Unable to create Output Event Adapter : " + RaspberrypiConstants.MQTT_ADAPTER_NAME, e);
|
||||
} finally {
|
||||
PrivilegedCarbonContext.endTenantFlow();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Output Event Adapter Configuration for given configuration.
|
||||
*
|
||||
* @param name Output Event Adapter name
|
||||
* @param type Output Event Adapter type
|
||||
* @param msgFormat Output Event Adapter message format
|
||||
* @return OutputEventAdapterConfiguration instance for given configuration
|
||||
*/
|
||||
private static OutputEventAdapterConfiguration createMqttOutputEventAdapterConfiguration(String name, String type,
|
||||
String msgFormat) throws IOException {
|
||||
OutputEventAdapterConfiguration outputEventAdapterConfiguration = new OutputEventAdapterConfiguration();
|
||||
outputEventAdapterConfiguration.setName(name);
|
||||
outputEventAdapterConfiguration.setType(type);
|
||||
outputEventAdapterConfiguration.setMessageFormat(msgFormat);
|
||||
File configFile = new File(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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -23,14 +23,23 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.osgi.service.component.ComponentContext;
|
||||
import org.wso2.carbon.core.ServerStartupObserver;
|
||||
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
|
||||
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.exception.RaspberrypiDeviceMgtPluginException;
|
||||
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl.RaspberrypiManagerService;
|
||||
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl.util.RaspberrypiStartupListener;
|
||||
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl.util.RaspberrypiUtils;
|
||||
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
|
||||
|
||||
/**
|
||||
* @scr.component name="org.wso2.carbon.device.mgt.iot.raspberrypi.internal.RaspberrypiManagementServiceComponent"
|
||||
* immediate="true"
|
||||
* @scr.reference name="event.output.adapter.service"
|
||||
* interface="org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService"
|
||||
* cardinality="1..1"
|
||||
* policy="dynamic"
|
||||
* bind="setOutputEventAdapterService"
|
||||
* unbind="unsetOutputEventAdapterService"
|
||||
*/
|
||||
public class RaspberrypiManagementServiceComponent {
|
||||
|
||||
@ -46,6 +55,8 @@ public class RaspberrypiManagementServiceComponent {
|
||||
raspberrypiServiceRegRef =
|
||||
bundleContext.registerService(DeviceManagementService.class.getName(),
|
||||
new RaspberrypiManagerService(), null);
|
||||
bundleContext.registerService(ServerStartupObserver.class.getName(), new RaspberrypiStartupListener(),
|
||||
null);
|
||||
String setupOption = System.getProperty("setup");
|
||||
if (setupOption != null) {
|
||||
if (log.isDebugEnabled()) {
|
||||
@ -82,4 +93,20 @@ public class RaspberrypiManagementServiceComponent {
|
||||
log.error("Error occurred while de-activating Raspberrypi Device Management bundle", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the Output EventAdapter Service dependency
|
||||
*
|
||||
* @param outputEventAdapterService Output EventAdapter Service reference
|
||||
*/
|
||||
protected void setOutputEventAdapterService(OutputEventAdapterService outputEventAdapterService) {
|
||||
RaspberrypiManagementDataHolder.getInstance().setOutputEventAdapterService(outputEventAdapterService);
|
||||
}
|
||||
|
||||
/**
|
||||
* De-reference the Output EventAdapter Service dependency.
|
||||
*/
|
||||
protected void unsetOutputEventAdapterService(OutputEventAdapterService outputEventAdapterService) {
|
||||
RaspberrypiManagementDataHolder.getInstance().setOutputEventAdapterService(null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,7 +196,7 @@ public class FireAlarmXMPPCommunicator extends XMPPTransportHandler {
|
||||
String payLoad = AgentUtilOperations.prepareSecurePayLoad(message);
|
||||
|
||||
xmppMessage.setTo(xmppAdminJID);
|
||||
xmppMessage.setSubject("PUBLISHER");
|
||||
xmppMessage.setSubject(agentManager.getAgentConfigs().getTenantDomain());
|
||||
xmppMessage.setBody(payLoad);
|
||||
xmppMessage.setType(Message.Type.chat);
|
||||
|
||||
|
||||
@ -57,8 +57,8 @@ public class AgentConstants {
|
||||
--------------------------------------------------------------------------------------- */
|
||||
public static final int DEFAULT_MQTT_RECONNECTION_INTERVAL = 2; // time in seconds
|
||||
public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0;
|
||||
public static final String MQTT_SUBSCRIBE_TOPIC = "wso2/%s/" + DEVICE_TYPE + "/%s";
|
||||
public static final String MQTT_PUBLISH_TOPIC = "wso2/%s/" + DEVICE_TYPE + "/%s/publisher";
|
||||
public static final String MQTT_SUBSCRIBE_TOPIC = "%s/" + DEVICE_TYPE + "/%s";
|
||||
public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/publisher";
|
||||
/* ---------------------------------------------------------------------------------------
|
||||
XMPP Connection specific information
|
||||
--------------------------------------------------------------------------------------- */
|
||||
|
||||
@ -196,7 +196,7 @@ public class FireAlarmXMPPCommunicator extends XMPPTransportHandler {
|
||||
String payLoad = AgentUtilOperations.prepareSecurePayLoad(message);
|
||||
|
||||
xmppMessage.setTo(xmppAdminJID);
|
||||
xmppMessage.setSubject("PUBLISHER");
|
||||
xmppMessage.setSubject(agentManager.getAgentConfigs().getTenantDomain());
|
||||
xmppMessage.setBody(payLoad);
|
||||
xmppMessage.setType(Message.Type.chat);
|
||||
|
||||
|
||||
@ -56,8 +56,8 @@ public class AgentConstants {
|
||||
--------------------------------------------------------------------------------------- */
|
||||
public static final int DEFAULT_MQTT_RECONNECTION_INTERVAL = 2; // time in seconds
|
||||
public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0;
|
||||
public static final String MQTT_SUBSCRIBE_TOPIC = "wso2/%s/" + DEVICE_TYPE + "/%s";
|
||||
public static final String MQTT_PUBLISH_TOPIC = "wso2/%s/" + DEVICE_TYPE + "/%s/publisher";
|
||||
public static final String MQTT_SUBSCRIBE_TOPIC = "%s/" + DEVICE_TYPE + "/%s";
|
||||
public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/publisher";
|
||||
/* ---------------------------------------------------------------------------------------
|
||||
XMPP Connection specific information
|
||||
--------------------------------------------------------------------------------------- */
|
||||
|
||||
@ -22,12 +22,8 @@ import org.wso2.carbon.apimgt.annotations.api.API;
|
||||
import org.wso2.carbon.apimgt.annotations.api.Permission;
|
||||
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.DeviceType;
|
||||
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.Feature;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.DeviceData;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.*;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
/**
|
||||
|
||||
@ -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.SortByField;
|
||||
import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
|
||||
import org.wso2.carbon.apimgt.annotations.api.Permission;
|
||||
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
||||
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
|
||||
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
|
||||
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
|
||||
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig;
|
||||
import org.wso2.carbon.device.mgt.iot.service.IoTServerStartupListener;
|
||||
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.DeviceData;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util.VirtualFirealarmSecurityManager;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.SensorRecord;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.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.SecurityManager;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.VirtualFireAlarmServiceUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.FormParam;
|
||||
import javax.ws.rs.GET;
|
||||
@ -52,31 +42,17 @@ import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.PrivateKey;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@SuppressWarnings("Non-Annoted WebService")
|
||||
public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmControllerService {
|
||||
|
||||
private static final String XMPP_PROTOCOL = "XMPP";
|
||||
private static final String HTTP_PROTOCOL = "HTTP";
|
||||
private static final String MQTT_PROTOCOL = "MQTT";
|
||||
private static Log log = LogFactory.getLog(VirtualFireAlarmControllerServiceImpl.class);
|
||||
// consists of utility methods related to encrypting and decrypting messages
|
||||
private org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.SecurityManager securityManager;
|
||||
// connects to the given MQTT broker and handles MQTT communication
|
||||
private VirtualFireAlarmMQTTConnector virtualFireAlarmMQTTConnector;
|
||||
// connects to the given XMPP server and handles XMPP communication
|
||||
private VirtualFireAlarmXMPPConnector virtualFireAlarmXMPPConnector;
|
||||
|
||||
|
||||
@POST
|
||||
@Path("device/{deviceId}/buzz")
|
||||
@ -89,7 +65,6 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
|
||||
return Response.status(Response.Status.BAD_REQUEST).build();
|
||||
}
|
||||
String protocolString = protocol.toUpperCase();
|
||||
String callUrlPattern = VirtualFireAlarmConstants.BULB_CONTEXT + switchToState;
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Sending request to switch-bulb of device [" + deviceId + "] via " +
|
||||
protocolString);
|
||||
@ -100,29 +75,31 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
|
||||
DeviceGroupConstants.Permissions.DEFAULT_OPERATOR_PERMISSIONS)) {
|
||||
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
|
||||
}
|
||||
switch (protocolString) {
|
||||
case XMPP_PROTOCOL:
|
||||
String xmppResource = VirtualFireAlarmConstants.BULB_CONTEXT.replace("/", "");
|
||||
virtualFireAlarmXMPPConnector.publishDeviceData(deviceId, xmppResource, switchToState);
|
||||
break;
|
||||
default:
|
||||
String mqttResource = VirtualFireAlarmConstants.BULB_CONTEXT.replace("/", "");
|
||||
String publishTopic = "wso2/" + APIUtil.getTenantDomainOftheUser() + "/"
|
||||
+ VirtualFireAlarmConstants.DEVICE_TYPE + "/" + deviceId;
|
||||
PrivateKey serverPrivateKey = SecurityManager.getServerPrivateKey();
|
||||
String actualMessage = mqttResource + ":" + state.toUpperCase();
|
||||
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) {
|
||||
case XMPP_PROTOCOL:
|
||||
dynamicProperties.put(VirtualFireAlarmConstants.JID_PROPERTY_KEY, deviceId);
|
||||
dynamicProperties.put(VirtualFireAlarmConstants.SUBJECT_PROPERTY_KEY, "CONTROL-REQUEST");
|
||||
dynamicProperties.put(VirtualFireAlarmConstants.MESSAGE_TYPE_PROPERTY_KEY,
|
||||
VirtualFireAlarmConstants.CHAT_PROPERTY_KEY);
|
||||
APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.XMPP_ADAPTER_NAME,
|
||||
dynamicProperties, encryptedMsg);
|
||||
break;
|
||||
default:
|
||||
|
||||
String publishTopic = APIUtil.getTenantDomainOftheUser() + "/"
|
||||
+ VirtualFireAlarmConstants.DEVICE_TYPE + "/" + deviceId;
|
||||
dynamicProperties.put(VirtualFireAlarmConstants.ADAPTER_TOPIC_PROPERTY, publishTopic);
|
||||
APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.ADAPTER_NAME,
|
||||
APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.MQTT_ADAPTER_NAME,
|
||||
dynamicProperties, encryptedMsg);
|
||||
break;
|
||||
}
|
||||
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) {
|
||||
log.error(e.getErrorMessage(), e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
|
||||
@ -139,8 +116,7 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
|
||||
@FormParam("policy") String policy) {
|
||||
String protocolString = protocol.toUpperCase();
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Sending request to update-policy of device [" + deviceId + "] via " +
|
||||
protocolString);
|
||||
log.debug("Sending request to update-policy of device [" + deviceId + "] via " + protocolString);
|
||||
}
|
||||
try {
|
||||
if (!APIUtil.getDeviceAccessAuthorizationService().isUserAuthorized(
|
||||
@ -148,23 +124,36 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
|
||||
DeviceGroupConstants.Permissions.DEFAULT_MANAGE_POLICIES_PERMISSIONS)) {
|
||||
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
|
||||
}
|
||||
PrivateKey serverPrivateKey = VirtualFirealarmSecurityManager.getServerPrivateKey();
|
||||
String actualMessage = VirtualFireAlarmConstants.POLICY_CONTEXT + ":" + policy;
|
||||
String encryptedMsg = VirtualFireAlarmServiceUtils.prepareSecurePayLoad(actualMessage,
|
||||
serverPrivateKey);
|
||||
Map<String, String> dynamicProperties = new HashMap<>();
|
||||
switch (protocolString) {
|
||||
case XMPP_PROTOCOL:
|
||||
String xmppResource = VirtualFireAlarmConstants.POLICY_CONTEXT.replace("/", "");
|
||||
virtualFireAlarmXMPPConnector.publishDeviceData(deviceId, xmppResource, policy);
|
||||
dynamicProperties.put(VirtualFireAlarmConstants.JID_PROPERTY_KEY, deviceId);
|
||||
dynamicProperties.put(VirtualFireAlarmConstants.SUBJECT_PROPERTY_KEY, "POLICTY-REQUEST");
|
||||
dynamicProperties.put(VirtualFireAlarmConstants.MESSAGE_TYPE_PROPERTY_KEY,
|
||||
VirtualFireAlarmConstants.CHAT_PROPERTY_KEY);
|
||||
APIUtil.getOutputEventAdapterService().publish(VirtualFireAlarmConstants.XMPP_ADAPTER_NAME,
|
||||
dynamicProperties, encryptedMsg);
|
||||
break;
|
||||
default:
|
||||
String 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;
|
||||
}
|
||||
return Response.ok().build();
|
||||
} catch (TransportHandlerException e) {
|
||||
log.error("Failed to send update-policy request to device [" + deviceId + "] via " + protocolString);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
|
||||
} catch (DeviceAccessAuthorizationException e) {
|
||||
log.error(e.getErrorMessage(), e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
|
||||
} catch (VirtualFireAlarmException e) {
|
||||
log.error(e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,13 +175,11 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
|
||||
DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) {
|
||||
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
|
||||
}
|
||||
if (sensorTableName != null) {
|
||||
List<SortByField> sortByFields = new ArrayList<>();
|
||||
SortByField sortByField = new SortByField("time", SORT.ASC, false);
|
||||
sortByFields.add(sortByField);
|
||||
List<SensorRecord> sensorRecords = APIUtil.getAllEventsForDevice(sensorTableName, query, sortByFields);
|
||||
return Response.status(Response.Status.OK.getStatusCode()).entity(sensorRecords).build();
|
||||
}
|
||||
} catch (AnalyticsException e) {
|
||||
String errorMsg = "Error on retrieving stats on table " + sensorTableName + " with query " + query;
|
||||
log.error(errorMsg);
|
||||
@ -201,135 +188,6 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
|
||||
log.error(e.getErrorMessage(), e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
|
||||
}
|
||||
return Response.status(Response.Status.BAD_REQUEST).build();
|
||||
}
|
||||
|
||||
private boolean waitForServerStartup() {
|
||||
while (!IoTServerStartupListener.isServerReady()) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the `SecurityManager` specific to this VirtualFirealarm controller service.
|
||||
*
|
||||
* @return the 'SecurityManager' instance bound to the 'securityManager' variable of this service.
|
||||
*/
|
||||
@SuppressWarnings("Unused")
|
||||
public SecurityManager getSecurityManager() {
|
||||
return securityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the `securityManager` variable of this VirtualFirealarm controller service.
|
||||
*
|
||||
* @param securityManager a 'SecurityManager' object that handles the encryption, decryption, signing and validation
|
||||
* of incoming messages from VirtualFirealarm device-types.
|
||||
*/
|
||||
@SuppressWarnings("Unused")
|
||||
public void setSecurityManager(SecurityManager securityManager) {
|
||||
this.securityManager = securityManager;
|
||||
securityManager.initVerificationManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the `VirtualFireAlarmXMPPConnector` specific to this VirtualFirealarm controller service.
|
||||
*
|
||||
* @return the 'VirtualFireAlarmXMPPConnector' instance bound to the 'virtualFireAlarmXMPPConnector' variable of
|
||||
* this service.
|
||||
*/
|
||||
@SuppressWarnings("Unused")
|
||||
public VirtualFireAlarmXMPPConnector getVirtualFireAlarmXMPPConnector() {
|
||||
return virtualFireAlarmXMPPConnector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the `virtualFireAlarmXMPPConnector` variable of this VirtualFirealarm controller service.
|
||||
*
|
||||
* @param virtualFireAlarmXMPPConnector a 'VirtualFireAlarmXMPPConnector' object that handles all XMPP related
|
||||
* communications of any connected VirtualFirealarm device-type
|
||||
*/
|
||||
@SuppressWarnings("Unused")
|
||||
public void setVirtualFireAlarmXMPPConnector(
|
||||
final VirtualFireAlarmXMPPConnector virtualFireAlarmXMPPConnector) {
|
||||
Runnable connector = new Runnable() {
|
||||
public void run() {
|
||||
if (waitForServerStartup()) {
|
||||
return;
|
||||
}
|
||||
VirtualFireAlarmControllerServiceImpl.this.virtualFireAlarmXMPPConnector =
|
||||
virtualFireAlarmXMPPConnector;
|
||||
|
||||
if (XmppConfig.getInstance().isEnabled()) {
|
||||
Runnable xmppStarter = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
virtualFireAlarmXMPPConnector.initConnector();
|
||||
virtualFireAlarmXMPPConnector.connect();
|
||||
}
|
||||
};
|
||||
|
||||
Thread xmppStarterThread = new Thread(xmppStarter);
|
||||
xmppStarterThread.setDaemon(true);
|
||||
xmppStarterThread.start();
|
||||
} else {
|
||||
log.warn(
|
||||
"XMPP disabled in 'devicemgt-config.xml'. Hence, VirtualFireAlarmXMPPConnector not " +
|
||||
"started.");
|
||||
}
|
||||
}
|
||||
};
|
||||
Thread connectorThread = new Thread(connector);
|
||||
connectorThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the `VirtualFireAlarmMQTTConnector` specific to this VirtualFirealarm controller service.
|
||||
*
|
||||
* @return the 'VirtualFireAlarmMQTTConnector' instance bound to the 'virtualFireAlarmMQTTConnector' variable of
|
||||
* this service.
|
||||
*/
|
||||
@SuppressWarnings("Unused")
|
||||
public VirtualFireAlarmMQTTConnector getVirtualFireAlarmMQTTConnector() {
|
||||
return virtualFireAlarmMQTTConnector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the `virtualFireAlarmMQTTConnector` variable of this VirtualFirealarm controller service.
|
||||
*
|
||||
* @param virtualFireAlarmMQTTConnector a 'VirtualFireAlarmMQTTConnector' object that handles all MQTT related
|
||||
* communications of any connected VirtualFirealarm device-type
|
||||
*/
|
||||
@SuppressWarnings("Unused")
|
||||
public void setVirtualFireAlarmMQTTConnector(
|
||||
final VirtualFireAlarmMQTTConnector virtualFireAlarmMQTTConnector) {
|
||||
Runnable connector = new Runnable() {
|
||||
public void run() {
|
||||
if (waitForServerStartup()) {
|
||||
return;
|
||||
}
|
||||
//The delay is added for the server to starts up.
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
VirtualFireAlarmControllerServiceImpl.this.virtualFireAlarmMQTTConnector =
|
||||
virtualFireAlarmMQTTConnector;
|
||||
if (MqttConfig.getInstance().isEnabled()) {
|
||||
virtualFireAlarmMQTTConnector.connect();
|
||||
} else {
|
||||
log.warn(
|
||||
"MQTT disabled in 'devicemgt-config.xml'. Hence, VirtualFireAlarmMQTTConnector not started.");
|
||||
}
|
||||
}
|
||||
};
|
||||
Thread connectorThread = new Thread(connector);
|
||||
connectorThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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.authorization.DeviceAccessAuthorizationException;
|
||||
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppAccount;
|
||||
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig;
|
||||
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppServerClient;
|
||||
import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
|
||||
import org.wso2.carbon.device.mgt.iot.util.ZipArchive;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppAccount;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppConfig;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppServerClient;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.APIUtil;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.ZipUtil;
|
||||
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
|
||||
@ -207,6 +208,9 @@ public class VirtualFireAlarmManagerServiceImpl implements VirtualFireAlarmManag
|
||||
} catch (UserStoreException ex) {
|
||||
log.error(ex.getMessage(), ex);
|
||||
return Response.status(500).entity(ex.getMessage()).build();
|
||||
} catch (VirtualFirealarmDeviceMgtPluginException ex) {
|
||||
log.error(ex.getMessage(), ex);
|
||||
return Response.status(500).entity(ex.getMessage()).build();
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,7 +242,7 @@ public class VirtualFireAlarmManagerServiceImpl implements VirtualFireAlarmManag
|
||||
|
||||
private ZipArchive createDownloadFile(String owner, String deviceName, String sketchType)
|
||||
throws DeviceManagementException, APIManagerException, JWTClientException, DeviceControllerException,
|
||||
UserStoreException {
|
||||
UserStoreException, VirtualFirealarmDeviceMgtPluginException {
|
||||
//create new device id
|
||||
String deviceId = shortUUID();
|
||||
if (apiApplicationKey == null) {
|
||||
@ -259,15 +263,14 @@ public class VirtualFireAlarmManagerServiceImpl implements VirtualFireAlarmManag
|
||||
String refreshToken = accessTokenInfo.getRefreshToken();
|
||||
//adding registering data
|
||||
XmppAccount newXmppAccount = new XmppAccount();
|
||||
newXmppAccount.setAccountName(owner + "_" + deviceId);
|
||||
newXmppAccount.setAccountName(deviceId);
|
||||
newXmppAccount.setUsername(deviceId);
|
||||
newXmppAccount.setPassword(accessToken);
|
||||
newXmppAccount.setEmail(deviceId + "@" + APIUtil.getTenantDomainOftheUser());
|
||||
XmppServerClient xmppServerClient = new XmppServerClient();
|
||||
xmppServerClient.initControlQueue();
|
||||
boolean status;
|
||||
if (XmppConfig.getInstance().isEnabled()) {
|
||||
status = xmppServerClient.createXMPPAccount(newXmppAccount);
|
||||
status = xmppServerClient.createAccount(newXmppAccount);
|
||||
if (!status) {
|
||||
String msg = "XMPP Account was not created for device - " + deviceId + " of owner - " + owner +
|
||||
".XMPP might have been disabled in org.wso2.carbon.device.mgt.iot" +
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -28,4 +28,8 @@ public class VirtualFireAlarmException extends Exception {
|
||||
public VirtualFireAlarmException(String errorMessage, Throwable throwable) {
|
||||
super(errorMessage, throwable);
|
||||
}
|
||||
|
||||
public VirtualFireAlarmException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,333 +21,33 @@ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.concurrent.FutureCallback;
|
||||
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
|
||||
import org.apache.http.impl.nio.client.HttpAsyncClients;
|
||||
import org.json.JSONObject;
|
||||
import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException;
|
||||
import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService;
|
||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException;
|
||||
import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService;
|
||||
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util.VirtualFirealarmSecurityManager;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException;
|
||||
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.URL;
|
||||
import java.security.Key;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class VirtualFireAlarmServiceUtils {
|
||||
private static final Log log = LogFactory.getLog(VirtualFireAlarmServiceUtils.class);
|
||||
|
||||
private static final String TEMPERATURE_STREAM_DEFINITION = "org.wso2.iot.devices.temperature";
|
||||
private static final String JSON_MESSAGE_KEY = "Msg";
|
||||
private static final String JSON_SIGNATURE_KEY = "Sig";
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* @throws VirtualFireAlarmException
|
||||
*/
|
||||
public static CertificateManagementService getCertificateManagementService() throws VirtualFireAlarmException {
|
||||
|
||||
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
||||
CertificateManagementService certificateManagementService = (CertificateManagementService)
|
||||
ctx.getOSGiService(CertificateManagementService.class, null);
|
||||
|
||||
if (certificateManagementService == null) {
|
||||
String msg = "EnrollmentService is not initialized";
|
||||
log.error(msg);
|
||||
throw new VirtualFireAlarmException(msg);
|
||||
}
|
||||
|
||||
return certificateManagementService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param deviceHTTPEndpoint
|
||||
* @param urlContext
|
||||
* @param fireAndForgot
|
||||
* @return
|
||||
* @throws DeviceManagementException
|
||||
*/
|
||||
public static String sendCommandViaHTTP(final String deviceHTTPEndpoint, String urlContext, boolean fireAndForgot)
|
||||
throws DeviceManagementException {
|
||||
|
||||
String responseMsg = "";
|
||||
String urlString = VirtualFireAlarmConstants.URL_PREFIX + deviceHTTPEndpoint + urlContext;
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(urlString);
|
||||
}
|
||||
|
||||
if (!fireAndForgot) {
|
||||
HttpURLConnection httpConnection = getHttpConnection(urlString);
|
||||
|
||||
try {
|
||||
httpConnection.setRequestMethod(HttpMethod.GET);
|
||||
} catch (ProtocolException e) {
|
||||
String errorMsg =
|
||||
"Protocol specific error occurred when trying to set method to GET" +
|
||||
" for:" + urlString;
|
||||
log.error(errorMsg);
|
||||
throw new DeviceManagementException(errorMsg, e);
|
||||
}
|
||||
|
||||
responseMsg = readResponseFromGetRequest(httpConnection);
|
||||
|
||||
} else {
|
||||
CloseableHttpAsyncClient httpclient = null;
|
||||
try {
|
||||
|
||||
httpclient = HttpAsyncClients.createDefault();
|
||||
httpclient.start();
|
||||
HttpGet request = new HttpGet(urlString);
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
Future<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 {
|
||||
try {
|
||||
message = Base64.encodeBase64String(message.getBytes());
|
||||
String signedPayload = SecurityManager.signMessage(message, signatureKey);
|
||||
String signedPayload = VirtualFirealarmSecurityManager.signMessage(message, signatureKey);
|
||||
JSONObject jsonPayload = new JSONObject();
|
||||
jsonPayload.put(JSON_MESSAGE_KEY, message);
|
||||
jsonPayload.put(JSON_SIGNATURE_KEY, signedPayload);
|
||||
return jsonPayload.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @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 {
|
||||
CertificateManagementService certificateManagementService =
|
||||
VirtualFireAlarmServiceUtils.getCertificateManagementService();
|
||||
X509Certificate clientCertificate = (X509Certificate) certificateManagementService.getCertificateByAlias(
|
||||
alias);
|
||||
clientPublicKey = clientCertificate.getPublicKey();
|
||||
|
||||
} catch (VirtualFireAlarmException e) {
|
||||
String errorMsg = "Could not retrieve CertificateManagementService from the runtime.";
|
||||
if(log.isDebugEnabled()){
|
||||
log.debug(errorMsg);
|
||||
}
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
} catch (KeystoreException e) {
|
||||
String errorMsg;
|
||||
if (e.getMessage().contains("NULL_CERT")) {
|
||||
errorMsg = "The Device-View page might have been accessed prior to the device being started.";
|
||||
if(log.isDebugEnabled()){
|
||||
log.debug(errorMsg);
|
||||
}
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
} else {
|
||||
errorMsg = "An error occurred whilst trying to retrieve certificate for alias [" + alias +
|
||||
"] with alias: [" + alias + "]";
|
||||
if(log.isDebugEnabled()){
|
||||
log.debug(errorMsg);
|
||||
}
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
}
|
||||
}
|
||||
return clientPublicKey;
|
||||
} catch (VirtualFirealarmDeviceMgtPluginException e) {
|
||||
throw new VirtualFireAlarmException(e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@
|
||||
</Permission>
|
||||
<Permission>
|
||||
<name>Download device</name>
|
||||
<path>/device-mgt/user</path>
|
||||
<path>/device-mgt/virtual_firealarm/user</path>
|
||||
<url>/enrollment/devices/download</url>
|
||||
<method>GET</method>
|
||||
<scope>virtual_firealarm_user</scope>
|
||||
|
||||
@ -27,9 +27,6 @@
|
||||
<jaxrs:serviceBeans>
|
||||
<bean id="VirtualFireAlarmControllerService"
|
||||
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 id="VirtualFireAlarmManagerService"
|
||||
class="org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.VirtualFireAlarmManagerServiceImpl">
|
||||
@ -40,15 +37,5 @@
|
||||
</jaxrs:providers>
|
||||
</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>
|
||||
|
||||
|
||||
@ -77,7 +77,18 @@
|
||||
org.wso2.carbon.base,
|
||||
org.wso2.carbon.core.util,
|
||||
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>
|
||||
<Export-Package>
|
||||
!org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.internal,
|
||||
@ -90,6 +101,10 @@
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>commons-codec.wso2</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.osgi</groupId>
|
||||
<artifactId>org.eclipse.osgi</artifactId>
|
||||
@ -106,6 +121,10 @@
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.ndatasource.core</artifactId>
|
||||
@ -122,6 +141,33 @@
|
||||
<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>
|
||||
<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>
|
||||
</project>
|
||||
@ -26,17 +26,17 @@ public class VirtualFireAlarmConstants {
|
||||
public final static String STATE_OFF = "OFF";
|
||||
|
||||
public static final String URL_PREFIX = "http://";
|
||||
public static final String BULB_CONTEXT = "/BULB/";
|
||||
public static final String POLICY_CONTEXT = "/POLICY/";
|
||||
public static final String BULB_CONTEXT = "BULB";
|
||||
public static final String POLICY_CONTEXT = "POLICY";
|
||||
|
||||
//sensor events sumerized table name for temperature
|
||||
public static final String TEMPERATURE_EVENT_TABLE = "DEVICE_TEMPERATURE_SUMMARY";
|
||||
public static final String DATA_SOURCE_NAME = "jdbc/VirtualFireAlarmDM_DB";
|
||||
public final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super";
|
||||
|
||||
//tranport related constants
|
||||
public static final String ADAPTER_NAME = "virtual_firealarm_mqtt";
|
||||
public static final String ADAPTER_TYPE = "oauth-mqtt";
|
||||
//mqtt tranport related constants
|
||||
public static final String MQTT_ADAPTER_NAME = "virtual_firealarm_mqtt";
|
||||
public static final String MQTT_ADAPTER_TYPE = "oauth-mqtt";
|
||||
public static final String ADAPTER_TOPIC_PROPERTY = "topic";
|
||||
public static final String MQTT_PORT = "\\$\\{mqtt.broker.port\\}";
|
||||
public static final String MQTT_BROKER_HOST = "\\$\\{mqtt.broker.host\\}";
|
||||
@ -45,6 +45,15 @@ public class VirtualFireAlarmConstants {
|
||||
public static final int CARBON_DEFAULT_PORT_OFFSET = 0;
|
||||
public static final int DEFAULT_MQTT_PORT = 1883;
|
||||
|
||||
//xmpp transport related constants
|
||||
public static final String XMPP_ADAPTER_NAME = "virtual_firealarm_xmpp";
|
||||
public static final String XMPP_ADAPTER_TYPE = "xmpp";
|
||||
public static final String PASSWORD_PROPERTY_KEY = "password";
|
||||
public static final String JID_PROPERTY_KEY = "jid";
|
||||
public static final String SUBJECT_PROPERTY_KEY = "subject";
|
||||
public static final String MESSAGE_TYPE_PROPERTY_KEY = "messageType";
|
||||
public static final String CHAT_PROPERTY_KEY = "chat";
|
||||
|
||||
public static final String USERNAME_PROPERTY_KEY = "username";
|
||||
public static final String DCR_PROPERTY_KEY = "dcrUrl";
|
||||
public static final String BROKER_URL_PROPERTY_KEY = "url";
|
||||
@ -52,4 +61,22 @@ public class VirtualFireAlarmConstants {
|
||||
public static final String QOS_PROPERTY_KEY = "qos";
|
||||
public static final String CLIENT_ID_PROPERTY_KEY = "qos";
|
||||
public static final String CLEAR_SESSION_PROPERTY_KEY = "clearSession";
|
||||
public static final String TOPIC = "topic";
|
||||
public static final String SUBSCRIBED_TOPIC = "carbon.super/virtual_firealarm/+/publisher";
|
||||
|
||||
public static final String CONTENT_VALIDATION = "contentValidation";
|
||||
public static final String CONTENT_TRANSFORMATION = "contentTransformer";
|
||||
|
||||
public static final String 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";
|
||||
}
|
||||
|
||||
@ -18,19 +18,27 @@
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.base.ServerConfiguration;
|
||||
import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException;
|
||||
import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService;
|
||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
import org.wso2.carbon.core.util.Utils;
|
||||
import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException;
|
||||
import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.internal.VirtualFirealarmManagementDataHolder;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppConfig;
|
||||
import org.wso2.carbon.event.input.adapter.core.InputEventAdapterConfiguration;
|
||||
import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterException;
|
||||
import org.wso2.carbon.event.output.adapter.core.MessageType;
|
||||
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration;
|
||||
import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException;
|
||||
import org.wso2.carbon.utils.CarbonUtils;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NamingException;
|
||||
@ -38,6 +46,8 @@ import javax.sql.DataSource;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
@ -53,8 +63,8 @@ public class VirtualFireAlarmUtils {
|
||||
|
||||
private static Log log = LogFactory.getLog(VirtualFireAlarmUtils.class);
|
||||
private static final String VIRTUAL_FIREALARM_CONFIG_LOCATION =
|
||||
CarbonUtils.getCarbonHome() + File.separator + "repository" + File.separator + "resources" +
|
||||
File.separator + "device-types" + File.separator + "virtual-firealarm.properties";
|
||||
CarbonUtils.getCarbonHome() + File.separator + "repository" + File.separator + "conf" +
|
||||
File.separator + "iot" + File.separator + "mqtt.properties";
|
||||
|
||||
public static void cleanupResources(Connection conn, PreparedStatement stmt, ResultSet rs) {
|
||||
if (rs != null) {
|
||||
@ -103,10 +113,10 @@ public class VirtualFireAlarmUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void setupOutputAdapter() throws IOException {
|
||||
public static void setupMqttOutputAdapter() throws IOException {
|
||||
OutputEventAdapterConfiguration outputEventAdapterConfiguration =
|
||||
createOutputEventAdapterConfiguration(VirtualFireAlarmConstants.ADAPTER_NAME,
|
||||
VirtualFireAlarmConstants.ADAPTER_TYPE, MessageType.TEXT);
|
||||
createMqttOutputEventAdapterConfiguration(VirtualFireAlarmConstants.MQTT_ADAPTER_NAME,
|
||||
VirtualFireAlarmConstants.MQTT_ADAPTER_TYPE, MessageType.TEXT);
|
||||
try {
|
||||
PrivilegedCarbonContext.startTenantFlow();
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
|
||||
@ -114,7 +124,24 @@ public class VirtualFireAlarmUtils {
|
||||
VirtualFirealarmManagementDataHolder.getInstance().getOutputEventAdapterService()
|
||||
.create(outputEventAdapterConfiguration);
|
||||
} 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 {
|
||||
PrivilegedCarbonContext.endTenantFlow();
|
||||
}
|
||||
@ -128,9 +155,8 @@ public class VirtualFireAlarmUtils {
|
||||
* @param msgFormat Output Event Adapter message format
|
||||
* @return OutputEventAdapterConfiguration instance for given configuration
|
||||
*/
|
||||
private static OutputEventAdapterConfiguration createOutputEventAdapterConfiguration(String name, String type,
|
||||
String msgFormat)
|
||||
throws IOException {
|
||||
private static OutputEventAdapterConfiguration createMqttOutputEventAdapterConfiguration(String name, String type,
|
||||
String msgFormat) throws IOException {
|
||||
OutputEventAdapterConfiguration outputEventAdapterConfiguration = new OutputEventAdapterConfiguration();
|
||||
outputEventAdapterConfiguration.setName(name);
|
||||
outputEventAdapterConfiguration.setType(type);
|
||||
@ -153,14 +179,55 @@ public class VirtualFireAlarmUtils {
|
||||
VirtualFireAlarmConstants.CLEAR_SESSION_PROPERTY_KEY));
|
||||
mqttAdapterProperties.put(VirtualFireAlarmConstants.QOS_PROPERTY_KEY, properties.getProperty(
|
||||
VirtualFireAlarmConstants.QOS_PROPERTY_KEY));
|
||||
mqttAdapterProperties.put(VirtualFireAlarmConstants.CLIENT_ID_PROPERTY_KEY, properties.getProperty(
|
||||
VirtualFireAlarmConstants.CLIENT_ID_PROPERTY_KEY));
|
||||
mqttAdapterProperties.put(VirtualFireAlarmConstants.CLIENT_ID_PROPERTY_KEY, "");
|
||||
outputEventAdapterConfiguration.setStaticProperties(mqttAdapterProperties);
|
||||
}
|
||||
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 = urlWithPlaceholders.replaceAll(VirtualFireAlarmConstants.MQTT_PORT, "" +
|
||||
(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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -16,14 +16,14 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util;
|
||||
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException;
|
||||
import org.wso2.carbon.certificate.mgt.core.util.ConfigurationUtil;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
@ -47,18 +47,18 @@ import java.security.UnrecoverableKeyException;
|
||||
import java.security.cert.CertificateException;
|
||||
|
||||
|
||||
public class SecurityManager {
|
||||
private static final Log log = LogFactory.getLog(SecurityManager.class);
|
||||
public class VirtualFirealarmSecurityManager {
|
||||
private static final Log log = LogFactory.getLog(VirtualFirealarmSecurityManager.class);
|
||||
|
||||
private static PrivateKey serverPrivateKey;
|
||||
private static final String SIGNATURE_ALG = "SHA1withRSA";
|
||||
private static final String CIPHER_PADDING = "RSA/ECB/PKCS1Padding";
|
||||
|
||||
private SecurityManager() {
|
||||
private VirtualFirealarmSecurityManager() {
|
||||
|
||||
}
|
||||
|
||||
public void initVerificationManager() {
|
||||
public static void initVerificationManager() {
|
||||
serverPrivateKey = retrievePrivateKey(ConfigurationUtil.CA_CERT_ALIAS,
|
||||
ConfigurationUtil.KEYSTORE_CA_CERT_PRIV_PASSWORD);
|
||||
}
|
||||
@ -117,7 +117,8 @@ public class SecurityManager {
|
||||
return serverPrivateKey;
|
||||
}
|
||||
|
||||
public static String encryptMessage(String message, Key encryptionKey) throws VirtualFireAlarmException {
|
||||
public static String encryptMessage(String message, Key encryptionKey) throws
|
||||
VirtualFirealarmDeviceMgtPluginException {
|
||||
Cipher encrypter;
|
||||
byte[] cipherData;
|
||||
|
||||
@ -129,30 +130,29 @@ public class SecurityManager {
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
String errorMsg = "Algorithm not found exception occurred for Cipher instance of [" + CIPHER_PADDING + "]";
|
||||
log.error(errorMsg);
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
|
||||
} catch (NoSuchPaddingException e) {
|
||||
String errorMsg = "No Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
|
||||
log.error(errorMsg);
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
|
||||
} catch (InvalidKeyException e) {
|
||||
String errorMsg = "InvalidKey exception occurred for encryptionKey \n[\n" + encryptionKey + "\n]\n";
|
||||
log.error(errorMsg);
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
|
||||
} catch (BadPaddingException e) {
|
||||
String errorMsg = "Bad Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
|
||||
log.error(errorMsg);
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
String errorMsg = "Illegal blockSize error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
|
||||
log.error(errorMsg);
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
|
||||
}
|
||||
|
||||
return Base64.encodeBase64String(cipherData);
|
||||
}
|
||||
|
||||
|
||||
public static String signMessage(String encryptedData, PrivateKey signatureKey) throws VirtualFireAlarmException {
|
||||
public static String signMessage(String encryptedData, PrivateKey signatureKey) throws VirtualFirealarmDeviceMgtPluginException {
|
||||
|
||||
Signature signature;
|
||||
String signedEncodedString;
|
||||
@ -168,23 +168,22 @@ public class SecurityManager {
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
String errorMsg = "Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
|
||||
log.error(errorMsg);
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
|
||||
} catch (SignatureException e) {
|
||||
String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
|
||||
log.error(errorMsg);
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
|
||||
} catch (InvalidKeyException e) {
|
||||
String errorMsg = "InvalidKey exception occurred for signatureKey \n[\n" + signatureKey + "\n]\n";
|
||||
log.error(errorMsg);
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
|
||||
}
|
||||
|
||||
return signedEncodedString;
|
||||
}
|
||||
|
||||
|
||||
public static boolean verifySignature(String data, String signedData, PublicKey verificationKey)
|
||||
throws VirtualFireAlarmException {
|
||||
throws VirtualFirealarmDeviceMgtPluginException {
|
||||
|
||||
Signature signature;
|
||||
boolean verified;
|
||||
@ -199,22 +198,21 @@ public class SecurityManager {
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
String errorMsg = "Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
|
||||
log.error(errorMsg);
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
|
||||
} catch (SignatureException e) {
|
||||
String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
|
||||
log.error(errorMsg);
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
|
||||
} catch (InvalidKeyException e) {
|
||||
String errorMsg = "InvalidKey exception occurred for signatureKey \n[\n" + verificationKey + "\n]\n";
|
||||
log.error(errorMsg);
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
|
||||
}
|
||||
|
||||
return verified;
|
||||
}
|
||||
|
||||
|
||||
public static String decryptMessage(String encryptedMessage, Key decryptKey) throws VirtualFireAlarmException {
|
||||
public static String decryptMessage(String encryptedMessage, Key decryptKey) throws VirtualFirealarmDeviceMgtPluginException {
|
||||
|
||||
Cipher decrypter;
|
||||
String decryptedMessage;
|
||||
@ -228,23 +226,23 @@ public class SecurityManager {
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
String errorMsg = "Algorithm not found exception occurred for Cipher instance of [" + CIPHER_PADDING + "]";
|
||||
log.error(errorMsg);
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
|
||||
} catch (NoSuchPaddingException e) {
|
||||
String errorMsg = "No Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
|
||||
log.error(errorMsg);
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
|
||||
} catch (InvalidKeyException e) {
|
||||
String errorMsg = "InvalidKey exception occurred for encryptionKey \n[\n" + decryptKey + "\n]\n";
|
||||
log.error(errorMsg);
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
|
||||
} catch (BadPaddingException e) {
|
||||
String errorMsg = "Bad Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
|
||||
log.error(errorMsg);
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
String errorMsg = "Illegal blockSize error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
|
||||
log.error(errorMsg);
|
||||
throw new VirtualFireAlarmException(errorMsg, e);
|
||||
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
|
||||
}
|
||||
|
||||
return decryptedMessage;
|
||||
@ -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.LogFactory;
|
||||
import org.wso2.carbon.core.ServerStartupObserver;
|
||||
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@ -34,7 +35,12 @@ public class VirtualFirealarmStartupListener implements ServerStartupObserver {
|
||||
@Override
|
||||
public void completedServerStartup() {
|
||||
try {
|
||||
VirtualFireAlarmUtils.setupOutputAdapter();
|
||||
XmppUtil.createXMPPAccountForDeviceType();
|
||||
VirtualFireAlarmUtils.setupMqttOutputAdapter();
|
||||
VirtualFireAlarmUtils.setupMqttInputAdapter();
|
||||
VirtualFireAlarmUtils.setupXmppInputAdapter();
|
||||
VirtualFireAlarmUtils.setupXmppOutputAdapter();
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to intilaize the virtual firealarm output adapter", e);
|
||||
}
|
||||
|
||||
@ -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
Loading…
Reference in New Issue
Block a user