refactored device type after adapter changes

revert-dabc3590
ayyoob 9 years ago
parent 10f75d5f73
commit f880bda706

@ -17,7 +17,7 @@
~ under the License.
-->
<eventReceiver name="EventReceiver_AndroidSense" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver">
<eventReceiver name="android_sense_mqtt" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver">
<from eventAdapterType="oauth-mqtt">
<property name="topic">carbon.super/android_sense/+/data</property>
<property name="username">admin</property>

@ -17,6 +17,6 @@
~ under the License.
-->
<artifact name="EventReceiver_AndroidSense" version="1.0.0" type="event/receiver" serverRole="DataAnalyticsServer">
<artifact name="android_sense_mqtt" version="1.0.0" type="event/receiver" serverRole="DataAnalyticsServer">
<file>EventReceiver_AndroidSense.xml</file>
</artifact>

@ -20,7 +20,7 @@
<artifacts>
<artifact name="AndroidSense_CAPP" version="1.0.0" type="carbon/application">
<dependency artifact="EventStream_AndroidSense" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
<dependency artifact="EventReceiver_AndroidSense" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
<dependency artifact="android_sense_mqtt" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
<dependency artifact="EventPublisher_AndroidSense" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
<dependency artifact="EventExecution_AndroidSense" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
</artifact>

@ -23,17 +23,12 @@ import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.analytics.dataservice.commons.SORT;
import org.wso2.carbon.analytics.dataservice.commons.SortByField;
import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants;
import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.transport.AndroidSenseMQTTConnector;
import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.SensorRecord;
import org.wso2.carbon.device.mgt.iot.androidsense.plugin.constants.AndroidSenseConstants;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.service.IoTServerStartupListener;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;

