forked from community/device-mgt-plugins
parent
10f75d5f73
commit
f880bda706
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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>
|
||||
* <complexType name="ControlQueue">
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element name="Name" type="{http://www.w3.org/2001/XMLSchema}string"/>
|
||||
* <element name="Enabled" type="{http://www.w3.org/2001/XMLSchema}boolean"/>
|
||||
* <element name="ControlClass" type="{http://www.w3.org/2001/XMLSchema}string"/>
|
||||
* <element name="Protocol" type="{http://www.w3.org/2001/XMLSchema}string"/>
|
||||
* <element name="ServerURL" type="{http://www.w3.org/2001/XMLSchema}string"/>
|
||||
* <element name="Port" type="{http://www.w3.org/2001/XMLSchema}short"/>
|
||||
* <element name="Username" type="{http://www.w3.org/2001/XMLSchema}string"/>
|
||||
* <element name="Password" type="{http://www.w3.org/2001/XMLSchema}string"/>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </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>
|
||||
* <complexType name="ControlQueuesConfig">
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element name="ControlQueue" type="{}ControlQueue" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </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>
|
||||
* <complexType name="DeviceManagementConfigurations">
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element name="ControlQueues" type="{}ControlQueuesConfig"/>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </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;
|
||||
}
|
||||
|
||||
}
|
@ -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";
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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…
Reference in new issue