@ -26,11 +26,11 @@ import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants;
import org.wso2.carbon.device.mgt.iot.androidsense.plugin.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.androidsense.plugin.constants.AndroidSenseConstants;
import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.AndroidConfiguration;
import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.Constants;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.exception.IoTException;
import org.wso2.carbon.device.mgt.iot.util.IoTUtil;
@ -61,7 +61,7 @@ public class AndroidSenseManagerServiceImpl implements AndroidSenseManagerServic
if (APIUtil.getDeviceManagementService().isEnrolled(deviceIdentifier)) {
AndroidConfiguration androidConfiguration = new AndroidConfiguration();
androidConfiguration.setTenantDomain(APIUtil.getAuthenticatedUserTenantDomain());
String mqttEndpoint = MqttConfig.getInstance().getMqttQueueEndpoint();
String mqttEndpoint = MqttConfig.getInstance().getBrokerEndpoint();
if (mqttEndpoint.contains(Constants.LOCALHOST)) {
mqttEndpoint = mqttEndpoint.replace(Constants.LOCALHOST, IoTUtil.getHostName());
}
@ -84,7 +84,7 @@ public class AndroidSenseManagerServiceImpl implements AndroidSenseManagerServic
if (added) {
AndroidConfiguration androidConfiguration = new AndroidConfiguration();
androidConfiguration.setTenantDomain(APIUtil.getAuthenticatedUserTenantDomain());
String mqttEndpoint = MqttConfig.getInstance().getMqttQueueEndpoint();
String mqttEndpoint = MqttConfig.getInstance().getBrokerEndpoint();
if (mqttEndpoint.contains(Constants.LOCALHOST)) {
mqttEndpoint = mqttEndpoint.replace(Constants.LOCALHOST, IoTUtil.getHostName());
}

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

@ -62,7 +62,13 @@
org.wso2.carbon.device.mgt.common,
org.wso2.carbon.device.mgt.iot.*,
org.wso2.carbon.device.mgt.extensions.feature.mgt.*,
org.wso2.carbon.utils.*
org.wso2.carbon.utils.*,
org.wso2.carbon.base,
org.wso2.carbon.context,
org.wso2.carbon.core,
org.wso2.carbon.core.util,
org.wso2.carbon.event.output.adapter.core,
org.wso2.carbon.event.output.adapter.core.exception
</Import-Package>
<Export-Package>
!org.wso2.carbon.device.mgt.iot.androidsense.plugin.internal,

@ -16,6 +16,10 @@
package org.wso2.carbon.device.mgt.iot.androidsense.plugin.constants;
import org.wso2.carbon.utils.CarbonUtils;
import java.io.File;
public class AndroidSenseConstants {
public final static String DEVICE_TYPE = "android_sense";
@ -70,4 +74,7 @@ public class AndroidSenseConstants {
public static final String CLIENT_ID_PROPERTY_KEY = "qos";
public static final String CLEAR_SESSION_PROPERTY_KEY = "clearSession";
public static final String TOPIC = "topic";
public static final String MQTT_CONFIG_LOCATION = CarbonUtils.getEtcCarbonConfigDirPath() + File.separator
+ "mqtt.properties";
}

@ -50,7 +50,7 @@ public class AndroidSenseManagerService implements DeviceManagementService {
@Override
public ProvisioningConfig getProvisioningConfig() {
return new ProvisioningConfig(AndroidSenseConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true);
return new ProvisioningConfig(AndroidSenseConstants.DEVICE_TYPE_PROVIDER_DOMAIN, false);
}
@Override

@ -21,14 +21,12 @@ 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.androidsense.plugin.constants.AndroidSenseConstants;
import org.wso2.carbon.device.mgt.iot.androidsense.plugin.exception.AndroidSenseDeviceMgtPluginException;
import org.wso2.carbon.device.mgt.iot.androidsense.plugin.internal.AndroidSenseManagementDataHolder;
import org.wso2.carbon.event.output.adapter.core.MessageType;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration;
import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException;
import org.wso2.carbon.utils.CarbonUtils;
import javax.naming.Context;
import javax.naming.InitialContext;
@ -42,7 +40,6 @@ 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;
@ -53,10 +50,6 @@ public class AndroidSenseUtils {
private static Log log = LogFactory.getLog(AndroidSenseUtils.class);
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) {
try {
@ -131,12 +124,12 @@ public class AndroidSenseUtils {
* @return OutputEventAdapterConfiguration instance for given configuration
*/
private static OutputEventAdapterConfiguration createMqttOutputEventAdapterConfiguration(String name, String type,
String msgFormat) throws IOException {
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);
File configFile = new File(AndroidSenseConstants.MQTT_CONFIG_LOCATION);
if (configFile.exists()) {
Map<String, String> mqttAdapterProperties = new HashMap<>();
InputStream propertyStream = configFile.toURI().toURL().openStream();
@ -160,7 +153,7 @@ public class AndroidSenseUtils {
return outputEventAdapterConfiguration;
}
private static String replaceMqttProperty(String urlWithPlaceholders) {
public static String replaceMqttProperty(String urlWithPlaceholders) {
urlWithPlaceholders = Utils.replaceSystemProperty(urlWithPlaceholders);
urlWithPlaceholders = urlWithPlaceholders.replaceAll(AndroidSenseConstants.MQTT_PORT, "" +
(AndroidSenseConstants.DEFAULT_MQTT_PORT + getPortOffset()));

@ -21,9 +21,11 @@ import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext;
import org.wso2.carbon.core.ServerStartupObserver;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.iot.androidsense.plugin.exception.AndroidSenseDeviceMgtPluginException;
import org.wso2.carbon.device.mgt.iot.androidsense.plugin.impl.AndroidSenseManagerService;
import org.wso2.carbon.device.mgt.iot.androidsense.plugin.impl.util.AndroidSenseStartupListener;
import org.wso2.carbon.device.mgt.iot.androidsense.plugin.impl.util.AndroidSenseUtils;
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
@ -50,6 +52,8 @@ public class AndroidSenseManagementServiceComponent {
BundleContext bundleContext = ctx.getBundleContext();
androidServiceRegRef =
bundleContext.registerService(DeviceManagementService.class.getName(), new AndroidSenseManagerService(), null);
bundleContext.registerService(ServerStartupObserver.class.getName(), new AndroidSenseStartupListener(),
null);
String setupOption = System.getProperty("setup");
if (setupOption != null) {
if (log.isDebugEnabled()) {

@ -0,0 +1,60 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.androidsense.plugin.mqtt;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.iot.androidsense.plugin.constants.AndroidSenseConstants;
import org.wso2.carbon.device.mgt.iot.androidsense.plugin.impl.util.AndroidSenseUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class MqttConfig {
private static String brokerEndpoint;
private static MqttConfig mqttConfig = new MqttConfig();
private static final Log log = LogFactory.getLog(MqttConfig.class);
private MqttConfig() {
File configFile = new File(AndroidSenseConstants.MQTT_CONFIG_LOCATION);
if (configFile.exists()) {
try {
InputStream propertyStream = configFile.toURI().toURL().openStream();
Properties properties = new Properties();
properties.load(propertyStream);
brokerEndpoint = AndroidSenseUtils.replaceMqttProperty(
properties.getProperty(AndroidSenseConstants.BROKER_URL_PROPERTY_KEY));
} catch (IOException e) {
log.error("Failed to read the mqtt.properties file" + e);
}
}
}
public static MqttConfig getInstance() {
return mqttConfig;
}
public String getBrokerEndpoint() {
return brokerEndpoint;
}
}

@ -32,7 +32,6 @@ import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.iot.arduino.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.arduino.plugin.constants.ArduinoConstants;
import org.wso2.carbon.device.mgt.iot.arduino.service.impl.util.ZipUtil;
import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
import org.wso2.carbon.device.mgt.iot.util.ZipArchive;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
@ -172,9 +171,6 @@ public class ArduinoManagerServiceImpl implements ArduinoManagerService {
} catch (APIManagerException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (DeviceControllerException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (IOException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
@ -185,7 +181,7 @@ public class ArduinoManagerServiceImpl implements ArduinoManagerService {
}
private ZipArchive createDownloadFile(String owner, String deviceName)
throws DeviceManagementException, JWTClientException, DeviceControllerException, APIManagerException,
throws DeviceManagementException, JWTClientException, APIManagerException,
UserStoreException {
if (owner == null) {
throw new IllegalArgumentException("Error on createDownloadFile() Owner is null!");

@ -19,8 +19,6 @@
package org.wso2.carbon.device.mgt.iot.arduino.service.impl.util;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig;
import org.wso2.carbon.device.mgt.iot.exception.IoTException;
import org.wso2.carbon.device.mgt.iot.util.IoTUtil;
import org.wso2.carbon.device.mgt.iot.util.IotDeviceManagementUtil;

@ -54,7 +54,7 @@ public class ArduinoManagerService implements DeviceManagementService {
@Override
public ProvisioningConfig getProvisioningConfig() {
return new ProvisioningConfig(DEVICE_TYPE_PROVIDER_DOMAIN, true);
return new ProvisioningConfig(DEVICE_TYPE_PROVIDER_DOMAIN, false);
}
@Override

@ -63,28 +63,15 @@
<Bundle-Description>IoT Server Impl Bundle</Bundle-Description>
<Private-Package>org.wso2.carbon.device.mgt.iot.internal</Private-Package>
<Import-Package>
org.jivesoftware.smack.*,
javax.xml.namespace;resolution:=optional,
javax.xml.validation;resolution:=optional,
org.apache.commons.codec.binary,
org.apache.http.*,
org.apache.commons.io.*,
org.apache.commons.logging.*,
org.json;version="${commons-json.version}",
org.wso2.carbon.base.*,
org.osgi.framework,
org.osgi.service.component,
javax.xml.bind.*;resolution:=optional,
javax.xml.parsers.*;resolution:=optional,
javax.crypto,
org.apache.tomcat.util.codec.binary,
org.w3c.dom;resolution:=optional,
org.wso2.carbon.core;version="${carbon.kernel.version.range}",
org.wso2.carbon.utils.*;version="${carbon.kernel.version.range}",
org.wso2.carbon.device.mgt.common.*,
org.eclipse.paho.client.mqttv3.*;version="${eclipse.paho.version}",
javax.xml;resolution:=optional,
javax.net.ssl;resolution:=optional
org.apache.axis2.context,
org.apache.commons.io,
org.apache.commons.logging,
org.wso2.carbon.core,
org.wso2.carbon.device.mgt.common,
org.wso2.carbon.utils
</Import-Package>
<Export-Package>
!org.wso2.carbon.device.mgt.iot.internal,

@ -1,118 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.config.server;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.wso2.carbon.device.mgt.iot.config.server.datasource.ControlQueue;
import org.wso2.carbon.device.mgt.iot.config.server.datasource.DeviceManagementConfiguration;
import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
import org.wso2.carbon.device.mgt.iot.util.IotDeviceManagementUtil;
import org.wso2.carbon.utils.CarbonUtils;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import java.io.File;
import java.util.List;
/**
* Class responsible for the iot device manager configuration initialization.
*/
public class DeviceManagementConfigurationManager {
private static final Log log = LogFactory.getLog(DeviceManagementConfigurationManager.class);
private static final String DEVICE_MGT_CONFIG_XML_NAME = "devicemgt-config.xml";
private static final String DEVICE_MGT_ROOT_DIRECTORY = "iot";
private final String XMLCONFIGS_FILE_LOCATION =
CarbonUtils.getCarbonConfigDirPath() + File.separator +
DEVICE_MGT_ROOT_DIRECTORY + File.separator + DEVICE_MGT_CONFIG_XML_NAME;
private static final String IOT_DEVICE_CONFIG_XSD_NAME = "devicemgt-config.xsd";
private final String XSDCONFIGS_FILE_LOCATION =
CarbonUtils.getCarbonConfigDirPath() + File.separator +
DEVICE_MGT_ROOT_DIRECTORY + File.separator + IOT_DEVICE_CONFIG_XSD_NAME;
private DeviceManagementConfiguration currentDeviceManagementConfiguration;
private static DeviceManagementConfigurationManager deviceConfigurationManager =
new DeviceManagementConfigurationManager();
private DeviceManagementConfigurationManager() {
}
public static DeviceManagementConfigurationManager getInstance() {
return deviceConfigurationManager;
}
public void initConfig() throws DeviceControllerException {
try {
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File(XSDCONFIGS_FILE_LOCATION));
File deviceCloudMgtConfig = new File(XMLCONFIGS_FILE_LOCATION);
Document doc = IotDeviceManagementUtil.convertToDocument(deviceCloudMgtConfig);
JAXBContext deviceCloudContext = JAXBContext.newInstance(DeviceManagementConfiguration.class);
Unmarshaller unmarshaller = deviceCloudContext.createUnmarshaller();
unmarshaller.setSchema(schema);
unmarshaller.setEventHandler(new IotConfigValidationEventHandler());
this.currentDeviceManagementConfiguration = (DeviceManagementConfiguration) unmarshaller.unmarshal(doc);
} catch (Exception e) {
String error = "Error occurred while initializing DeviceController configurations";
log.error(error);
throw new DeviceControllerException(error, e);
}
}
public DeviceManagementConfiguration getDeviceCloudMgtConfig() {
return currentDeviceManagementConfiguration;
}
public ControlQueue getControlQueue(String name) {
List<ControlQueue> controlQueues = currentDeviceManagementConfiguration.getControlQueues().getControlQueue();
if (controlQueues != null) {
for (ControlQueue controlQueue : controlQueues) {
if (controlQueue.getName().equals(name)) {
return controlQueue;
}
}
}
return null;
}
private class IotConfigValidationEventHandler implements ValidationEventHandler {
@Override
public boolean handleEvent(ValidationEvent event) {
String error = "\nEVENT" + "\nSEVERITY: " + event.getSeverity()
+ "\n MESSAGE: " + event.getMessage()
+ "\n LINKED EXCEPTION: " + event.getLinkedException()
+ "\n LOCATOR"
+ "\n LINE NUMBER: " + event.getLocator().getLineNumber()
+ "\n COLUMN NUMBER: " + event.getLocator().getColumnNumber()
+ "\n OFFSET: " + event.getLocator().getOffset()
+ "\n OBJECT: " + event.getLocator().getObject()
+ "\n NODE: " + event.getLocator().getNode()
+ "\n URL: " + event.getLocator().getURL();
log.error(error);
return true;
}
}
}

@ -1,229 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.config.server.datasource;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for ControlQueue complex type.
* <p/>
* <p>The following schema fragment specifies the expected content contained within this class.
* <p/>
* <pre>
* &lt;complexType name="ControlQueue">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="Name" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;element name="Enabled" type="{http://www.w3.org/2001/XMLSchema}boolean"/>
* &lt;element name="ControlClass" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;element name="Protocol" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;element name="ServerURL" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;element name="Port" type="{http://www.w3.org/2001/XMLSchema}short"/>
* &lt;element name="Username" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;element name="Password" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ControlQueue", propOrder = {
"name",
"enabled",
"controlClass",
"protocol",
"serverURL",
"port",
"username",
"password"
})
public class ControlQueue {
@XmlElement(name = "Name", required = true)
protected String name;
@XmlElement(name = "Enabled")
protected boolean enabled;
@XmlElement(name = "ControlClass", required = true)
protected String controlClass;
@XmlElement(name = "Protocol", required = true)
protected String protocol;
@XmlElement(name = "ServerURL", required = true)
protected String serverURL;
@XmlElement(name = "Port")
protected short port;
@XmlElement(name = "Username", required = true)
protected String username;
@XmlElement(name = "Password", required = true)
protected String password;
/**
* Gets the value of the name property.
*
* @return possible object is
* {@link String }
*/
public String getName() {
return name;
}
/**
* Sets the value of the name property.
*
* @param value allowed object is
* {@link String }
*/
public void setName(String value) {
this.name = value;
}
/**
* Gets the value of the enabled property.
*/
public boolean isEnabled() {
return enabled;
}
/**
* Sets the value of the enabled property.
*/
public void setEnabled(boolean value) {
this.enabled = value;
}
/**
* Gets the value of the controlClass property.
*
* @return possible object is
* {@link String }
*/
public String getControlClass() {
return controlClass;
}
/**
* Sets the value of the controlClass property.
*
* @param value allowed object is
* {@link String }
*/
public void setControlClass(String value) {
this.controlClass = value;
}
/**
* Gets the value of the protocol property.
*
* @return possible object is
* {@link String }
*/
public String getProtocol() {
return protocol;
}
/**
* Sets the value of the protocol property.
*
* @param value allowed object is
* {@link String }
*/
public void setProtocol(String value) {
this.protocol = value;
}
/**
* Gets the value of the serverURL property.
*
* @return possible object is
* {@link String }
*/
public String getServerURL() {
return serverURL;
}
/**
* Sets the value of the serverURL property.
*
* @param value allowed object is
* {@link String }
*/
public void setServerURL(String value) {
this.serverURL = value;
}
/**
* Gets the value of the port property.
*/
public short getPort() {
return port;
}
/**
* Sets the value of the port property.
*/
public void setPort(short value) {
this.port = value;
}
/**
* Gets the value of the username property.
*
* @return possible object is
* {@link String }
*/
public String getUsername() {
return username;
}
/**
* Sets the value of the username property.
*
* @param value allowed object is
* {@link String }
*/
public void setUsername(String value) {
this.username = value;
}
/**
* Gets the value of the password property.
*
* @return possible object is
* {@link String }
*/
public String getPassword() {
return password;
}
/**
* Sets the value of the password property.
*
* @param value allowed object is
* {@link String }
*/
public void setPassword(String value) {
this.password = value;
}
}

@ -1,82 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.config.server.datasource;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for ControlQueuesConfig complex type.
* <p/>
* <p>The following schema fragment specifies the expected content contained within this class.
* <p/>
* <pre>
* &lt;complexType name="ControlQueuesConfig">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="ControlQueue" type="{}ControlQueue" maxOccurs="unbounded" minOccurs="0"/>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ControlQueuesConfig", propOrder = {
"controlQueue"
})
public class ControlQueuesConfig {
@XmlElement(name = "ControlQueue")
protected List<ControlQueue> controlQueue;
/**
* Gets the value of the controlQueue property.
* <p/>
* <p/>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the controlQueue property.
* <p/>
* <p/>
* For example, to add a new item, do as follows:
* <pre>
* getControlQueue().add(newItem);
* </pre>
* <p/>
* <p/>
* <p/>
* Objects of the following type(s) are allowed in the list
* {@link ControlQueue }
*/
public List<ControlQueue> getControlQueue() {
if (controlQueue == null) {
controlQueue = new ArrayList<ControlQueue>();
}
return this.controlQueue;
}
}

@ -1,74 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.config.server.datasource;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for DeviceCloudConfig complex type.
* <p/>
* <p>The following schema fragment specifies the expected content contained within this class.
* <p/>
* <pre>
* &lt;complexType name="DeviceManagementConfigurations">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="ControlQueues" type="{}ControlQueuesConfig"/>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "DeviceManagementConfigurations", propOrder = {
"controlQueues"
})
@XmlRootElement(name = "DeviceManagementConfigurations")
public class DeviceManagementConfiguration {
@XmlElement(name = "ControlQueues", required = true)
protected ControlQueuesConfig controlQueues;
/**
* Gets the value of the controlQueues property.
*
* @return possible object is
* {@link ControlQueuesConfig }
*/
public ControlQueuesConfig getControlQueues() {
return controlQueues;
}
/**
* Sets the value of the controlQueues property.
*
* @param value allowed object is
* {@link ControlQueuesConfig }
*/
public void setControlQueues(ControlQueuesConfig value) {
this.controlQueues = value;
}
}

@ -1,69 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.config.server.datasource;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;
/**
* This object contains factory methods for each
* Java content interface and Java element interface
* generated in the org.wso2.carbon.device.mgt.iot.common.config.server.configs package.
* <p>An ObjectFactory allows you to programatically
* construct new instances of the Java representation
* for XML content. The Java representation of XML
* content can consist of schema derived interfaces
* and classes representing the binding of schema
* type definitions, element declarations and model
* groups. Factory methods for each of these are
* provided in this class.
*/
@XmlRegistry
public class ObjectFactory {
private final static QName _DeviceCloudConfiguration_QNAME = new QName("", "DeviceManagementConfigurations");
/**
* Create a new ObjectFactory that can be used to create new instances of schema derived classes for package:
* org.wso2.carbon.device.mgt.iot.common.config.server.configs
*/
public ObjectFactory() {
}
/**
* Create an instance of {@link DeviceManagementConfiguration }
*/
public DeviceManagementConfiguration createDeviceCloudConfig() {
return new DeviceManagementConfiguration();
}
/**
* Create an instance of {@link JAXBElement }{@code <}{@link DeviceManagementConfiguration }{@code >}}
*/
@XmlElementDecl(namespace = "", name = "DeviceManagementConfigurations")
public JAXBElement<DeviceManagementConfiguration> createDeviceCloudConfiguration(
DeviceManagementConfiguration value) {
return new JAXBElement<DeviceManagementConfiguration>(_DeviceCloudConfiguration_QNAME,
DeviceManagementConfiguration.class, null, value);
}
}

@ -1,81 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.controlqueue.mqtt;
import org.wso2.carbon.device.mgt.iot.config.server.DeviceManagementConfigurationManager;
import org.wso2.carbon.device.mgt.iot.config.server.datasource.ControlQueue;
public class MqttConfig {
private String mqttQueueEndpoint;
private String mqttQueueUsername;
private String mqttQueuePassword;
private boolean isEnabled;
private static final String MQTT_QUEUE_CONFIG_NAME = "MQTT";
private static final String LOCALHOST = "localhost";
private static final String PORT_OFFSET_PROPERTY = "portOffset";
private ControlQueue mqttControlQueue;
private static MqttConfig mqttConfig = new MqttConfig();
public String getMqttQueueEndpoint() {
return mqttQueueEndpoint;
}
public String getMqttQueueUsername() {
return mqttQueueUsername;
}
public String getMqttQueuePassword() {
return mqttQueuePassword;
}
public ControlQueue getMqttControlQueue() {
return mqttControlQueue;
}
public boolean isEnabled() {
return isEnabled;
}
public static String getMqttQueueConfigName() {
return MQTT_QUEUE_CONFIG_NAME;
}
private MqttConfig() {
mqttControlQueue = DeviceManagementConfigurationManager.getInstance().getControlQueue(MQTT_QUEUE_CONFIG_NAME);
int portOffset = Integer.parseInt(System.getProperty(PORT_OFFSET_PROPERTY));
String brokerURL = mqttControlQueue.getServerURL();
if (portOffset != 0 && brokerURL.contains(LOCALHOST)) {
// if using the internal MB (meaning URL is localhost and there is a portOffset)
// then increment port accordingly
int mqttPort = mqttControlQueue.getPort();
mqttPort = mqttPort + portOffset;
mqttQueueEndpoint = mqttControlQueue.getServerURL() + ":" + mqttPort;
} else {
mqttQueueEndpoint = mqttControlQueue.getServerURL() + ":" + mqttControlQueue.getPort();
}
mqttQueueUsername = mqttControlQueue.getUsername();
mqttQueuePassword = mqttControlQueue.getPassword();
isEnabled = mqttControlQueue.isEnabled();
}
public static MqttConfig getInstance() {
return mqttConfig;
}
}

@ -1,60 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.controlqueue.xmpp;
public class XmppAccount {
private String username;
private String password;
private String accountName;
private String email;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}

@ -1,93 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.controlqueue.xmpp;
import org.wso2.carbon.device.mgt.iot.config.server.DeviceManagementConfigurationManager;
import org.wso2.carbon.device.mgt.iot.config.server.datasource.ControlQueue;
public class XmppConfig {
private String xmppServerIP;
private int xmppServerPort;
private String xmppEndpoint;
private String xmppUsername;
private String xmppPassword;
private boolean isEnabled;
private static final String XMPP_QUEUE_CONFIG_NAME = "XMPP";
private final int SERVER_CONNECTION_PORT = 5222;
private ControlQueue xmppControlQueue;
private static XmppConfig xmppConfig = new XmppConfig();
public String getXmppServerIP() {
return xmppServerIP;
}
public int getXmppServerPort() {
return xmppServerPort;
}
public String getXmppEndpoint() {
return xmppEndpoint;
}
public String getXmppUsername() {
return xmppUsername;
}
public String getXmppPassword() {
return xmppPassword;
}
public ControlQueue getXmppControlQueue() {
return xmppControlQueue;
}
public boolean isEnabled() {
return isEnabled;
}
public static String getXmppQueueConfigName() {
return XMPP_QUEUE_CONFIG_NAME;
}
private XmppConfig() {
xmppControlQueue = DeviceManagementConfigurationManager.getInstance().getControlQueue(
XMPP_QUEUE_CONFIG_NAME);
xmppServerIP = xmppControlQueue.getServerURL();
int indexOfChar = xmppServerIP.lastIndexOf('/');
if (indexOfChar != -1) {
xmppServerIP = xmppServerIP.substring((indexOfChar + 1), xmppServerIP.length());
}
xmppServerPort = xmppControlQueue.getPort();
xmppEndpoint = xmppControlQueue.getServerURL() + ":" + xmppServerPort;
xmppUsername = xmppControlQueue.getUsername();
xmppPassword = xmppControlQueue.getPassword();
isEnabled = xmppControlQueue.isEnabled();
}
public static XmppConfig getInstance() {
return xmppConfig;
}
public int getSERVER_CONNECTION_PORT() {
return SERVER_CONNECTION_PORT;
}
}

@ -1,352 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.controlqueue.xmpp;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
import org.wso2.carbon.device.mgt.iot.util.IoTUtil;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
public class XmppServerClient {
private static final Log log = LogFactory.getLog(XmppServerClient.class);
private static final String XMPP_SERVER_API_CONTEXT = "/plugins/restapi/v1";
private static final String XMPP_USERS_API = "/users";
private static final String XMPP_SESSIONS_API = "/sessions";
@SuppressWarnings("unused")
private static final String XMPP_GROUPS_API = "/groups";
@SuppressWarnings("unused")
private static final String APPLICATION_JSON_MT = "application/json";
private static final String DEVICEMGT_CONFIG_FILE = "devicemgt-config.xml";
private static final String APPLICATION_JSON = "application/json";
private String xmppEndpoint;
private String xmppUsername;
private String xmppPassword;
private boolean xmppEnabled = false;
public XmppServerClient() {
}
public void initControlQueue() {
xmppEndpoint = XmppConfig.getInstance().getXmppEndpoint();
xmppUsername = XmppConfig.getInstance().getXmppUsername();
xmppPassword = XmppConfig.getInstance().getXmppPassword();
xmppEnabled = XmppConfig.getInstance().isEnabled();
}
public boolean createXMPPAccount(XmppAccount newUserAccount) throws DeviceControllerException {
if (xmppEnabled) {
String xmppUsersAPIEndpoint = xmppEndpoint + XMPP_SERVER_API_CONTEXT + XMPP_USERS_API;
if (log.isDebugEnabled()) {
log.debug("The Create-UserAccount Endpoint URL of the XMPP Server is set to: " + xmppUsersAPIEndpoint);
}
String encodedString = xmppUsername + ":" + xmppPassword;
encodedString = new String(Base64.encodeBase64(encodedString.getBytes(StandardCharsets.UTF_8)));
String authorizationHeader = "Basic " + encodedString;
String jsonRequest = "{\n" +
" \"username\": \"" + newUserAccount.getUsername() + "\"," +
" \"password\": \"" + newUserAccount.getPassword() + "\"," +
" \"name\": \"" + newUserAccount.getAccountName() + "\"," +
" \"email\": \"" + newUserAccount.getEmail() + "\"," +
" \"properties\": {" +
" \"property\": [" +
" {" +
" \"@key\": \"console.rows_per_page\"," +
" \"@value\": \"user-summary=8\"" +
" }," +
" {" +
" \"@key\": \"console.order\"," +
" \"@value\": \"session-summary=1\"" +
" }" +
" ]" +
" }" +
"}";
StringEntity requestEntity;
try {
requestEntity = new StringEntity(jsonRequest, APPLICATION_JSON,
StandardCharsets.UTF_8.toString());
} catch (UnsupportedEncodingException e) {
return false;
}
URL xmppUserApiUrl;
try {
xmppUserApiUrl = new URL(xmppUsersAPIEndpoint);
} catch (MalformedURLException e) {
String errMsg = "Malformed XMPP URL + " + xmppUsersAPIEndpoint;
log.error(errMsg);
throw new DeviceControllerException(errMsg);
}
HttpClient httpClient;
try {
httpClient = IoTUtil.getHttpClient(xmppUserApiUrl.getPort(), xmppUserApiUrl.getProtocol());
} catch (Exception e) {
log.error("Error on getting a http client for port :" + xmppUserApiUrl.getPort() + " protocol :"
+ xmppUserApiUrl.getProtocol());
return false;
}
HttpPost httpPost = new HttpPost(xmppUsersAPIEndpoint);
httpPost.addHeader(HttpHeaders.AUTHORIZATION, authorizationHeader);
httpPost.setEntity(requestEntity);
try {
HttpResponse httpResponse = httpClient.execute(httpPost);
if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) {
String response = IoTUtil.getResponseString(httpResponse);
String errorMsg = "XMPP Server returned status: '" + httpResponse.getStatusLine().getStatusCode() +
"' for account creation with error:\n" + response;
log.error(errorMsg);
throw new DeviceControllerException(errorMsg);
} else {
EntityUtils.consume(httpResponse.getEntity());
return true;
}
} catch (IOException e) {
String errorMsg = "Error occured whilst trying a 'POST' at : " + xmppUsersAPIEndpoint;
log.error(errorMsg);
throw new DeviceControllerException(errorMsg, e);
}
} else {
log.warn(String.format("XMPP <Enabled> set to false in [%s]", DEVICEMGT_CONFIG_FILE));
return false;
}
}
public boolean doesXMPPUserAccountExist(String username) throws DeviceControllerException {
if (xmppEnabled) {
String xmppCheckUserAPIEndpoint = xmppEndpoint + XMPP_SERVER_API_CONTEXT + XMPP_USERS_API + "/" + username;
if (log.isDebugEnabled()) {
log.debug("The Check-User-Account Endpoint URL of the XMPP Server is set to: " +
xmppCheckUserAPIEndpoint);
}
String encodedString = xmppUsername + ":" + xmppPassword;
encodedString = new String(Base64.encodeBase64(encodedString.getBytes(StandardCharsets.UTF_8)));
String authorizationHeader = "Basic " + encodedString;
URL xmppUserApiUrl;
try {
xmppUserApiUrl = new URL(xmppCheckUserAPIEndpoint);
} catch (MalformedURLException e) {
String errMsg = "Malformed XMPP URL + " + xmppCheckUserAPIEndpoint;
log.error(errMsg);
throw new DeviceControllerException(errMsg, e);
}
HttpClient httpClient;
try {
httpClient = IoTUtil.getHttpClient(xmppUserApiUrl.getPort(), xmppUserApiUrl.getProtocol());
} catch (Exception e) {
String errorMsg = "Error on getting a http client for port :" + xmppUserApiUrl.getPort() +
" protocol :" + xmppUserApiUrl.getProtocol();
log.error(errorMsg);
throw new DeviceControllerException(errorMsg, e);
}
HttpGet httpGet = new HttpGet(xmppCheckUserAPIEndpoint);
httpGet.addHeader(HttpHeaders.AUTHORIZATION, authorizationHeader);
try {
HttpResponse httpResponse = httpClient.execute(httpGet);
if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
String response = IoTUtil.getResponseString(httpResponse);
if (log.isDebugEnabled()) {
log.debug("XMPP Server returned status: '" + httpResponse.getStatusLine().getStatusCode() +
"' for checking existence of account [" + username + "] with message:\n" +
response + "\nProbably, an account with this username does not exist.");
}
return false;
}
} catch (IOException e) {
String errorMsg = "Error occured whilst trying a 'GET' at : " + xmppCheckUserAPIEndpoint;
log.error(errorMsg);
throw new DeviceControllerException(errorMsg, e);
}
if (log.isDebugEnabled()) {
log.debug("XMPP Server already has an account for the username - [" + username + "].");
}
return true;
} else {
String warnMsg = String.format("XMPP <Enabled> set to false in [%s]", DEVICEMGT_CONFIG_FILE);
log.warn(warnMsg);
throw new DeviceControllerException(warnMsg);
}
}
public JSONArray getAllCurrentUserSessions() throws DeviceControllerException {
if (xmppEnabled) {
JSONArray xmppSessions;
String xmppSessionsAPIEndpoint = xmppEndpoint + XMPP_SERVER_API_CONTEXT + XMPP_SESSIONS_API;
if (log.isDebugEnabled()) {
log.debug("The Get-Sessions Endpoint URL of the XMPP Server is set to: " + xmppSessionsAPIEndpoint);
}
String encodedString = xmppUsername + ":" + xmppPassword;
encodedString = new String(Base64.encodeBase64(encodedString.getBytes(StandardCharsets.UTF_8)));
String authorizationHeader = "Basic " + encodedString;
URL xmppUserApiUrl;
try {
xmppUserApiUrl = new URL(xmppSessionsAPIEndpoint);
} catch (MalformedURLException e) {
String errMsg = "Malformed XMPP URL + " + xmppSessionsAPIEndpoint;
log.error(errMsg);
throw new DeviceControllerException(errMsg, e);
}
HttpClient httpClient;
try {
httpClient = IoTUtil.getHttpClient(xmppUserApiUrl.getPort(), xmppUserApiUrl.getProtocol());
} catch (Exception e) {
String errorMsg = "Error on getting a http client for port :" + xmppUserApiUrl.getPort() +
" protocol :" + xmppUserApiUrl.getProtocol();
log.error(errorMsg);
throw new DeviceControllerException(errorMsg, e);
}
HttpGet httpGet = new HttpGet(xmppSessionsAPIEndpoint);
httpGet.addHeader(HttpHeaders.AUTHORIZATION, authorizationHeader);
httpGet.addHeader(HttpHeaders.ACCEPT, APPLICATION_JSON);
try {
HttpResponse httpResponse = httpClient.execute(httpGet);
if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
String errorMsg = "XMPP Server returned status: '" + httpResponse.getStatusLine().getStatusCode() +
"' for checking current XMPP Sessions.";
log.error(errorMsg);
throw new DeviceControllerException(errorMsg);
}
String response = IoTUtil.getResponseString(httpResponse);
xmppSessions = new JSONObject(response).getJSONArray("session");
return xmppSessions;
} catch (IOException e) {
String errorMsg = "Error occured whilst trying a 'GET' at : " + xmppSessionsAPIEndpoint;
log.error(errorMsg);
throw new DeviceControllerException(errorMsg, e);
}
} else {
String warnMsg = String.format("XMPP <Enabled> set to false in [%s]", DEVICEMGT_CONFIG_FILE);
log.warn(warnMsg);
throw new DeviceControllerException(warnMsg);
}
}
public void deleteCurrentXmppSessions() throws DeviceControllerException {
JSONArray xmppSessionsArray;
try {
xmppSessionsArray = getAllCurrentUserSessions();
} catch (DeviceControllerException e) {
if (e.getMessage().contains(DEVICEMGT_CONFIG_FILE)) {
log.warn(String.format("XMPP <Enabled> set to false in [%s]", DEVICEMGT_CONFIG_FILE));
return;
} else {
throw e;
}
}
if (xmppSessionsArray.length() != 0) {
String xmppSessionsAPIEndpoint = xmppEndpoint + XMPP_SERVER_API_CONTEXT + XMPP_SESSIONS_API;
String encodedString = xmppUsername + ":" + xmppPassword;
encodedString = new String(Base64.encodeBase64(encodedString.getBytes(StandardCharsets.UTF_8)));
String authorizationHeader = "Basic " + encodedString;
if (log.isDebugEnabled()) {
log.debug("The Get-Sessions Endpoint URL of the XMPP Server is set to: " + xmppSessionsAPIEndpoint);
}
URL xmppUserApiUrl;
try {
xmppUserApiUrl = new URL(xmppSessionsAPIEndpoint);
} catch (MalformedURLException e) {
String errMsg = "Malformed XMPP URL + " + xmppSessionsAPIEndpoint;
log.error(errMsg);
throw new DeviceControllerException(errMsg, e);
}
HttpClient httpClient;
try {
httpClient = IoTUtil.getHttpClient(xmppUserApiUrl.getPort(), xmppUserApiUrl.getProtocol());
} catch (Exception e) {
String errorMsg = "Error on getting a http client for port :" + xmppUserApiUrl.getPort() +
" protocol :" + xmppUserApiUrl.getProtocol();
log.error(errorMsg);
throw new DeviceControllerException(errorMsg, e);
}
for (int i = 0; i < xmppSessionsArray.length(); i++) {
String sessionName = xmppSessionsArray.getJSONObject(i).getString("username");
String xmppUserSessionsAPIEndpoint = xmppSessionsAPIEndpoint + "/" + sessionName;
HttpDelete httpDelete = new HttpDelete(xmppUserSessionsAPIEndpoint);
httpDelete.addHeader(HttpHeaders.AUTHORIZATION, authorizationHeader);
try {
HttpResponse httpResponse = httpClient.execute(httpDelete);
if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
String errorMsg =
"XMPP Server returned status: '" + httpResponse.getStatusLine().getStatusCode() +
"' for checking current XMPP Sessions.";
log.error(errorMsg);
throw new DeviceControllerException(errorMsg);
}
} catch (IOException e) {
String errorMsg = "Error occured whilst trying a 'DELETE' user-session [" + sessionName + "] " +
"at : " + xmppUserSessionsAPIEndpoint;
log.error(errorMsg);
throw new DeviceControllerException(errorMsg, e);
}
}
}
}
}

@ -1,42 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.exception;
public class DeviceControllerException extends Exception {
public DeviceControllerException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public DeviceControllerException(Throwable cause) {
super(cause);
}
public DeviceControllerException(String message, Throwable cause) {
super(message, cause);
}
public DeviceControllerException(String message) {
super(message);
}
public DeviceControllerException() {
}
}

@ -1,43 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.exception;
public class NotImplementedException extends RuntimeException {
public NotImplementedException() {
super();
}
public NotImplementedException(String message) {
super(message);
}
public NotImplementedException(String message, Throwable cause) {
super(message, cause);
}
public NotImplementedException(Throwable cause) {
super(cause);
}
protected NotImplementedException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

@ -1,39 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.exception;
public class UnauthorizedException extends Exception {
public UnauthorizedException(String message) {
super(message);
}
public UnauthorizedException(String message, Throwable cause) {
super(message, cause);
}
public UnauthorizedException(Throwable cause) {
super(cause);
}
public UnauthorizedException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

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

@ -23,11 +23,7 @@ import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleContext;
import org.osgi.service.component.ComponentContext;
import org.wso2.carbon.core.ServerStartupObserver;
import org.wso2.carbon.device.mgt.iot.config.server.DeviceManagementConfigurationManager;
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig;
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppServerClient;
import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
import org.wso2.carbon.device.mgt.iot.service.IoTServerStartupListener;
import org.wso2.carbon.device.mgt.iot.url.printer.URLPrinterStartupHandler;
import org.wso2.carbon.utils.ConfigurationContextService;
/**
@ -43,7 +39,6 @@ import org.wso2.carbon.utils.ConfigurationContextService;
public class IotDeviceManagementServiceComponent {
private static final Log log = LogFactory.getLog(IotDeviceManagementServiceComponent.class);
public static ConfigurationContextService configurationContextService;
protected void activate(ComponentContext ctx) {
if (log.isDebugEnabled()) {
@ -51,9 +46,7 @@ public class IotDeviceManagementServiceComponent {
}
try {
BundleContext bundleContext = ctx.getBundleContext();
/* Initialize the data source configuration */
DeviceManagementConfigurationManager.getInstance().initConfig();
bundleContext.registerService(ServerStartupObserver.class.getName(), new IoTServerStartupListener(), null);
bundleContext.registerService(ServerStartupObserver.class.getName(), new URLPrinterStartupHandler(), null);
if (log.isDebugEnabled()) {
log.debug("Iot Device Management Service Component has been successfully activated");
}
@ -63,19 +56,6 @@ public class IotDeviceManagementServiceComponent {
}
protected void deactivate(ComponentContext ctx) {
XmppConfig xmppConfig = XmppConfig.getInstance();
try {
if (xmppConfig.isEnabled()) {
XmppServerClient xmppServerClient = new XmppServerClient();
xmppServerClient.initControlQueue();
xmppServerClient.deleteCurrentXmppSessions();
}
} catch (DeviceControllerException e) {
String errorMsg = "An error occurred whilst trying to delete all existing XMPP login sessions at " +
"[" + xmppConfig.getXmppEndpoint() + "].";
log.error(errorMsg, e);
}
if (log.isDebugEnabled()) {
log.debug("De-activating Iot Device Management Service Component");
}
@ -86,7 +66,7 @@ public class IotDeviceManagementServiceComponent {
log.debug("Setting ConfigurationContextService");
}
IotDeviceManagementServiceComponent.configurationContextService = configurationContextService;
IoTDeviceManagementDataHolder.getInstance().setConfigurationContextService(configurationContextService);
}
@ -94,6 +74,6 @@ public class IotDeviceManagementServiceComponent {
if (log.isDebugEnabled()) {
log.debug("Un-setting ConfigurationContextService");
}
IotDeviceManagementServiceComponent.configurationContextService = null;
IoTDeviceManagementDataHolder.getInstance().setConfigurationContextService(null);
}
}

@ -1,66 +0,0 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.mqtt;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
public class PolicyPush {
private static final Log log = LogFactory.getLog(PolicyPush.class);
public boolean pushToMQTT(String topic, String content, String broker, String clientId) {
byte qos = 2;
MemoryPersistence persistence = new MemoryPersistence();
try {
MqttClient me = new MqttClient(broker, clientId, persistence);
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
if (log.isDebugEnabled()) {
log.debug("Connecting to broker: " + broker);
}
me.connect(connOpts);
if (log.isDebugEnabled()) {
log.debug("Connected");
log.debug("Publishing message: " + content);
}
MqttMessage message = new MqttMessage(content.getBytes());
message.setQos(qos);
me.publish(topic, message);
if (log.isDebugEnabled()) {
log.debug("Message published");
}
me.disconnect();
if (log.isDebugEnabled()) {
log.debug("Disconnected");
}
return true;
} catch (MqttException ex) {
log.error("Error occurred when trying to publish to MQTT Queue", ex);
return false;
}
}
}

@ -1,41 +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.service;
import org.wso2.carbon.core.ServerStartupObserver;
public class IoTServerStartupListener implements ServerStartupObserver {
private static volatile boolean serverReady = false;
@Override
public void completingServerStartup() {
}
@Override
public void completedServerStartup() {
IoTServerStartupListener.setServerReady(true);
}
public static boolean isServerReady() {
return IoTServerStartupListener.serverReady;
}
public static void setServerReady(boolean serverReady) {
IoTServerStartupListener.serverReady = serverReady;
}
}

@ -1,219 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.transport;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tomcat.util.codec.binary.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
/**
* This is a utility class which contains methods common to the communication process of a client and the server. The
* methods include encryption/decryption of payloads and signing/verification of payloads received and to be sent.
*/
public class CommunicationUtils {
private static final Log log = LogFactory.getLog(TransportUtils.class);
// The Signature Algorithm used.
private static final String SIGNATURE_ALG = "SHA1withRSA";
// The Encryption Algorithm and the Padding used.
private static final String CIPHER_PADDING = "RSA/ECB/PKCS1Padding";
/**
* Encrypts the message with the key that's passed in.
*
* @param message the message to be encrypted.
* @param encryptionKey the key to use for the encryption of the message.
* @return the encrypted message in String format.
* @throws TransportHandlerException if an error occurs with the encryption flow which can be due to Padding
* issues, encryption key being invalid or the algorithm used is unrecognizable.
*/
public static String encryptMessage(String message, Key encryptionKey) throws TransportHandlerException {
Cipher encrypter;
byte[] cipherData;
try {
encrypter = Cipher.getInstance(CIPHER_PADDING);
encrypter.init(Cipher.ENCRYPT_MODE, encryptionKey);
cipherData = encrypter.doFinal(message.getBytes(StandardCharsets.UTF_8));
} catch (NoSuchAlgorithmException e) {
String errorMsg = "Algorithm not found exception occurred for Cipher instance of [" + CIPHER_PADDING + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (NoSuchPaddingException e) {
String errorMsg = "No Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (InvalidKeyException e) {
String errorMsg = "InvalidKey exception occurred for encryptionKey \n[\n" + encryptionKey + "\n]\n";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (BadPaddingException e) {
String errorMsg = "Bad Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (IllegalBlockSizeException e) {
String errorMsg = "Illegal blockSize error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
}
return Base64.encodeBase64String(cipherData);
}
///TODO:: Exception needs to change according to the common package
/**
* Signed a given message using the PrivateKey that's passes in.
*
* @param message the message to be signed. Ideally some encrypted payload.
* @param signatureKey the PrivateKey with which the message is to be signed.
* @return the Base64Encoded String of the signed payload.
* @throws TransportHandlerException if some error occurs with the signing process which may be related to the
* signature algorithm used or the key used for signing.
*/
public static String signMessage(String message, PrivateKey signatureKey) throws TransportHandlerException {
Signature signature;
String signedEncodedString;
try {
signature = Signature.getInstance(SIGNATURE_ALG);
signature.initSign(signatureKey);
signature.update(Base64.decodeBase64(message));
byte[] signatureBytes = signature.sign();
signedEncodedString = Base64.encodeBase64String(signatureBytes);
} catch (NoSuchAlgorithmException e) {
String errorMsg =
"Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (SignatureException e) {
String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (InvalidKeyException e) {
String errorMsg = "InvalidKey exception occurred for signatureKey \n[\n" + signatureKey + "\n]\n";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
}
return signedEncodedString;
}
/**
* Verifies some signed-data against the a Public-Key to ensure that it was produced by the holder of the
* corresponding Private Key.
*
* @param data the actual payoad which was signed by some Private Key.
* @param signedData the signed data produced by signing the payload using a Private Key.
* @param verificationKey the corresponding Public Key which is an exact pair of the Private-Key with we expect
* the data to be signed by.
* @return true if the signed data verifies to be signed by the corresponding Private Key.
* @throws TransportHandlerException if some error occurs with the verification process which may be related to
* the signature algorithm used or the key used for signing.
*/
public static boolean verifySignature(String data, String signedData, PublicKey verificationKey)
throws TransportHandlerException {
Signature signature;
boolean verified;
try {
signature = Signature.getInstance(SIGNATURE_ALG);
signature.initVerify(verificationKey);
signature.update(Base64.decodeBase64(data));
verified = signature.verify(Base64.decodeBase64(signedData));
} catch (NoSuchAlgorithmException e) {
String errorMsg =
"Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (SignatureException e) {
String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (InvalidKeyException e) {
String errorMsg = "InvalidKey exception occurred for signatureKey \n[\n" + verificationKey + "\n]\n";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
}
return verified;
}
/**
* Encrypts the message with the key that's passed in.
*
* @param encryptedMessage the encrypted message that is supposed to be decrypted.
* @param decryptKey the key to use in the decryption process.
* @return the decrypted message in String format.
* @throws TransportHandlerException if an error occurs with the encryption flow which can be due to Padding
* issues, encryption key being invalid or the algorithm used is unrecognizable.
*/
public static String decryptMessage(String encryptedMessage, Key decryptKey) throws TransportHandlerException {
Cipher decrypter;
String decryptedMessage;
try {
decrypter = Cipher.getInstance(CIPHER_PADDING);
decrypter.init(Cipher.DECRYPT_MODE, decryptKey);
decryptedMessage = new String(decrypter.doFinal(Base64.decodeBase64(encryptedMessage)),
StandardCharsets.UTF_8);
} catch (NoSuchAlgorithmException e) {
String errorMsg = "Algorithm not found exception occurred for Cipher instance of [" + CIPHER_PADDING + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (NoSuchPaddingException e) {
String errorMsg = "No Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (InvalidKeyException e) {
String errorMsg = "InvalidKey exception occurred for encryptionKey \n[\n" + decryptKey + "\n]\n";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (BadPaddingException e) {
String errorMsg = "Bad Padding error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (IllegalBlockSizeException e) {
String errorMsg = "Illegal blockSize error occurred for Cipher instance of [" + CIPHER_PADDING + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
}
return decryptedMessage;
}
}

@ -1,108 +0,0 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.transport;
/**
* This interface consists of the core functionality related to the transport between any device and the server. The
* interface is an abstraction, regardless of the underlying protocol used for the transport. Implementation of this
* interface by any class that caters a specific protocol (ex: HTTP, XMPP, MQTT, CoAP) would ideally have methods
* specific to the protocol used for communication and other methods that implement the logic related to the devices
* using the protocol. The methods of the interface are identified as generic ones for implementing transport
* protocols for device communication. The implementation can utilize the appropriate method signatures applicable for
* intended protocol.
*
* @param <T> an object of the message type specific to the protocol implemented. To be set to 'String' if there
* isn't anything specific.
*/
public interface TransportHandler<T> {
// a default timeout interval to be used for the protocol specific connections
int DEFAULT_TIMEOUT_INTERVAL = 5000; // millis ~ 5 sec
/**
* Implements the underlying connect mechanism specific to the protocol enabled by the interface. An object of a
* class that implements this interface would call this method before any communication is started via the
* intended protocol.
*/
void connect();
/**
* Used to check whether a connection (via the implemented protocol) to the external-endpoint exists. Ideally
* used to verify that the connection persists and to spawn a reconnection attempt if not.
*
* @return 'true' if connection is already made & exists, else 'false'.
*/
boolean isConnected();
/**
* @throws TransportHandlerException in the event of any exceptions that occur whilst processing the message.
* @see TransportHandler#processIncomingMessage(Object, String...)
*/
void processIncomingMessage() throws TransportHandlerException;
/**
* @param message the message (of the type specific to the protocol) received from the device.
* @throws TransportHandlerException
* @see TransportHandler#processIncomingMessage(Object, String...)
*/
void processIncomingMessage(T message) throws TransportHandlerException;
/**
* This is an overloaded method with three different method-signatures. This method is used to process any
* incoming messages via the implemented protocol. It would ideally be invoked at a point where a message
* received event is activated (Ex: `MessageArrived` callback in Eclipse-Paho-MQTT Client & `PacketListener`(s)
* in XMPP).
* <p/>
*
* @param message the message (of the type specific to the protocol) received from the device.
* @param messageParams one or more other parameters received as part-of & relevant-to the message (Ex: MQTT Topic).
* @throws TransportHandlerException in the event of any exceptions that occur whilst processing the message.
*/
void processIncomingMessage(T message, String... messageParams) throws TransportHandlerException;
/**
* @throws TransportHandlerException in the event of any exceptions that occur whilst sending the message.
* @see TransportHandler#publishDeviceData(String...)
*/
void publishDeviceData() throws TransportHandlerException;
/**
* @param publishData the message (of the type specific to the protocol) to be sent to the device.
* @throws TransportHandlerException in the event of any exceptions that occur whilst sending the message.
* @see TransportHandler#publishDeviceData(String...)
*/
void publishDeviceData(T publishData) throws TransportHandlerException;
/**
* This is an overloaded method with three different method-signatures. This method is used to publish messages
* to an external-endpoint/device via the implemented protocol. It could in itself call the (communicating)
* external-endpoint or invoke any method provided by the protocol specific library.
* <p/>
*
* @param publishData one or more parameters specific to the message and the data to be sent.
* @throws TransportHandlerException in the event of any exceptions that occur whilst sending the message.
*/
void publishDeviceData(String... publishData) throws TransportHandlerException;
/**
* Implements the underlying disconnect mechanism specific to the protocol enabled by the interface. An object of a
* class that implements this interface would call this method upon completion of all communication. In the case of
* the IoT-Server invoking this would only be required if the server shuts-down.
*/
void disconnect();
}

@ -1,56 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.transport;
public class TransportHandlerException extends Exception {
private static final long serialVersionUID = 2736466230451105440L;
private String errorMessage;
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public TransportHandlerException(String msg, Exception nestedEx) {
super(msg, nestedEx);
setErrorMessage(msg);
}
public TransportHandlerException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
public TransportHandlerException(String msg) {
super(msg);
setErrorMessage(msg);
}
public TransportHandlerException() {
super();
}
public TransportHandlerException(Throwable cause) {
super(cause);
}
}

@ -1,296 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.transport;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramSocket;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.SocketException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class TransportUtils {
private static final Log log = LogFactory.getLog(TransportUtils.class);
public static final int MIN_PORT_NUMBER = 9000;
public static final int MAX_PORT_NUMBER = 11000;
/**
* Given a server endpoint as a String, this method splits it into Protocol, Host and Port
*
* @param ipString a network endpoint in the format - '<PROTOCOL>://<HOST>:<PORT>'
* @return a map with keys "Protocol", "Host" & "Port" for the related values from the ipString
* @throws TransportHandlerException
*/
public static Map<String, String> getHostAndPort(String ipString)
throws TransportHandlerException {
Map<String, String> ipPortMap = new HashMap<String, String>();
String[] ipPortArray = ipString.split(":");
if (ipPortArray.length != 3) {
String errorMsg =
"The IP String - '" + ipString +
"' is invalid. It needs to be in format '<PROTOCOL>://<HOST>:<PORT>'.";
log.info(errorMsg);
throw new TransportHandlerException(errorMsg);
}
ipPortMap.put("Protocol", ipPortArray[0]);
ipPortMap.put("Host", ipPortArray[1].replace(File.separator, ""));
ipPortMap.put("Port", ipPortArray[2]);
return ipPortMap;
}
/**
* This method validates whether a specific IP Address is of IPv4 type
*
* @param ipAddress the IP Address which needs to be validated
* @return true if it is of IPv4 type and false otherwise
*/
public static boolean validateIPv4(String ipAddress) {
try {
if (ipAddress == null || ipAddress.isEmpty()) {
return false;
}
String[] parts = ipAddress.split("\\.");
if (parts.length != 4) {
return false;
}
for (String s : parts) {
int i = Integer.parseInt(s);
if ((i < 0) || (i > 255)) {
return false;
}
}
return !ipAddress.endsWith(".");
} catch (NumberFormatException nfe) {
log.warn("The IP Address: " + ipAddress + " could not " +
"be validated against IPv4-style");
return false;
}
}
public static Map<String, String> getInterfaceIPMap() throws TransportHandlerException {
Map<String, String> interfaceToIPMap = new HashMap<String, String>();
Enumeration<NetworkInterface> networkInterfaces;
String networkInterfaceName = "";
String ipAddress;
try {
networkInterfaces = NetworkInterface.getNetworkInterfaces();
} catch (SocketException exception) {
String errorMsg =
"Error encountered whilst trying to get the list of network-interfaces";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, exception);
}
try {
for (; networkInterfaces.hasMoreElements(); ) {
networkInterfaceName = networkInterfaces.nextElement().getName();
if (log.isDebugEnabled()) {
log.debug("Network Interface: " + networkInterfaceName);
log.debug("------------------------------------------");
}
Enumeration<InetAddress> interfaceIPAddresses = NetworkInterface.getByName(
networkInterfaceName).getInetAddresses();
for (; interfaceIPAddresses.hasMoreElements(); ) {
ipAddress = interfaceIPAddresses.nextElement().getHostAddress();
if (log.isDebugEnabled()) {
log.debug("IP Address: " + ipAddress);
}
if (TransportUtils.validateIPv4(ipAddress)) {
interfaceToIPMap.put(networkInterfaceName, ipAddress);
}
}
if (log.isDebugEnabled()) {
log.debug("------------------------------------------");
}
}
} catch (SocketException exception) {
String errorMsg =
"Error encountered whilst trying to get the IP Addresses of the network " +
"interface: " + networkInterfaceName;
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, exception);
}
return interfaceToIPMap;
}
/**
* Attempts to find a free port between the MIN_PORT_NUMBER(9000) and MAX_PORT_NUMBER(11000).
* Tries 'RANDOMLY picked' port numbers between this range up-until "randomAttempts" number of
* times. If still fails, then tries each port in descending order from the MAX_PORT_NUMBER
* whilst skipping already attempted ones via random selection.
*
* @param randomAttempts no of times to TEST port numbers picked randomly over the given range
* @return an available/free port
*/
public static synchronized int getAvailablePort(int randomAttempts) {
ArrayList<Integer> failedPorts = new ArrayList<Integer>(randomAttempts);
Random randomNum = new Random();
int randomPort = MAX_PORT_NUMBER;
while (randomAttempts > 0) {
randomPort = randomNum.nextInt(MAX_PORT_NUMBER - MIN_PORT_NUMBER) + MIN_PORT_NUMBER;
if (checkIfPortAvailable(randomPort)) {
return randomPort;
}
failedPorts.add(randomPort);
randomAttempts--;
}
randomPort = MAX_PORT_NUMBER;
while (true) {
if (!failedPorts.contains(randomPort) && checkIfPortAvailable(randomPort)) {
return randomPort;
}
randomPort--;
}
}
private static boolean checkIfPortAvailable(int port) {
ServerSocket tcpSocket = null;
DatagramSocket udpSocket = null;
try {
tcpSocket = new ServerSocket(port);
tcpSocket.setReuseAddress(true);
udpSocket = new DatagramSocket(port);
udpSocket.setReuseAddress(true);
return true;
} catch (IOException ex) {
// denotes the port is in use
} finally {
if (tcpSocket != null) {
try {
tcpSocket.close();
} catch (IOException e) {
/* not to be thrown */
}
}
if (udpSocket != null) {
udpSocket.close();
}
}
return false;
}
/**
* This is a utility method that creates and returns a HTTP connection object.
*
* @param urlString the URL pattern to which the connection needs to be created
* @return an HTTPConnection object which cn be used to send HTTP requests
* @throws TransportHandlerException if errors occur when creating the HTTP connection with
* the given URL string
*/
public static HttpURLConnection getHttpConnection(String urlString) throws
TransportHandlerException {
URL connectionUrl;
HttpURLConnection httpConnection;
try {
connectionUrl = new URL(urlString);
httpConnection = (HttpURLConnection) connectionUrl.openConnection();
} catch (MalformedURLException e) {
String errorMsg = "Error occured whilst trying to form HTTP-URL from string: " + urlString;
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (IOException exception) {
String errorMsg = "Error occured whilst trying to open a connection to: " + urlString;
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, exception);
}
return httpConnection;
}
/**
* This is a utility method that reads and returns the response from a HTTP connection
*
* @param httpConnection the connection from which a response is expected
* @return the response (as a string) from the given HTTP connection
* @throws TransportHandlerException if any errors occur whilst reading the response from
* the connection stream
*/
public static String readResponseFromHttpRequest(HttpURLConnection httpConnection)
throws TransportHandlerException {
BufferedReader bufferedReader;
try {
bufferedReader = new BufferedReader(new InputStreamReader(
httpConnection.getInputStream(), StandardCharsets.UTF_8));
} catch (IOException exception) {
String errorMsg = "There is an issue with connecting the reader to the input stream at: " +
httpConnection.getURL();
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, exception);
}
String responseLine;
StringBuilder completeResponse = new StringBuilder();
try {
while ((responseLine = bufferedReader.readLine()) != null) {
completeResponse.append(responseLine);
}
} catch (IOException exception) {
String errorMsg = "Error occured whilst trying read from the connection stream at: " +
httpConnection.getURL();
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, exception);
}
try {
bufferedReader.close();
} catch (IOException exception) {
log.error("Could not succesfully close the bufferedReader to the connection at: " + httpConnection.getURL());
}
return completeResponse.toString();
}
}

@ -1,407 +0,0 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.transport.mqtt;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandler;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
import java.io.File;
import java.nio.charset.StandardCharsets;
/**
* This is an abstract class that implements the "TransportHandler" interface. The interface is an abstraction for
* the core functionality with regards to device-server communication regardless of the Transport protocol. This
* specific class contains the MQTT-Transport specific implementations. The class implements utility methods for the
* case of a MQTT communication. However, this "abstract class", even-though it implements the "TransportHandler"
* interface, does not contain the logic relevant to the interface methods. The specific functionality of the
* interface methods are intended to be implemented by the concrete class that extends this abstract class and
* utilizes the MQTT specific functionality (ideally a device API writer who would like to communicate to the device
* via MQTT Protocol).
* <p/>
* This class contains the Device-Management specific implementation for all the MQTT functionality. This includes
* connecting to a MQTT Broker & subscribing to the appropriate MQTT-topic, action plan upon losing connection or
* successfully delivering a message to the broker and upon receiving a MQTT message. Makes use of the 'Paho-MQTT'
* library provided by Eclipse Org.
*/
public abstract class MQTTTransportHandler implements MqttCallback, TransportHandler<MqttMessage> {
private static final Log log = LogFactory.getLog(MQTTTransportHandler.class);
private MqttClient client;
private String clientId;
private MqttConnectOptions options; // options to be set to the client-connection.
// topic to which a will-message is automatically published by the broker upon the device losing its connection.
private String clientWillTopic;
protected String mqttBrokerEndPoint;
protected int timeoutInterval; // interval to use for reconnection attempts etc.
protected String subscribeTopic;
// Quality of Service Levels for MQTT Subscription and Publishing.
public static final int QoS_0 = 0; // At-Most Once
@SuppressWarnings("unused")
public static final int QoS_1 = 1; // At-Least Once
public static final int QoS_2 = 2; // Exactly Once
public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = QoS_0;
// Prefix to the Will-Topic to which a message is published if client loses its connection.
private static final String DISCONNECTION_WILL_TOPIC_PREFIX = "Disconnection/";
// Will-Message of the client to be published if connection is lost.
private static final String DISCONNECTION_WILL_MSG = "Lost-Connection";
/**
* Constructor for the MQTTTransportHandler which takes in the owner, type of the device and the MQTT Broker URL
* and the topic to subscribe.
*
* @param deviceOwner the owner of the device.
* @param deviceType the CDMF Device-Type of the device.
* @param mqttBrokerEndPoint the IP/URL of the MQTT broker endpoint.
* @param subscribeTopic the MQTT topic to which the client is to be subscribed.
*/
protected MQTTTransportHandler(String deviceOwner, String deviceType,
String mqttBrokerEndPoint, String subscribeTopic) {
this.clientId = deviceOwner + ":" + deviceType;
this.subscribeTopic = subscribeTopic;
this.clientWillTopic = DISCONNECTION_WILL_TOPIC_PREFIX + deviceType;
this.mqttBrokerEndPoint = mqttBrokerEndPoint;
this.timeoutInterval = DEFAULT_TIMEOUT_INTERVAL;
this.initMQTTClient();
}
/**
* Constructor for the MQTTTransportHandler which takes in the owner, type of the device and the MQTT Broker URL
* and the topic to subscribe. Additionally this constructor takes in the reconnection-time interval between
* successive attempts to connect to the broker.
*
* @param deviceOwner the owner of the device.
* @param deviceType the CDMF Device-Type of the device.
* @param mqttBrokerEndPoint the IP/URL of the MQTT broker endpoint.
* @param subscribeTopic the MQTT topic to which the client is to be subscribed
* @param intervalInMillis the time interval in MILLI-SECONDS between attempts to connect to the broker.
*/
protected MQTTTransportHandler(String deviceOwner, String deviceType,
String mqttBrokerEndPoint, String subscribeTopic, int intervalInMillis) {
this.clientId = deviceOwner + ":" + deviceType;
this.subscribeTopic = subscribeTopic;
this.clientWillTopic = DISCONNECTION_WILL_TOPIC_PREFIX + deviceType;
this.mqttBrokerEndPoint = mqttBrokerEndPoint;
this.timeoutInterval = intervalInMillis;
this.initMQTTClient();
}
/**
* Initializes the MQTT-Client. Creates a client using the given MQTT-broker endpoint and the clientId (which is
* constructed by a concatenation of [deviceOwner]:[deviceType]). Also sets the client's options parameter with
* the clientWillTopic (in-case of connection failure) and other info. Also sets the callback to this current class.
*/
private void initMQTTClient() {
try {
client = new MqttClient(this.mqttBrokerEndPoint, clientId, null);
log.info("MQTT client was created with ClientID : " + clientId);
} catch (MqttException ex) {
String errorMsg = "Initializing the MQTT Client failed.";
log.error(errorMsg, ex);
//TODO:: Throw the error out
}
options = new MqttConnectOptions();
options.setKeepAliveInterval(120); // set the keep alive interval to 120 seconds by default.
options.setCleanSession(true); // sets clean session to true by default.
setDisconnectionWillForClient(QoS_2, true); // sets default will-topic & msg with QoS 2 and retained true.
client.setCallback(this); // callback for MQTT events are set to `this` object.
}
/**
* @param qos the Quality of Service at which the last-will-message is to be published.
* @param isRetained indicate whether to retain the last-will-message.
* @see MQTTTransportHandler#setDisconnectionWillForClient(String, String, int, boolean). Uses the default values
* for Will-Topic and Will-Message.
*/
protected void setDisconnectionWillForClient(int qos, boolean isRetained) {
this.setDisconnectionWillForClient(clientWillTopic, DISCONNECTION_WILL_MSG, qos, isRetained);
}
/**
* Sets the [Will] option in the default options-set of the MQTT Client. A will-topic, will-message is parsed
* along with the QoS and the retained flag. When the client loses its connection to the broker, the broker
* publishes the will-message to the will-topic, to itself.
*
* @param willTopic the topic to which the last will message is to be published when client exists ungracefully.
* @param willMsg the message to be published upon client's ungraceful exit from the broker.
* @param qos the Quality of Service at which the last-will-message is to be published.
* @param isRetained indicate whether to retain the last-will-message.
*/
protected void setDisconnectionWillForClient(String willTopic, String willMsg, int qos, boolean isRetained) {
this.options.setWill(willTopic, willMsg.getBytes(StandardCharsets.UTF_8), qos, isRetained);
}
/**
* Sets the [Clean-Session] option in the default options-set of the MQTT Client. It is set to `true` by default.
*
* @param setCleanSession `true` indicates that the session details can be cleared/cleaned upon disconnection,
* `false` indicates that the session details are to be persisted if the client disconnects.
*/
@SuppressWarnings("unused")
protected void setClientCleanSession(boolean setCleanSession) {
this.options.setCleanSession(setCleanSession);
}
/**
* Sets the [Username] & [Password] options in the default options-set of the MQTT Client. By default these
* values are not set.
*
* @param username the username to be used by the client to connect to the broker.
* @param password the password to be used by the client to connect to the broker.
*/
@SuppressWarnings("unused")
protected void setUsernameAndPassword(String username, String password) {
this.options.setUserName(username);
this.options.setPassword(password.toCharArray());
}
/**
* Connects to the MQTT-Broker at the endpoint specified in the constructor to this class using default the
* MQTT-options.
*
* @throws TransportHandlerException in the event of 'Connecting to' the MQTT broker fails.
*/
protected void connectToQueue() throws TransportHandlerException {
this.connectToQueue(options);
}
/**
* Connects to the MQTT-Broker at the endpoint specified in the constructor to this class using the MQTT-Options
* passed.
*
* @param options options to be used by the client for this connection. (username, password, clean-session, etc)
* @throws TransportHandlerException in the event of 'Connecting to' the MQTT broker fails.
*/
protected void connectToQueue(MqttConnectOptions options) throws TransportHandlerException {
try {
client.connect(options);
if (log.isDebugEnabled()) {
log.debug("MQTT Client connected to queue at: " + this.mqttBrokerEndPoint);
}
} catch (MqttException ex) {
String errorMsg = "MQTT Exception occured whilst connecting to queue at [" + this.mqttBrokerEndPoint + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, ex);
}
}
/**
* @throws TransportHandlerException in the event of 'Subscribing to' the MQTT broker fails.
* @see MQTTTransportHandler#subscribeToQueue(int). Uses default QoS of 1.
*/
protected void subscribeToQueue() throws TransportHandlerException {
this.subscribeToQueue(QoS_0);
}
/**
* Subscribes to the MQTT-Topic specified in the constructor to this class.
*
* @throws TransportHandlerException in the event of 'Subscribing to' the MQTT broker fails.
*/
protected void subscribeToQueue(int qos) throws TransportHandlerException {
try {
client.subscribe(subscribeTopic, qos);
if (log.isDebugEnabled()) {
log.debug("Client [" + clientId + "] subscribed to topic: " + subscribeTopic);
}
} catch (MqttException ex) {
String errorMsg = "MQTT Exception occurred whilst client [" + clientId + "] tried to subscribe to " +
"topic: [" + subscribeTopic + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, ex);
}
}
/**
* @param topic the topic to which the message is to be published.
* @param payLoad the message (payload) of the MQTT publish action.
* @see MQTTTransportHandler#publishToQueue(String, String, int, boolean)
*/
@SuppressWarnings("unused")
protected void publishToQueue(String topic, String payLoad) throws TransportHandlerException {
publishToQueue(topic, payLoad, DEFAULT_MQTT_QUALITY_OF_SERVICE, false);
}
/**
* @param topic the topic to which the message is to be published.
* @param message the message (payload) of the MQTT publish action as a `MQTTMessage`.
* @throws TransportHandlerException if any error occurs whilst trying to publish to the MQTT Queue.
* @see MQTTTransportHandler#publishToQueue(String, String, int, boolean)
*/
protected void publishToQueue(String topic, MqttMessage message) throws TransportHandlerException {
if (!isConnected()) {
connectToQueue();
}
try {
client.publish(topic, message);
if (log.isDebugEnabled()) {
log.debug(
"Message: " + message.toString() + " to MQTT topic [" + topic + "] published successfully");
}
} catch (MqttException ex) {
String errorMsg = "MQTT Client Error whilst client [" + clientId + "] tried to publish to queue at " +
"[" + mqttBrokerEndPoint + "] under topic [" + topic + "]";
log.info(errorMsg);
throw new TransportHandlerException(errorMsg, ex);
}
}
/**
* This method is used to publish messages to the MQTT-Endpoint to which this client is connected to. It is via
* publishing to this broker that the messages are communicated to the device. This is an overloaded method with
* different parameter combinations. This method invokes the publish method provided by the MQTT-Client library.
*
* @param topic the topic to which the message is to be published.
* @param payLoad the message (payload) of the MQTT publish action.
* @param qos the Quality-of-Service of the current publish action.
* Could be 0(At-most once), 1(At-least once) or 2(Exactly once)
* @param retained indicate whether to retain the publish-message in the event of no subscribers.
* @throws TransportHandlerException if any error occurs whilst trying to publish to the MQTT Queue.
*/
protected void publishToQueue(String topic, String payLoad, int qos, boolean retained)
throws TransportHandlerException {
try {
client.publish(topic, payLoad.getBytes(StandardCharsets.UTF_8), qos, retained);
if (log.isDebugEnabled()) {
log.debug("Message: " + payLoad + " to MQTT topic [" + topic + "] published successfully");
}
} catch (MqttException ex) {
String errorMsg = "MQTT Client Error whilst client [" + clientId + "] tried to publish to queue at " +
"[" + mqttBrokerEndPoint + "] under topic [" + topic + "]";
log.info(errorMsg);
throw new TransportHandlerException(errorMsg, ex);
}
}
/**
* Checks whether the connection to the MQTT-Broker exists.
*
* @return `true` if the client is connected to the MQTT-Broker, else `false`.
*/
@Override
public boolean isConnected() {
return client.isConnected();
}
/**
* Callback method which is triggered once the MQTT client losers its connection to the broker. Spawns a new
* thread that executes necessary actions to try and reconnect to the endpoint.
*
* @param throwable a Throwable Object containing the details as to why the failure occurred.
*/
@Override
public void connectionLost(Throwable throwable) {
if (log.isDebugEnabled()) {
log.warn("Connection for client: " + this.clientId + " to " + this.mqttBrokerEndPoint + " was lost." +
"\nThis was due to - " + throwable.getMessage());
}
Thread reconnectThread = new Thread() {
public void run() {
while(isConnected()) {
connect();
}
}
};
reconnectThread.start();
}
/**
* Callback method which is triggered upon receiving a MQTT Message from the broker. Spawns a new thread that
* executes any actions to be taken with the received message.
*
* @param topic the MQTT-Topic to which the received message was published to and the client subscribed to.
* @param mqttMessage the actual MQTT-Message that was received from the broker.
*/
@Override
public void messageArrived(final String topic, final MqttMessage mqttMessage) {
if (log.isDebugEnabled()) {
log.debug("Got an MQTT message '" + mqttMessage.toString() + "' for topic '" + topic + "'.");
}
Thread messageProcessorThread = new Thread() {
public void run() {
try {
processIncomingMessage(mqttMessage, topic);
} catch (TransportHandlerException e) {
log.error("An error occurred when trying to process received MQTT message [" + mqttMessage + "] " +
"for topic [" + topic + "].", e);
}
}
};
messageProcessorThread.start();
}
/**
* Callback method which gets triggered upon successful completion of a message delivery to the broker.
*
* @param iMqttDeliveryToken the MQTT-DeliveryToken which includes the details about the specific message delivery.
*/
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
String topic = iMqttDeliveryToken.getTopics()[0];
String client = iMqttDeliveryToken.getClient().getClientId();
try {
if (iMqttDeliveryToken.isComplete()) {
if (log.isDebugEnabled()) {
if (iMqttDeliveryToken.getMessage() != null) {
String message = iMqttDeliveryToken.getMessage().toString();
log.debug("Message to client [" + client + "] under topic (" + topic +
") was delivered successfully with the delivery message: '" + message + "'");
} else {
log.debug("Message to client [" + client + "] under topic (" + topic +
") was delivered successfully.");
}
}
} else {
log.warn("FAILED: Delivery of MQTT message to [" + client + "] under topic [" + topic + "] failed.");
}
} catch (MqttException e) {
log.warn("Error occurred whilst trying to read the message from the MQTT delivery token.");
}
}
/**
* Closes the connection to the MQTT Broker.
*/
public void closeConnection() throws MqttException {
if (client != null && isConnected()) {
client.disconnect();
}
}
/**
* Fetches the default options set for the MQTT Client
*
* @return the options that are currently set for the client.
*/
public MqttConnectOptions getOptions() {
return options;
}
}

@ -1,373 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.transport.xmpp;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.FromContainsFilter;
import org.jivesoftware.smack.filter.OrFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.filter.ToContainsFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandler;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
/**
* This is an abstract class that implements the "TransportHandler" interface. The interface is an abstraction for
* the core functionality with regards to device-server communication regardless of the Transport protocol. This
* specific class contains the HTTP-Transport specific implementations. The class implements utility methods for the
* case of a HTTP communication. However, this "abstract class", even-though it implements the "TransportHandler"
* interface, does not contain the logic relevant to the interface methods. The specific functionality of the
* interface methods are intended to be implemented by the concrete class that extends this abstract class and
* utilizes the HTTP specific functionality (ideally a device API writer who would like to communicate to the device
* via HTTP Protocol).
* <p/>
* This class contains the IoT-Server specific implementation for all the XMPP functionality. This includes
* connecting to a XMPP Server & Login-In using the device's/server's XMPP-Account, Setting listeners and filters on
* incoming XMPP messages and Sending XMPP replies for messages received. Makes use of the 'Smack-XMPP' library
* provided by jivesoftware/igniterealtime.
*/
public abstract class XMPPTransportHandler implements TransportHandler<Message> {
private static final Log log = LogFactory.getLog(XMPPTransportHandler.class);
protected String server;
protected int timeoutInterval; // millis
//TODO:: Shouldnt be hard-coded. Need to be read from configs
private static final int DEFAULT_XMPP_PORT = 5222;
private XMPPConnection connection;
private int port;
private PacketFilter filter;
private PacketListener listener;
/**
* Constructor for XMPPTransportHandler passing only the server-IP.
*
* @param server the IP of the XMPP server.
*/
@SuppressWarnings("unused")
protected XMPPTransportHandler(String server) {
this.server = server;
this.port = DEFAULT_XMPP_PORT;
this.timeoutInterval = DEFAULT_TIMEOUT_INTERVAL;
initXMPPClient();
}
/**
* Constructor for XMPPTransportHandler passing server-IP and the XMPP-port.
*
* @param server the IP of the XMPP server.
* @param port the XMPP server's port to connect to. (default - 5222)
*/
protected XMPPTransportHandler(String server, int port) {
this.server = server;
this.port = port;
this.timeoutInterval = DEFAULT_TIMEOUT_INTERVAL;
initXMPPClient();
}
/**
* Constructor for XMPPTransportHandler passing server-IP, the XMPP-port and the
* timeoutInterval used by listeners to the server and for reconnection schedules.
*
* @param server the IP of the XMPP server.
* @param port the XMPP server's port to connect to. (default - 5222)
* @param timeoutInterval the timeout interval to use for the connection and reconnection
*/
@SuppressWarnings("unused")
protected XMPPTransportHandler(String server, int port, int timeoutInterval) {
this.server = server;
this.port = port;
this.timeoutInterval = timeoutInterval;
initXMPPClient();
}
/**
* Sets the client's time-out-limit whilst waiting for XMPP-replies from server.
*
* @param millis the time in millis to be set as the time-out-limit whilst waiting for a
* XMPP-reply.
*/
@SuppressWarnings("unused")
public void setTimeoutInterval(int millis) {
this.timeoutInterval = millis;
}
/**
* Checks whether the connection to the XMPP-Server persists.
*
* @return true if the client is connected to the XMPP-Server, else false.
*/
@Override
public boolean isConnected() {
return connection.isConnected();
}
/**
* Initializes the XMPP Client. Sets the time-out-limit whilst waiting for XMPP-replies from
* server. Sets the XMPP configurations to connect to the server and creates the
* XMPPConnection object used for connecting and Logging-In.
*/
private void initXMPPClient() {
log.info(String.format("Initializing connection to XMPP Server at %1$s via port " +
"%2$d.", server, port));
SmackConfiguration.setPacketReplyTimeout(timeoutInterval);
ConnectionConfiguration config = new ConnectionConfiguration(server, port);
// TODO:: Need to enable SASL-Authentication appropriately
config.setSASLAuthenticationEnabled(false);
config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
connection = new XMPPConnection(config);
}
//TODO:: Re-check all exception handling
/**
* Connects to the XMPP-Server and if attempt unsuccessful, then throws exception.
*
* @throws TransportHandlerException in the event of 'Connecting to' the XMPP server fails.
*/
protected void connectToServer() throws TransportHandlerException {
try {
connection.connect();
log.info(String.format(
"Connection to XMPP Server at %1$s established successfully......", server));
} catch (XMPPException xmppExcepion) {
String errorMsg =
"Connection attempt to the XMPP Server at " + server + " via port " + port +
" failed.";
log.info(errorMsg);
throw new TransportHandlerException(errorMsg, xmppExcepion);
}
}
/**
* If successfully established connection, then tries to Log in using the device's XMPP
* Account credentials.
*
* @param username the username of the device's XMPP-Account.
* @param password the password of the device's XMPP-Account.
* @param resource the resource the resource, specific to the XMPP-Account to which the login
* is made to
* @throws TransportHandlerException in the event of 'Logging into' the XMPP server fails.
*/
protected void loginToServer(String username, String password, String resource)
throws TransportHandlerException {
if (isConnected()) {
try {
if (resource == null) {
connection.login(username, password);
log.info(String.format("Logged into XMPP Server at %1$s as user %2$s......",
server, username));
} else {
connection.login(username, password, resource);
log.info(String.format(
"Logged into XMPP Server at %1$s as user %2$s on resource %3$s......",
server, username, resource));
}
} catch (XMPPException xmppException) {
String errorMsg =
"Login attempt to the XMPP Server at " + server + " with username - " +
username + " failed.";
log.info(errorMsg);
throw new TransportHandlerException(errorMsg, xmppException);
}
} else {//TODO:: Log not required
String errorMsg =
"Not connected to XMPP-Server to attempt Login. Please 'connectToServer' " +
"before Login";
if (log.isDebugEnabled()) {
log.debug(errorMsg);
}
throw new TransportHandlerException(errorMsg);
}
}
/**
* Sets a filter for all the incoming XMPP-Messages on the Sender's JID (XMPP-Account ID).
* Also creates a listener for the incoming messages and connects the listener to the
* XMPPConnection alongside the set filter.
*
* @param senderJID the JID (XMPP-Account ID of the sender) to which the filter is to be set.
*/
@SuppressWarnings("unused")
protected void setFilterOnSender(String senderJID) {
filter = new AndFilter(new PacketTypeFilter(Message.class), new FromContainsFilter(
senderJID));
listener = new PacketListener() {
@Override
public void processPacket(Packet packet) {
if (packet instanceof Message) {
final Message xmppMessage = (Message) packet;
Thread msgProcessThread = new Thread() {
public void run() {
try {
processIncomingMessage(xmppMessage);
} catch (TransportHandlerException e) {
log.error("An error occurred when trying to process received XMPP message " +
"[" + xmppMessage.getBody() + "].", e);
}
}
};
msgProcessThread.start();
}
}
};
connection.addPacketListener(listener, filter);
}
/**
* Sets a filter for all the incoming XMPP-Messages on the Receiver's JID (XMPP-Account ID).
* Also creates a listener for the incoming messages and connects the listener to the
* XMPPConnection alongside the set filter.
*
* @param receiverJID the JID (XMPP-Account ID of the receiver) to which the filter is to be
* set.
*/
protected void setFilterOnReceiver(String receiverJID) {
filter = new AndFilter(new PacketTypeFilter(Message.class), new ToContainsFilter(
receiverJID));
listener = new PacketListener() {
@Override
public void processPacket(Packet packet) {
if (packet instanceof Message) {
final Message xmppMessage = (Message) packet;
Thread msgProcessThread = new Thread() {
public void run() {
try {
processIncomingMessage(xmppMessage);
} catch (TransportHandlerException e) {
log.error("An error occurred when trying to process received XMPP message " +
"[" + xmppMessage.getBody() + "].", e);
}
}
};
msgProcessThread.start();
}
}
};
connection.addPacketListener(listener, filter);
}
/**
* Sets a filter for all the incoming XMPP-Messages on the From-JID & To-JID (XMPP-Account IDs)
* passed in. Also creates a listener for the incoming messages and connects the listener to
* the XMPPConnection alongside the set filter.
*
* @param senderJID the From-JID (XMPP-Account ID) to which the filter is to be set.
* @param receiverJID the To-JID (XMPP-Account ID) to which the filter is to be set.
* @param andCondition if true: then filter is set with 'AND' operator (senderJID &&
* receiverJID),
* if false: then the filter is set with 'OR' operator (senderJID |
* receiverJID)
*/
@SuppressWarnings("unused")
protected void setMessageFilterAndListener(String senderJID, String receiverJID, boolean
andCondition) {
PacketFilter jidFilter;
if (andCondition) {
jidFilter = new AndFilter(new FromContainsFilter(senderJID), new ToContainsFilter(
receiverJID));
} else {
jidFilter = new OrFilter(new FromContainsFilter(senderJID), new ToContainsFilter(
receiverJID));
}
filter = new AndFilter(new PacketTypeFilter(Message.class), jidFilter);
listener = new PacketListener() {
@Override
public void processPacket(Packet packet) {
if (packet instanceof Message) {
final Message xmppMessage = (Message) packet;
Thread msgProcessThread = new Thread() {
public void run() {
try {
processIncomingMessage(xmppMessage);
} catch (TransportHandlerException e) {
log.error("An error occurred when trying to process received XMPP message " +
"[" + xmppMessage.getBody() + "].", e);
}
}
};
msgProcessThread.start();
}
}
};
connection.addPacketListener(listener, filter);
}
/**
* Sends an XMPP message. Calls the overloaded method with Subject set to "Reply-From-Device"
*
* @param JID the JID (XMPP Account ID) to which the message is to be sent to.
* @param message the XMPP-Message that is to be sent.
*/
@SuppressWarnings("unused")
protected void sendXMPPMessage(String JID, String message) {
sendXMPPMessage(JID, message, "XMPP-Message");
}
/**
* Overloaded method to send an XMPP message. Includes the subject to be mentioned in the
* message that is sent.
*
* @param JID the JID (XMPP Account ID) to which the message is to be sent to.
* @param message the XMPP-Message that is to be sent.
* @param subject the subject that the XMPP-Message would carry.
*/
protected void sendXMPPMessage(String JID, String message, String subject) {
Message xmppMessage = new Message();
xmppMessage.setTo(JID);
xmppMessage.setSubject(subject);
xmppMessage.setBody(message);
xmppMessage.setType(Message.Type.chat);
sendXMPPMessage(JID, xmppMessage);
}
/**
* Sends an XMPP message.
*
* @param JID the JID (XMPP Account ID) to which the message is to be sent to.
* @param xmppMessage the XMPP-Message that is to be sent.
*/
protected void sendXMPPMessage(String JID, Message xmppMessage) {
connection.sendPacket(xmppMessage);
if (log.isDebugEnabled()) {
log.debug("Message: '" + xmppMessage.getBody() + "' sent to XMPP JID [" + JID + "] sent successfully.");
}
}
/**
* Closes the connection to the XMPP Server.
*/
public void closeConnection() {
if (connection != null && isConnected()) {
connection.disconnect();
}
}
}

@ -0,0 +1,60 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.url.printer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.core.ServerStartupObserver;
import org.wso2.carbon.device.mgt.iot.internal.IoTDeviceManagementDataHolder;
import org.wso2.carbon.utils.CarbonUtils;
import org.wso2.carbon.utils.ConfigurationContextService;
import org.wso2.carbon.utils.NetworkUtils;
public class URLPrinterStartupHandler implements ServerStartupObserver {
private static final Log log = LogFactory.getLog(URLPrinterStartupHandler.class);
@Override
public void completingServerStartup() {
}
@Override
public void completedServerStartup() {
log.info("IoT Console URL : " + this.getIoTUrl());
}
private String getIoTUrl() {
// Hostname
String hostName = "localhost";
try {
hostName = NetworkUtils.getMgtHostName();
} catch (Exception ignored) {
}
// HTTPS port
String mgtConsoleTransport = CarbonUtils.getManagementTransport();
ConfigurationContextService configContextService =
IoTDeviceManagementDataHolder.getInstance().getConfigurationContextService();
int port = CarbonUtils.getTransportPort(configContextService, mgtConsoleTransport);
int httpsProxyPort =
CarbonUtils.getTransportProxyPort(configContextService.getServerConfigContext(), mgtConsoleTransport);
if (httpsProxyPort > 0) {
port = httpsProxyPort;
}
return "https://" + hostName + ":" + port + "/devicemgt";
}
}

@ -18,73 +18,15 @@
package org.wso2.carbon.device.mgt.iot.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.device.mgt.iot.exception.IoTException;
import org.wso2.carbon.utils.NetworkUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.SocketException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
public class IoTUtil {
public static final String HOST_NAME = "HostName";
private static final Log log = LogFactory.getLog(IoTUtil.class);
private static final String HTTPS_PROTOCOL = "https";
/**
* Return a http client instance
* @param protocol- service endpoint protocol http/https
* @return
*/
public static HttpClient getHttpClient(int port, String protocol)
throws IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
HttpClient httpclient;
if (HTTPS_PROTOCOL.equals(protocol)) {
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build());
httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
} else {
httpclient = HttpClients.createDefault();
}
return httpclient;
}
public static String getResponseString(HttpResponse httpResponse) throws IOException {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent()));
String readLine;
String response = "";
while (((readLine = br.readLine()) != null)) {
response += readLine;
}
return response;
} finally {
EntityUtils.consumeQuietly(httpResponse.getEntity());
if (br != null) {
try {
br.close();
} catch (IOException e) {
log.warn("Error while closing the connection! " + e.getMessage());
}
}
}
}
public static String getHostName() throws IoTException {
String hostName = ServerConfiguration.getInstance().getFirstProperty(HOST_NAME);

@ -22,13 +22,8 @@ import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.utils.CarbonUtils;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
@ -42,28 +37,6 @@ public class IotDeviceManagementUtil {
private static final Log log = LogFactory.getLog(IotDeviceManagementUtil.class.getName());
public static Document convertToDocument(File file) throws DeviceManagementException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
try {
DocumentBuilder docBuilder = factory.newDocumentBuilder();
return docBuilder.parse(file);
} catch (Exception e) {
throw new DeviceManagementException("Error occurred while parsing file, while converting " +
"to a org.w3c.dom.Document : " + e.getMessage(), e);
}
}
private static Device.Property getProperty(String property, String value) {
if (property != null) {
Device.Property prop = new Device.Property();
prop.setName(property);
prop.setValue(value);
return prop;
}
return null;
}
public static ZipArchive getSketchArchive(String archivesPath, String templateSketchPath, Map contextParams)
throws DeviceManagementException, IOException {

@ -29,10 +29,6 @@ import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppAccount;
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig;
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppServerClient;
import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants;
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util.ZipUtil;
@ -178,9 +174,6 @@ public class RaspberryPiManagerServiceImpl implements RaspberryPiManagerService
} catch (APIManagerException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (DeviceControllerException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (IOException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
@ -216,13 +209,13 @@ public class RaspberryPiManagerServiceImpl implements RaspberryPiManagerService
}
private ZipArchive createDownloadFile(String owner, String deviceName, String sketchType)
throws DeviceManagementException, JWTClientException, APIManagerException, DeviceControllerException,
throws DeviceManagementException, JWTClientException, APIManagerException,
UserStoreException {
//create new device id
String deviceId = shortUUID();
if (apiApplicationKey == null) {
String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm().getRealmConfiguration()
.getAdminUserName();
String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
.getRealmConfiguration().getAdminUserName();
APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
String[] tags = {RaspberrypiConstants.DEVICE_TYPE};
apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
@ -235,27 +228,7 @@ public class RaspberryPiManagerServiceImpl implements RaspberryPiManagerService
//create token
String accessToken = accessTokenInfo.getAccessToken();
String refreshToken = accessTokenInfo.getRefreshToken();
//adding registering data
XmppAccount newXmppAccount = new XmppAccount();
newXmppAccount.setAccountName(owner + "_" + deviceId);
newXmppAccount.setUsername(deviceId);
newXmppAccount.setPassword(accessToken);
newXmppAccount.setEmail(deviceId + "@wso2.com");
XmppServerClient xmppServerClient = new XmppServerClient();
xmppServerClient.initControlQueue();
boolean status;
if (XmppConfig.getInstance().isEnabled()) {
status = xmppServerClient.createXMPPAccount(newXmppAccount);
if (!status) {
String msg = "XMPP Account was not created for device - " + deviceId + " of owner - " + owner +
".XMPP might have been disabled in org.wso2.carbon.device.mgt.iot.common.config" +
".server.configs";
log.warn(msg);
throw new DeviceManagementException(msg);
}
}
//Register the device with CDMF
status = register(deviceId, deviceName);
boolean status = register(deviceId, deviceName);
if (!status) {
String msg = "Error occurred while registering the device with " + "id: " + deviceId + " owner:" + owner;
throw new DeviceManagementException(msg);

@ -19,9 +19,8 @@
package org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig;
import org.wso2.carbon.device.mgt.iot.exception.IoTException;
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.util.IoTUtil;
import org.wso2.carbon.device.mgt.iot.util.IotDeviceManagementUtil;
import org.wso2.carbon.device.mgt.iot.util.ZipArchive;
@ -61,16 +60,10 @@ public class ZipUtil {
String httpsServerEP = HTTPS_PROTOCOL_APPENDER + iotServerIP + ":" + httpsServerPort;
String httpServerEP = HTTP_PROTOCOL_APPENDER + iotServerIP + ":" + httpServerPort;
String apimEndpoint = httpsServerEP;
String mqttEndpoint = MqttConfig.getInstance().getMqttQueueEndpoint();
String mqttEndpoint = MqttConfig.getInstance().getBrokerEndpoint();
if (mqttEndpoint.contains(LOCALHOST)) {
mqttEndpoint = mqttEndpoint.replace(LOCALHOST, iotServerIP);
}
String xmppEndpoint = XmppConfig.getInstance().getXmppEndpoint();
int indexOfChar = xmppEndpoint.lastIndexOf(":");
if (indexOfChar != -1) {
xmppEndpoint = xmppEndpoint.substring(0, indexOfChar);
}
xmppEndpoint = xmppEndpoint + ":" + XmppConfig.getInstance().getSERVER_CONNECTION_PORT();
Map<String, String> contextParams = new HashMap<>();
contextParams.put("SERVER_NAME", APIUtil.getTenantDomainOftheUser());
@ -81,7 +74,6 @@ public class ZipUtil {
contextParams.put("HTTP_EP", httpServerEP);
contextParams.put("APIM_EP", apimEndpoint);
contextParams.put("MQTT_EP", mqttEndpoint);
contextParams.put("XMPP_EP", xmppEndpoint);
contextParams.put("DEVICE_TOKEN", token);
contextParams.put("DEVICE_REFRESH_TOKEN", refreshToken);

@ -29,7 +29,6 @@
<jaxrs:serviceBeans>
<bean id="RaspberryPiControllerService"
class="org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.RaspberryPiControllerServiceImpl">
<property name="raspberryPiMQTTConnector" ref="raspberryPiMQTTConnector"/>
</bean>
<bean id="RaspberryPiManagerService"
class="org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.RaspberryPiManagerServiceImpl">
@ -39,9 +38,4 @@
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
</jaxrs:providers>
</jaxrs:server>
<bean id="raspberryPiMQTTConnector"
class="org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.transport.RaspberryPiMQTTConnector">
</bean>
</beans>

@ -18,6 +18,10 @@
package org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants;
import org.wso2.carbon.utils.CarbonUtils;
import java.io.File;
public class RaspberrypiConstants {
public final static String DEVICE_TYPE = "raspberrypi";
@ -57,4 +61,7 @@ public class RaspberrypiConstants {
public static final String CLEAR_SESSION_PROPERTY_KEY = "clearSession";
public static final String TOPIC = "topic";
public static final String MQTT_CONFIG_LOCATION = CarbonUtils.getEtcCarbonConfigDirPath() + File.separator
+ "mqtt.properties";
}

@ -52,7 +52,7 @@ public class RaspberrypiManagerService implements DeviceManagementService {
@Override
public ProvisioningConfig getProvisioningConfig() {
return new ProvisioningConfig(RaspberrypiConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true);
return new ProvisioningConfig(RaspberrypiConstants.DEVICE_TYPE_PROVIDER_DOMAIN, false);
}
@Override

@ -55,10 +55,6 @@ public class RaspberrypiUtils {
private static Log log = LogFactory.getLog(RaspberrypiUtils.class);
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) {
try {
@ -132,12 +128,12 @@ public class RaspberrypiUtils {
* @return OutputEventAdapterConfiguration instance for given configuration
*/
private static OutputEventAdapterConfiguration createMqttOutputEventAdapterConfiguration(String name, String type,
String msgFormat) throws IOException {
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);
File configFile = new File(RaspberrypiConstants.MQTT_CONFIG_LOCATION);
if (configFile.exists()) {
Map<String, String> mqttAdapterProperties = new HashMap<>();
InputStream propertyStream = configFile.toURI().toURL().openStream();
@ -161,7 +157,7 @@ public class RaspberrypiUtils {
return outputEventAdapterConfiguration;
}
private static String replaceMqttProperty(String urlWithPlaceholders) {
public static String replaceMqttProperty(String urlWithPlaceholders) {
urlWithPlaceholders = Utils.replaceSystemProperty(urlWithPlaceholders);
urlWithPlaceholders = urlWithPlaceholders.replaceAll(RaspberrypiConstants.MQTT_PORT, "" +
(RaspberrypiConstants.DEFAULT_MQTT_PORT + getPortOffset()));

@ -0,0 +1,60 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.mqtt;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants;
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl.util.RaspberrypiUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class MqttConfig {
private static String brokerEndpoint;
private static MqttConfig mqttConfig = new MqttConfig();
private static final Log log = LogFactory.getLog(MqttConfig.class);
private MqttConfig() {
File configFile = new File(RaspberrypiConstants.MQTT_CONFIG_LOCATION);
if (configFile.exists()) {
try {
InputStream propertyStream = configFile.toURI().toURL().openStream();
Properties properties = new Properties();
properties.load(propertyStream);
brokerEndpoint = RaspberrypiUtils.replaceMqttProperty(
properties.getProperty(RaspberrypiConstants.BROKER_URL_PROPERTY_KEY));
} catch (IOException e) {
log.error("Failed to read the mqtt.properties file" + e);
}
}
}
public static MqttConfig getInstance() {
return mqttConfig;
}
public String getBrokerEndpoint() {
return brokerEndpoint;
}
}

@ -67,7 +67,7 @@ public class TransportUtils {
}
ipPortMap.put("Protocol", ipPortArray[0]);
ipPortMap.put("Host", ipPortArray[1].replace(File.separator, ""));
ipPortMap.put("Host", ipPortArray[1].replace("/", ""));
ipPortMap.put("Port", ipPortArray[2]);
return ipPortMap;
}

@ -68,7 +68,7 @@ public class TransportUtils {
}
ipPortMap.put("Protocol", ipPortArray[0]);
ipPortMap.put("Host", ipPortArray[1].replace(File.separator, ""));
ipPortMap.put("Host", ipPortArray[1].replace("/", ""));
ipPortMap.put("Port", ipPortArray[2]);
return ipPortMap;
}

@ -31,7 +31,6 @@ 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.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;
@ -199,9 +198,6 @@ public class VirtualFireAlarmManagerServiceImpl implements VirtualFireAlarmManag
} catch (APIManagerException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (DeviceControllerException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
} catch (IOException ex) {
log.error(ex.getMessage(), ex);
return Response.status(500).entity(ex.getMessage()).build();
@ -241,7 +237,7 @@ public class VirtualFireAlarmManagerServiceImpl implements VirtualFireAlarmManag
}
private ZipArchive createDownloadFile(String owner, String deviceName, String sketchType)
throws DeviceManagementException, APIManagerException, JWTClientException, DeviceControllerException,
throws DeviceManagementException, APIManagerException, JWTClientException,
UserStoreException, VirtualFirealarmDeviceMgtPluginException {
//create new device id
String deviceId = shortUUID();

@ -19,12 +19,12 @@
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig;
import org.wso2.carbon.device.mgt.iot.exception.IoTException;
import org.wso2.carbon.device.mgt.iot.util.IoTUtil;
import org.wso2.carbon.device.mgt.iot.util.IotDeviceManagementUtil;
import org.wso2.carbon.device.mgt.iot.util.ZipArchive;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppConfig;
import org.wso2.carbon.utils.CarbonUtils;
import java.io.File;
@ -61,17 +61,15 @@ public class ZipUtil {
String httpsServerEP = HTTPS_PROTOCOL_APPENDER + iotServerIP + ":" + httpsServerPort;
String httpServerEP = HTTP_PROTOCOL_APPENDER + iotServerIP + ":" + httpServerPort;
String apimEndpoint = httpsServerEP;
String mqttEndpoint = MqttConfig.getInstance().getMqttQueueEndpoint();
String mqttEndpoint = MqttConfig.getInstance().getBrokerEndpoint();
if (mqttEndpoint.contains(LOCALHOST)) {
mqttEndpoint = mqttEndpoint.replace(LOCALHOST, iotServerIP);
}
String xmppEndpoint = XmppConfig.getInstance().getXmppEndpoint();
int indexOfChar = xmppEndpoint.lastIndexOf(":");
if (indexOfChar != -1) {
xmppEndpoint = xmppEndpoint.substring(0, indexOfChar);
String xmppEndpoint = XmppConfig.getInstance().getXmppServerIP() + ":" +
XmppConfig.getInstance().getXmppServerPort();
if (xmppEndpoint.contains(LOCALHOST)) {
xmppEndpoint = xmppEndpoint.replace(LOCALHOST, iotServerIP);
}
xmppEndpoint = xmppEndpoint + ":" + XmppConfig.getInstance().getSERVER_CONNECTION_PORT();
Map<String, String> contextParams = new HashMap<>();
contextParams.put("TENANT_DOMAIN", APIUtil.getTenantDomainOftheUser());
contextParams.put("DEVICE_OWNER", owner);
@ -81,7 +79,7 @@ public class ZipUtil {
contextParams.put("HTTP_EP", httpServerEP);
contextParams.put("APIM_EP", apimEndpoint);
contextParams.put("MQTT_EP", mqttEndpoint);
contextParams.put("XMPP_EP", xmppEndpoint);
contextParams.put("XMPP_EP", "XMPP:" + xmppEndpoint);
contextParams.put("DEVICE_TOKEN", token);
contextParams.put("DEVICE_REFRESH_TOKEN", refreshToken);

@ -18,6 +18,10 @@
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants;
import org.wso2.carbon.utils.CarbonUtils;
import java.io.File;
public class VirtualFireAlarmConstants {
public final static String DEVICE_TYPE = "virtual_firealarm";
public final static String DEVICE_PLUGIN_DEVICE_NAME = "DEVICE_NAME";
@ -66,6 +70,7 @@ public class VirtualFireAlarmConstants {
public static final String CONTENT_VALIDATION = "contentValidation";
public static final String CONTENT_TRANSFORMATION = "contentTransformer";
public static final String RESOURCE = "resource";
public static final String JSON_SERIAL_KEY = "SerialNumber";
public static final String TEMPERATURE_STREAM_DEFINITION = "org.wso2.iot.devices.temperature";
@ -79,4 +84,9 @@ public class VirtualFireAlarmConstants {
public static final String ADMIN_USERNAME = "admin.username";
public static final String ADMIN_PASSWORD = "admin.password";
public static final String XMPP_SERVER_PASSWORD = "admin@123456789";
public static final String MQTT_CONFIG_LOCATION = CarbonUtils.getEtcCarbonConfigDirPath() + File.separator
+ "mqtt.properties";
public static final String XMPP_CONFIG_LOCATION = CarbonUtils.getEtcCarbonConfigDirPath() + File.separator
+ "xmpp.properties";
}

@ -52,7 +52,7 @@ public class VirtualFireAlarmManagerService implements DeviceManagementService {
@Override
public ProvisioningConfig getProvisioningConfig() {
return new ProvisioningConfig(VirtualFireAlarmConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true);
return new ProvisioningConfig(VirtualFireAlarmConstants.DEVICE_TYPE_PROVIDER_DOMAIN, false);
}
@Override

@ -37,7 +37,6 @@ import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterExcep
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;
@ -62,9 +61,6 @@ import java.util.Properties;
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 + "conf" +
File.separator + "iot" + File.separator + "mqtt.properties";
public static void cleanupResources(Connection conn, PreparedStatement stmt, ResultSet rs) {
if (rs != null) {
@ -161,7 +157,7 @@ public class VirtualFireAlarmUtils {
outputEventAdapterConfiguration.setName(name);
outputEventAdapterConfiguration.setType(type);
outputEventAdapterConfiguration.setMessageFormat(msgFormat);
File configFile = new File(VIRTUAL_FIREALARM_CONFIG_LOCATION);
File configFile = new File(VirtualFireAlarmConstants.MQTT_CONFIG_LOCATION);
if (configFile.exists()) {
Map<String, String> mqttAdapterProperties = new HashMap<>();
InputStream propertyStream = configFile.toURI().toURL().openStream();
@ -180,6 +176,7 @@ public class VirtualFireAlarmUtils {
mqttAdapterProperties.put(VirtualFireAlarmConstants.QOS_PROPERTY_KEY, properties.getProperty(
VirtualFireAlarmConstants.QOS_PROPERTY_KEY));
mqttAdapterProperties.put(VirtualFireAlarmConstants.CLIENT_ID_PROPERTY_KEY, "");
mqttAdapterProperties.put(VirtualFireAlarmConstants.RESOURCE, "output-event");
outputEventAdapterConfiguration.setStaticProperties(mqttAdapterProperties);
}
return outputEventAdapterConfiguration;
@ -199,7 +196,7 @@ public class VirtualFireAlarmUtils {
inputEventAdapterConfiguration.setName(name);
inputEventAdapterConfiguration.setType(type);
inputEventAdapterConfiguration.setMessageFormat(msgFormat);
File configFile = new File(VIRTUAL_FIREALARM_CONFIG_LOCATION);
File configFile = new File(VirtualFireAlarmConstants.MQTT_CONFIG_LOCATION);
if (configFile.exists()) {
Map<String, String> mqttAdapterProperties = new HashMap<>();
InputStream propertyStream = configFile.toURI().toURL().openStream();
@ -222,12 +219,13 @@ public class VirtualFireAlarmUtils {
mqttAdapterProperties.put(VirtualFireAlarmConstants.CONTENT_TRANSFORMATION,
VirtualFirealarmMqttContentTransformer.class.getName());
mqttAdapterProperties.put(VirtualFireAlarmConstants.CONTENT_VALIDATION, "default");
mqttAdapterProperties.put(VirtualFireAlarmConstants.RESOURCE, "input-event");
inputEventAdapterConfiguration.setProperties(mqttAdapterProperties);
}
return inputEventAdapterConfiguration;
}
private static String replaceMqttProperty(String urlWithPlaceholders) {
public static String replaceMqttProperty(String urlWithPlaceholders) {
urlWithPlaceholders = Utils.replaceSystemProperty(urlWithPlaceholders);
urlWithPlaceholders = urlWithPlaceholders.replaceAll(VirtualFireAlarmConstants.MQTT_PORT, "" +
(VirtualFireAlarmConstants.DEFAULT_MQTT_PORT + getPortOffset()));

@ -0,0 +1,60 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.mqtt;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.impl.util.VirtualFireAlarmUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class MqttConfig {
private static String brokerEndpoint;
private static MqttConfig mqttConfig = new MqttConfig();
private static final Log log = LogFactory.getLog(MqttConfig.class);
private MqttConfig() {
File configFile = new File(VirtualFireAlarmConstants.MQTT_CONFIG_LOCATION);
if (configFile.exists()) {
try {
InputStream propertyStream = configFile.toURI().toURL().openStream();
Properties properties = new Properties();
properties.load(propertyStream);
brokerEndpoint = VirtualFireAlarmUtils.replaceMqttProperty(
properties.getProperty(VirtualFireAlarmConstants.BROKER_URL_PROPERTY_KEY));
} catch (IOException e) {
log.error("Failed to read the mqtt.properties file" + e);
}
}
}
public static MqttConfig getInstance() {
return mqttConfig;
}
public String getBrokerEndpoint() {
return brokerEndpoint;
}
}

@ -21,8 +21,6 @@ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException;
import org.wso2.carbon.utils.CarbonUtils;
import java.io.File;
import java.io.IOException;
@ -39,16 +37,11 @@ public class XmppConfig {
private String virtualFirealarmAdminUsername;
private String virtualFirealarmAdminPassword;
private String virtualFirealarmAdminJID;
private static final String VIRTUAL_FIREALARM_CONFIG_LOCATION =
CarbonUtils.getCarbonHome() + File.separator + "repository" + File.separator + "conf" +
File.separator + "iot" + File.separator + "xmpp.properties";
private static XmppConfig xmppConfig = new XmppConfig();
private static final Log log = LogFactory.getLog(XmppConfig.class);
private XmppConfig() {
File configFile = new File(VIRTUAL_FIREALARM_CONFIG_LOCATION);
File configFile = new File(VirtualFireAlarmConstants.XMPP_CONFIG_LOCATION);
if (configFile.exists()) {
try {
InputStream propertyStream = configFile.toURI().toURL().openStream();
@ -104,6 +97,4 @@ public class XmppConfig {
return virtualFirealarmAdminJID;
}
}

@ -47,6 +47,7 @@ public class XmppServerClient {
attributes.put("email", xmppAccount.getEmail());
attributes.put("name", xmppAccount.getAccountName());
accountManager.createAccount(xmppAccount.getUsername(), xmppAccount.getPassword(), attributes);
xmppConnection.disconnect();
return true;
} catch (XMPPException e) {
if (e.getXMPPError().getCode() == 409) {

@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<DeviceManagementConfigurations>
<ControlQueues>
<ControlQueue>
<Name>MQTT</Name>
<Enabled>true</Enabled>
<ControlClass>org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttControlPublisher</ControlClass>
<Protocol>MQTT</Protocol>
<!--<ServerURL>tcp://204.232.188.214</ServerURL>-->
<ServerURL>tcp://localhost</ServerURL>
<Port>1883</Port>
<Username>admin</Username>
<Password>admin</Password>
</ControlQueue>
<ControlQueue>
<Name>XMPP</Name>
<Enabled>false</Enabled>
<ControlClass>org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppServerClient</ControlClass>
<Protocol>XMPP</Protocol>
<ServerURL>http://localhost</ServerURL>
<Port>9090</Port>
<Username>admin</Username>
<Password>admin</Password>
</ControlQueue>
</ControlQueues>
</DeviceManagementConfigurations>

@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="DeviceManagementConfigurations" type="DeviceManagementConfigurations" />
<xs:complexType name="DeviceManagementConfigurations" >
<xs:sequence>
<xs:element type="ControlQueuesConfig" name="ControlQueues"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ControlQueuesConfig">
<xs:sequence>
<xs:element type="ControlQueue" name="ControlQueue" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ControlQueue">
<xs:sequence>
<xs:element type="xs:string" name="Name"/>
<xs:element type="xs:boolean" name="Enabled"/>
<xs:element type="xs:string" name="ControlClass"/>
<xs:element type="xs:string" name="Protocol"/>
<xs:element type="xs:string" name="ServerURL"/>
<xs:element type="xs:short" name="Port"/>
<xs:element type="xs:string" name="Username"/>
<xs:element type="xs:string" name="Password"/>
</xs:sequence>
</xs:complexType>
</xs:schema>

@ -1,8 +1,6 @@
instructions.configure = \
org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/jaggeryapps/);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot_${feature.version}/jaggeryapps/,target:${installFolder}/../../deployment/server/jaggeryapps/,overwrite:true);\
org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../conf/iot/);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot_${feature.version}/conf/mqtt.properties,target:${installFolder}/../../conf/iot/mqtt.properties,overwrite:true);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot_${feature.version}/conf/devicemgt-config.xml,target:${installFolder}/../../conf/iot/devicemgt-config.xml,overwrite:true);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot_${feature.version}/conf/devicemgt-config.xsd,target:${installFolder}/../../conf/iot/devicemgt-config.xsd,overwrite:true);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot_${feature.version}/conf/xmpp.properties,target:${installFolder}/../../conf/iot/xmpp.properties,overwrite:true);\
org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../conf/etc/);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot_${feature.version}/conf/mqtt.properties,target:${installFolder}/../../conf/etc/mqtt.properties,overwrite:true);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.iot_${feature.version}/conf/xmpp.properties,target:${installFolder}/../../conf/etc/xmpp.properties,overwrite:true);\
Loading…
Cancel
Save