Merge pull request #297 from Shabirmean/master

Modifications to incorporate token-refresh for Virtual Firealarm
revert-dabc3590
Ruwan 9 years ago
commit 71f972d027

@ -173,6 +173,13 @@
<artifactId>json</artifactId> <artifactId>json</artifactId>
</dependency> </dependency>
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<version>1.10</version>
</dependency>
</dependencies> </dependencies>

@ -23,12 +23,12 @@ import org.apache.commons.logging.LogFactory;
import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.AbstractHandler;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandlerException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportUtils;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.http.HTTPTransportHandler;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentConstants; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentManager; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentManager;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.exception.AgentCoreOperationException; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.exception.AgentCoreOperationException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandlerException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportUtils;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.http.HTTPTransportHandler;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -191,21 +191,19 @@ public class FireAlarmHTTPCommunicator extends HTTPTransportHandler {
private void executeDataPush(String pushDataPayload) { private void executeDataPush(String pushDataPayload) {
AgentManager agentManager = AgentManager.getInstance(); AgentManager agentManager = AgentManager.getInstance();
int responseCode = -1;
String pushDataEndPointURL = agentManager.getPushDataAPIEP(); String pushDataEndPointURL = agentManager.getPushDataAPIEP();
HttpURLConnection httpConnection = null; HttpURLConnection httpConnection;
int responseCode = -1;
try { try {
httpConnection = TransportUtils.getHttpConnection(agentManager.getPushDataAPIEP()); httpConnection = TransportUtils.getHttpConnection(agentManager.getPushDataAPIEP());
httpConnection.setRequestMethod(AgentConstants.HTTP_POST); httpConnection.setRequestMethod(AgentConstants.HTTP_POST);
httpConnection.setRequestProperty("Authorization", "Bearer " + httpConnection.setRequestProperty("Authorization",
agentManager.getAgentConfigs().getAuthToken()); "Bearer " + agentManager.getAgentConfigs().getAuthToken());
httpConnection.setRequestProperty("Content-Type", httpConnection.setRequestProperty("Content-Type", AgentConstants.APPLICATION_JSON);
AgentConstants.APPLICATION_JSON_TYPE);
httpConnection.setDoOutput(true); httpConnection.setDoOutput(true);
DataOutputStream dataOutPutWriter = new DataOutputStream( DataOutputStream dataOutPutWriter = new DataOutputStream(httpConnection.getOutputStream());
httpConnection.getOutputStream());
dataOutPutWriter.writeBytes(pushDataPayload); dataOutPutWriter.writeBytes(pushDataPayload);
dataOutPutWriter.flush(); dataOutPutWriter.flush();
dataOutPutWriter.close(); dataOutPutWriter.close();
@ -225,39 +223,34 @@ public class FireAlarmHTTPCommunicator extends HTTPTransportHandler {
} catch (IOException exception) { } catch (IOException exception) {
String errorMsg = String errorMsg =
"An IO error occurred whilst trying to get the response code from: " + "An IO error occurred whilst trying to get the response code from: " +
pushDataEndPointURL + " for a " + AgentConstants.HTTP_POST + pushDataEndPointURL + " for a " + AgentConstants.HTTP_POST + " method.";
" " + "method.";
log.error(AgentConstants.LOG_APPENDER + errorMsg); log.error(AgentConstants.LOG_APPENDER + errorMsg);
} catch (TransportHandlerException exception) { } catch (TransportHandlerException exception) {
log.error(AgentConstants.LOG_APPENDER + log.error(AgentConstants.LOG_APPENDER +
"Error encountered whilst trying to create HTTP-Connection " + "Error encountered whilst trying to create HTTP-Connection to IoT-Server EP at: " +
"to IoT-Server EP at: " +
pushDataEndPointURL); pushDataEndPointURL);
} }
if (responseCode == HttpStatus.CONFLICT_409 || if (responseCode == HttpStatus.CONFLICT_409 ||
responseCode == HttpStatus.PRECONDITION_FAILED_412) { responseCode == HttpStatus.PRECONDITION_FAILED_412) {
log.warn(AgentConstants.LOG_APPENDER + log.warn(AgentConstants.LOG_APPENDER +
"DeviceIP is being Re-Registered due to Push-Data failure " + "DeviceIP is being Re-Registered due to Push-Data failure with response code: " +
"with response code: " +
responseCode); responseCode);
registerThisDevice(); registerThisDevice();
} else if (responseCode != HttpStatus.NO_CONTENT_204) { } else if (responseCode != HttpStatus.NO_CONTENT_204) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.error(AgentConstants.LOG_APPENDER + "Status Code: " + responseCode + log.error(AgentConstants.LOG_APPENDER + "Status Code: " + responseCode +
" encountered whilst trying to Push-Device-Data to IoT " + " encountered whilst trying to Push-Device-Data to IoT Server at: " +
"Server at: " +
agentManager.getPushDataAPIEP()); agentManager.getPushDataAPIEP());
} }
agentManager.updateAgentStatus(AgentConstants.SERVER_NOT_RESPONDING); agentManager.updateAgentStatus(AgentConstants.SERVER_NOT_RESPONDING);
} }
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug(AgentConstants.LOG_APPENDER + "Push-Data call with payload - " + log.debug(AgentConstants.LOG_APPENDER + "Push-Data call with payload - " + pushDataPayload +
pushDataPayload + ", to IoT Server returned status " + ", to IoT Server returned status " + responseCode);
responseCode);
} }
} }
@ -272,16 +265,14 @@ public class FireAlarmHTTPCommunicator extends HTTPTransportHandler {
closeConnection(); closeConnection();
} catch (Exception e) { } catch (Exception e) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.warn(AgentConstants.LOG_APPENDER + log.warn(AgentConstants.LOG_APPENDER + "Unable to 'STOP' HTTP server at port: " + port);
"Unable to 'STOP' HTTP server at port: " + port);
} }
try { try {
Thread.sleep(timeoutInterval); Thread.sleep(timeoutInterval);
} catch (InterruptedException e1) { } catch (InterruptedException e1) {
log.error(AgentConstants.LOG_APPENDER + log.error(
"HTTP-Termination: Thread Sleep Interrupt " + AgentConstants.LOG_APPENDER + "HTTP-Termination: Thread Sleep Interrupt Exception");
"Exception");
} }
} }
} }
@ -398,8 +389,7 @@ public class FireAlarmHTTPCommunicator extends HTTPTransportHandler {
} catch (TransportHandlerException e) { } catch (TransportHandlerException e) {
String errorMsg = String errorMsg =
"Protocol specific error occurred when trying to fetch an HTTPConnection to:" + "Protocol specific error occurred when trying to fetch an HTTPConnection to:" +
" " + " " + registerEndpointURLString;
registerEndpointURLString;
log.error(AgentConstants.LOG_APPENDER + errorMsg); log.error(AgentConstants.LOG_APPENDER + errorMsg);
throw new AgentCoreOperationException(); throw new AgentCoreOperationException();
} }
@ -419,8 +409,7 @@ public class FireAlarmHTTPCommunicator extends HTTPTransportHandler {
} catch (IOException exception) { } catch (IOException exception) {
String errorMsg = "An IO error occurred whilst trying to get the response code from:" + String errorMsg = "An IO error occurred whilst trying to get the response code from:" +
" " + " " + registerEndpointURLString + " for a " + AgentConstants.HTTP_POST + " method.";
registerEndpointURLString + " for a " + AgentConstants.HTTP_POST + " method.";
log.error(AgentConstants.LOG_APPENDER + errorMsg); log.error(AgentConstants.LOG_APPENDER + errorMsg);
throw new AgentCoreOperationException(errorMsg, exception); throw new AgentCoreOperationException(errorMsg, exception);
} }

@ -22,6 +22,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage; import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttSecurityException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentConstants; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentManager; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentManager;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentUtilOperations; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentUtilOperations;
@ -35,13 +36,14 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
//TODO:: Lincense heade, comments and SPECIFIC class name since its not generic //TODO:: Lincence header, comments and SPECIFIC class name since its not generic
public class FireAlarmMQTTCommunicator extends MQTTTransportHandler { public class FireAlarmMQTTCommunicator extends MQTTTransportHandler {
private static final Log log = LogFactory.getLog(FireAlarmMQTTCommunicator.class); private static final Log log = LogFactory.getLog(FireAlarmMQTTCommunicator.class);
private ScheduledExecutorService service = Executors.newScheduledThreadPool(2); private ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
private ScheduledFuture<?> dataPushServiceHandler; private ScheduledFuture<?> dataPushServiceHandler;
private static final String DEFAULT_PASSWORD = "";
public FireAlarmMQTTCommunicator(String deviceOwner, String deviceType, public FireAlarmMQTTCommunicator(String deviceOwner, String deviceType,
String mqttBrokerEndPoint, String subscribeTopic) { String mqttBrokerEndPoint, String subscribeTopic) {
@ -68,18 +70,23 @@ public class FireAlarmMQTTCommunicator extends MQTTTransportHandler {
public void run() { public void run() {
while (!isConnected()) { while (!isConnected()) {
try { try {
connectToQueue(); connectToQueue(agentManager.getAgentConfigs().getAuthToken(), DEFAULT_PASSWORD);
agentManager.updateAgentStatus("Connected to MQTT Queue"); agentManager.updateAgentStatus("Connected to MQTT Queue");
} catch (TransportHandlerException e) { } catch (TransportHandlerException e) {
log.warn(AgentConstants.LOG_APPENDER + "Connection to MQTT Broker at: " + mqttBrokerEndPoint + log.warn(AgentConstants.LOG_APPENDER + "Connection to MQTT Broker at: " + mqttBrokerEndPoint +
" failed.\n Will retry in " + timeoutInterval + " milli-seconds."); " failed.\n Will retry in " + timeoutInterval + " milli-seconds.");
if (e.getCause() != null && e.getCause() instanceof MqttSecurityException) {
refreshOAuthToken((MqttSecurityException) e.getCause());
}
} }
try{ try {
if (isConnected()) {
subscribeToQueue(); subscribeToQueue();
agentManager.updateAgentStatus("Subscribed to MQTT Queue"); agentManager.updateAgentStatus("Subscribed to MQTT Queue");
publishDeviceData(); publishDeviceData();
}
} catch (TransportHandlerException e) { } catch (TransportHandlerException e) {
log.warn(AgentConstants.LOG_APPENDER + "Subscription to MQTT Broker at: " + log.warn(AgentConstants.LOG_APPENDER + "Subscription to MQTT Broker at: " +
mqttBrokerEndPoint + " failed"); mqttBrokerEndPoint + " failed");
@ -100,6 +107,26 @@ public class FireAlarmMQTTCommunicator extends MQTTTransportHandler {
connectorThread.start(); connectorThread.start();
} }
private void refreshOAuthToken(final MqttSecurityException exception) {
Runnable tokenRefresher = new Runnable() {
public void run() {
String authenticationMethod = AgentUtilOperations.getAuthenticationMethod();
try {
if (exception.getReasonCode() == MqttSecurityException.REASON_CODE_FAILED_AUTHENTICATION &&
authenticationMethod.equals(AgentConstants.TOKEN_AUTHENTICATION_METHOD)) {
AgentUtilOperations.refreshOAuthToken();
}
} catch (AgentCoreOperationException e1) {
log.error(AgentConstants.LOG_APPENDER + "Token Refresh Attempt Failed. " + e1);
}
}
};
Thread connectorThread = new Thread(tokenRefresher);
connectorThread.setDaemon(true);
connectorThread.start();
}
@Override @Override
public void processIncomingMessage(MqttMessage message, String... messageParams) { public void processIncomingMessage(MqttMessage message, String... messageParams) {

@ -35,6 +35,7 @@ public class AgentConfiguration {
private String apimGatewayEndpoint; private String apimGatewayEndpoint;
private String mqttBrokerEndpoint; private String mqttBrokerEndpoint;
private String xmppServerEndpoint; private String xmppServerEndpoint;
private String apiApplicationKey;
private String authMethod; private String authMethod;
private String authToken; private String authToken;
private String refreshToken; private String refreshToken;
@ -121,6 +122,14 @@ public class AgentConfiguration {
this.xmppServerEndpoint = xmppServerEndpoint; this.xmppServerEndpoint = xmppServerEndpoint;
} }
public String getApiApplicationKey() {
return apiApplicationKey;
}
public void setApiApplicationKey(String apiApplicationKey) {
this.apiApplicationKey = apiApplicationKey;
}
public String getAuthMethod() { public String getAuthMethod() {
return authMethod; return authMethod;
} }

@ -23,10 +23,10 @@ public class AgentConstants {
public static final String LOG_APPENDER = "AGENT_LOG:: "; public static final String LOG_APPENDER = "AGENT_LOG:: ";
public static final String PROPERTIES_FILE_PATH = ""; public static final String PROPERTIES_FILE_PATH = "";
public static final int DEFAULT_RETRY_THREAD_INTERVAL = 5000; // time in millis public static final int DEFAULT_RETRY_THREAD_INTERVAL = 5000; // time in millis
public static final String TOKEN_AUTHENTICATION_METHOD = "token";
/* --------------------------------------------------------------------------------------- /* ---------------------------------------------------------------------------------------
IoT-Server specific information IoT-Server specific information
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
public static final String DEVICE_CONTROLLER_API_EP = "/virtual_firealarm/controller";
public static final String DEVICE_ENROLLMENT_API_EP = "/scep"; public static final String DEVICE_ENROLLMENT_API_EP = "/scep";
public static final String DEVICE_REGISTER_API_EP = "/register"; public static final String DEVICE_REGISTER_API_EP = "/register";
public static final String DEVICE_PUSH_TEMPERATURE_API_EP = "/temperature"; public static final String DEVICE_PUSH_TEMPERATURE_API_EP = "/temperature";
@ -34,18 +34,22 @@ public class AgentConstants {
"{\"owner\":\"%s\",\"deviceId\":\"%s\",\"reply\":\"%s\",\"value\":\"%s\"}"; "{\"owner\":\"%s\",\"deviceId\":\"%s\",\"reply\":\"%s\",\"value\":\"%s\"}";
public static final String PUSH_SIMULATION_DATA_PAYLOAD = public static final String PUSH_SIMULATION_DATA_PAYLOAD =
"{\"owner\":\"%s\",\"deviceId\":\"%s\",\"reply\":\"%s\",\"value\":\"%s\",\"isSimulated\":\"%s\",\"duration\":\"%s\",\"frequency\":\"%s\"}"; "{\"owner\":\"%s\",\"deviceId\":\"%s\",\"reply\":\"%s\",\"value\":\"%s\",\"isSimulated\":\"%s\"," +
"\"duration\":\"%s\",\"frequency\":\"%s\"}";
public static final String AGENT_CONTROL_APP_EP = "/devicemgt/device/%s?id=%s";
public static final String DEVICE_DETAILS_PAGE_EP = "/devicemgt/device/%s?id=%s"; public static final String DEVICE_DETAILS_PAGE_EP = "/devicemgt/device/%s?id=%s";
public static final String DEVICE_ANALYTICS_PAGE_URL = "/devicemgt/device/virtual_firealarm/analytics?deviceId=%s&deviceName=%s"; public static final String DEVICE_ANALYTICS_PAGE_URL =
"/devicemgt/device/virtual_firealarm/analytics?deviceId=%s&deviceName=%s";
/* --------------------------------------------------------------------------------------- /* ---------------------------------------------------------------------------------------
HTTP Connection specific information for communicating with IoT-Server HTTP Connection specific information for communicating with IoT-Server
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
public static final String HTTP_POST = "POST"; public static final String HTTP_POST = "POST";
public static final String HTTP_GET = "GET"; public static final String HTTP_GET = "GET";
public static final String APPLICATION_JSON_TYPE = "application/json"; public static final String AUTHORIZATION_HEADER = "Authorization";
public static final String CONTENT_TYPE_HEADER = "Content-Type";
public static final String APPLICATION_JSON = "application/json";
public static final String X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded";
public static final String REGISTERED = "Registered"; public static final String REGISTERED = "Registered";
public static final String NOT_REGISTERED = "Not-Registered"; public static final String NOT_REGISTERED = "Not-Registered";
public static final String REGISTRATION_FAILED = "Registration Failed"; public static final String REGISTRATION_FAILED = "Registration Failed";
@ -59,10 +63,7 @@ public class AgentConstants {
public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0; public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0;
public static final String MQTT_SUBSCRIBE_TOPIC = "%s/" + DEVICE_TYPE + "/%s"; public static final String MQTT_SUBSCRIBE_TOPIC = "%s/" + DEVICE_TYPE + "/%s";
public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/publisher"; public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/publisher";
/* ---------------------------------------------------------------------------------------
XMPP Connection specific information
--------------------------------------------------------------------------------------- */
public static final String XMPP_ADMIN_ACCOUNT_UNAME = "admin";
/* --------------------------------------------------------------------------------------- /* ---------------------------------------------------------------------------------------
Device/Agent specific properties to be read from the 'deviceConfig.properties' file Device/Agent specific properties to be read from the 'deviceConfig.properties' file
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
@ -79,6 +80,7 @@ public class AgentConstants {
public static final String MQTT_BROKER_EP_PROPERTY = "mqtt-ep"; public static final String MQTT_BROKER_EP_PROPERTY = "mqtt-ep";
public static final String XMPP_SERVER_EP_PROPERTY = "xmpp-ep"; public static final String XMPP_SERVER_EP_PROPERTY = "xmpp-ep";
public static final String XMPP_SERVER_NAME_PROPERTY = "xmpp-server-name"; public static final String XMPP_SERVER_NAME_PROPERTY = "xmpp-server-name";
public static final String API_APPLICATION_KEY = "application-key";
public static final String AUTH_METHOD_PROPERTY = "auth-method"; public static final String AUTH_METHOD_PROPERTY = "auth-method";
public static final String AUTH_TOKEN_PROPERTY = "auth-token"; public static final String AUTH_TOKEN_PROPERTY = "auth-token";
public static final String REFRESH_TOKEN_PROPERTY = "refresh-token"; public static final String REFRESH_TOKEN_PROPERTY = "refresh-token";
@ -109,4 +111,17 @@ public class AgentConstants {
public static final String HTTP_PROTOCOL = "HTTP"; public static final String HTTP_PROTOCOL = "HTTP";
public static final String MQTT_PROTOCOL = "MQTT"; public static final String MQTT_PROTOCOL = "MQTT";
public static final String XMPP_PROTOCOL = "XMPP"; public static final String XMPP_PROTOCOL = "XMPP";
public static final String PROTOCOL_PROPERTY = "Protocol";
public static final String HOST_PROPERTY = "Host";
public static final String PORT_PROPERTY = "Port";
/* ---------------------------------------------------------------------------------------
Keystore specific strings for the device trustStore
--------------------------------------------------------------------------------------- */
public static final String DEVICE_KEYSTORE_TYPE = "JKS";
public static final String DEVICE_KEYSTORE = "virtual_firealarm.jks";
public static final String DEVICE_KEYSTORE_PASSWORD = "wso2@virtual_firealarm";
public static final String DEVICE_PRIVATE_KEY_ALIAS = "virtual_firealarm_key";
public static final String DEVICE_CERT_ALIAS = "virtual_firealarm_cert";
public static final String SERVER_CA_CERT_ALIAS = "ca_iotServer";
} }

@ -20,14 +20,14 @@ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.communication.http.FireAlarmHTTPCommunicator;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.communication.mqtt.FireAlarmMQTTCommunicator;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.communication.xmpp.FireAlarmXMPPCommunicator;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.enrollment.EnrollmentManager; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.enrollment.EnrollmentManager;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.exception.AgentCoreOperationException; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.exception.AgentCoreOperationException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandler; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandler;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandlerException; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandlerException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportUtils; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportUtils;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.communication.http.FireAlarmHTTPCommunicator;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.communication.mqtt.FireAlarmMQTTCommunicator;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.communication.xmpp.FireAlarmXMPPCommunicator;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.virtual.VirtualHardwareManager; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.virtual.VirtualHardwareManager;
import java.util.ArrayList; import java.util.ArrayList;
@ -74,18 +74,19 @@ public class AgentManager {
public void init() { public void init() {
agentCommunicator = new HashMap<>(); agentCommunicator = new HashMap<>();
// Read IoT-Server specific configurations from the 'deviceConfig.properties' file // Read IoT-Server specific configurations from the 'deviceConfig.properties' file
try { try {
this.agentConfigs = AgentUtilOperations.readIoTServerConfigs(); this.agentConfigs = AgentUtilOperations.readIoTServerConfigs();
} catch (AgentCoreOperationException e) { } catch (AgentCoreOperationException e) {
log.error("Reading device configuration from configd file failed:\n"); log.error("Reading device configuration from configuration file failed:\n");
log.error(e); log.error(e);
System.exit(0); System.exit(0);
} }
// Initialise IoT-Server URL endpoints from the configuration read from file // Initialise IoT-Server URL endpoints from the configuration read from file
AgentUtilOperations.initializeServerEndPoints(); AgentUtilOperations.initializeServerEndPoints();
// Set the hostNameVerifier to the APIM-Server IPAddress to enable HTTPS handshake
AgentUtilOperations.setHTTPSConfigurations();
String analyticsPageContext = String.format(AgentConstants.DEVICE_ANALYTICS_PAGE_URL, String analyticsPageContext = String.format(AgentConstants.DEVICE_ANALYTICS_PAGE_URL,
agentConfigs.getDeviceId(), agentConfigs.getDeviceId(),
@ -153,7 +154,9 @@ public class AgentManager {
} }
try { try {
if (!EnrollmentManager.getInstance().isEnrolled()) {
EnrollmentManager.getInstance().beginEnrollmentFlow(); EnrollmentManager.getInstance().beginEnrollmentFlow();
}
} catch (AgentCoreOperationException e) { } catch (AgentCoreOperationException e) {
log.error("Device Enrollment Failed:\n"); log.error("Device Enrollment Failed:\n");
log.error(e); log.error(e);
@ -223,6 +226,10 @@ public class AgentManager {
this.rootPath = rootPath; this.rootPath = rootPath;
} }
public String getRootPath() {
return rootPath;
}
public void setDeviceReady(boolean deviceReady) { public void setDeviceReady(boolean deviceReady) {
this.deviceReady = deviceReady; this.deviceReady = deviceReady;
} }
@ -324,6 +331,7 @@ public class AgentManager {
/** /**
* Get temperature reading from device * Get temperature reading from device
*
* @return Temperature * @return Temperature
*/ */
public int getTemperature() { public int getTemperature() {
@ -332,9 +340,10 @@ public class AgentManager {
/** /**
* Get humidity reading from device * Get humidity reading from device
*
* @return Humidity * @return Humidity
*/ */
public int getHumidity(){ public int getHumidity() {
return VirtualHardwareManager.getInstance().getHumidity(); return VirtualHardwareManager.getInstance().getHumidity();
} }

@ -19,19 +19,30 @@
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core; package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.eclipse.jetty.http.HttpStatus;
import org.json.JSONObject; import org.json.JSONObject;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.enrollment.EnrollmentManager; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.enrollment.EnrollmentManager;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.exception.AgentCoreOperationException; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.exception.AgentCoreOperationException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.CommunicationUtils; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.CommunicationUtils;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandlerException; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandlerException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportUtils;
import java.io.File; import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL; import java.net.URL;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -67,18 +78,21 @@ public class AgentUtilOperations {
Properties properties = new Properties(); Properties properties = new Properties();
InputStream propertiesInputStream = null; InputStream propertiesInputStream = null;
String propertiesFileName = AgentConstants.AGENT_PROPERTIES_FILE_NAME; String propertiesFileName = AgentConstants.AGENT_PROPERTIES_FILE_NAME;
String rootPath = "";
try { try {
ClassLoader loader = AgentUtilOperations.class.getClassLoader(); ClassLoader loader = AgentUtilOperations.class.getClassLoader();
URL path = loader.getResource(propertiesFileName); URL path = loader.getResource(propertiesFileName);
System.out.println(path);
String root = path.getPath().replace("wso2-firealarm-virtual-agent.jar!/deviceConfig.properties", "") if (path != null) {
log.info(AgentConstants.LOG_APPENDER + path);
rootPath = path.getPath().replace("wso2-firealarm-virtual-agent.jar!/deviceConfig.properties", "")
.replace("jar:", "").replace("file:", ""); .replace("jar:", "").replace("file:", "");
root = URLDecoder.decode(root, StandardCharsets.UTF_8.toString()); rootPath = URLDecoder.decode(rootPath, StandardCharsets.UTF_8.toString());
agentManager.setRootPath(root); agentManager.setRootPath(rootPath);
String deviceConfigFilePath = root + AgentConstants.AGENT_PROPERTIES_FILE_NAME; String deviceConfigFilePath = rootPath + AgentConstants.AGENT_PROPERTIES_FILE_NAME;
propertiesInputStream = new FileInputStream(deviceConfigFilePath); propertiesInputStream = new FileInputStream(deviceConfigFilePath);
//load a properties file from class path, inside static method //load a properties file from class path, inside static method
@ -108,6 +122,8 @@ public class AgentUtilOperations {
AgentConstants.XMPP_SERVER_EP_PROPERTY)); AgentConstants.XMPP_SERVER_EP_PROPERTY));
iotServerConfigs.setXmppServerName(properties.getProperty( iotServerConfigs.setXmppServerName(properties.getProperty(
AgentConstants.XMPP_SERVER_NAME_PROPERTY)); AgentConstants.XMPP_SERVER_NAME_PROPERTY));
iotServerConfigs.setApiApplicationKey(properties.getProperty(
AgentConstants.API_APPLICATION_KEY));
iotServerConfigs.setAuthMethod(properties.getProperty( iotServerConfigs.setAuthMethod(properties.getProperty(
AgentConstants.AUTH_METHOD_PROPERTY)); AgentConstants.AUTH_METHOD_PROPERTY));
iotServerConfigs.setAuthToken(properties.getProperty( iotServerConfigs.setAuthToken(properties.getProperty(
@ -138,6 +154,8 @@ public class AgentUtilOperations {
iotServerConfigs.getXmppServerEndpoint()); iotServerConfigs.getXmppServerEndpoint());
log.info(AgentConstants.LOG_APPENDER + "Authentication Method: " + log.info(AgentConstants.LOG_APPENDER + "Authentication Method: " +
iotServerConfigs.getAuthMethod()); iotServerConfigs.getAuthMethod());
log.info(AgentConstants.LOG_APPENDER + "Base64Encoded API Application Key: " +
iotServerConfigs.getApiApplicationKey());
log.info(AgentConstants.LOG_APPENDER + "Authentication Token: " + log.info(AgentConstants.LOG_APPENDER + "Authentication Token: " +
iotServerConfigs.getAuthToken()); iotServerConfigs.getAuthToken());
log.info(AgentConstants.LOG_APPENDER + "Refresh Token: " + log.info(AgentConstants.LOG_APPENDER + "Refresh Token: " +
@ -146,9 +164,12 @@ public class AgentUtilOperations {
iotServerConfigs.getDataPushInterval()); iotServerConfigs.getDataPushInterval());
log.info(AgentConstants.LOG_APPENDER + "XMPP Server Name: " + log.info(AgentConstants.LOG_APPENDER + "XMPP Server Name: " +
iotServerConfigs.getXmppServerName()); iotServerConfigs.getXmppServerName());
} else {
throw new AgentCoreOperationException(
"Failed to load path of resource [" + propertiesFileName + "] from this classpath.");
}
} catch (FileNotFoundException ex) { } catch (FileNotFoundException ex) {
String errorMsg = "[" + propertiesFileName + "] file not found at: " + AgentConstants.PROPERTIES_FILE_PATH; String errorMsg = "[" + propertiesFileName + "] file not found at: " + rootPath;
log.error(AgentConstants.LOG_APPENDER + errorMsg); log.error(AgentConstants.LOG_APPENDER + errorMsg);
throw new AgentCoreOperationException(errorMsg); throw new AgentCoreOperationException(errorMsg);
@ -174,10 +195,6 @@ public class AgentUtilOperations {
/** /**
* This method constructs the URLs for each of the API Endpoints called by the device agent * This method constructs the URLs for each of the API Endpoints called by the device agent
* Ex: Register API, Push-Data API * Ex: Register API, Push-Data API
*
* @throws AgentCoreOperationException if any error occurs at socket level whilst trying to
* retrieve the deviceIP of the network-interface read
* from the configs file
*/ */
public static void initializeServerEndPoints() { public static void initializeServerEndPoints() {
AgentManager agentManager = AgentManager.getInstance(); AgentManager agentManager = AgentManager.getInstance();
@ -209,6 +226,26 @@ public class AgentUtilOperations {
log.info(AgentConstants.LOG_APPENDER + "Push-Data API EndPoint: " + pushDataEndPointURL); log.info(AgentConstants.LOG_APPENDER + "Push-Data API EndPoint: " + pushDataEndPointURL);
} }
public static void setHTTPSConfigurations() {
String apimEndpoint = AgentManager.getInstance().getAgentConfigs().getApimGatewayEndpoint();
System.setProperty("javax.net.ssl.trustStore", AgentConstants.DEVICE_KEYSTORE);
System.setProperty("javax.net.ssl.trustStorePassword", AgentConstants.DEVICE_KEYSTORE_PASSWORD);
try {
final String apimHost = TransportUtils.getHostAndPort(apimEndpoint).get(AgentConstants.HOST_PROPERTY);
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return hostname.equals(apimHost);
}
});
} catch (TransportHandlerException e) {
log.error(AgentConstants.LOG_APPENDER +
"Failed to set HTTPS HostNameVerifier to the APIMServer-Host using the APIM-Endpoint " +
"string [" + apimEndpoint + "].");
log.error(AgentConstants.LOG_APPENDER + e);
}
}
public static String prepareSecurePayLoad(String message) throws AgentCoreOperationException { public static String prepareSecurePayLoad(String message) throws AgentCoreOperationException {
PrivateKey devicePrivateKey = EnrollmentManager.getInstance().getPrivateKey(); PrivateKey devicePrivateKey = EnrollmentManager.getInstance().getPrivateKey();
@ -227,7 +264,6 @@ public class AgentUtilOperations {
jsonPayload.put(JSON_SIGNATURE_KEY, signedPayload); jsonPayload.put(JSON_SIGNATURE_KEY, signedPayload);
//below statements are temporary fix. //below statements are temporary fix.
jsonPayload.put(JSON_SERIAL_KEY, EnrollmentManager.getInstance().getSCEPCertificate().getSerialNumber()); jsonPayload.put(JSON_SERIAL_KEY, EnrollmentManager.getInstance().getSCEPCertificate().getSerialNumber());
return jsonPayload.toString(); return jsonPayload.toString();
} }
@ -265,6 +301,138 @@ public class AgentUtilOperations {
return actualMessage; return actualMessage;
} }
public static String getAuthenticationMethod() {
String authMethod = AgentManager.getInstance().getAgentConfigs().getAuthMethod();
switch (authMethod) {
case AgentConstants.TOKEN_AUTHENTICATION_METHOD:
return AgentConstants.TOKEN_AUTHENTICATION_METHOD;
default:
return "";
}
}
public static void refreshOAuthToken() throws AgentCoreOperationException {
AgentManager agentManager = AgentManager.getInstance();
String tokenEndpoint = agentManager.getAgentConfigs().getApimGatewayEndpoint();
tokenEndpoint = tokenEndpoint + APIManagerTokenUtils.TOKEN_ENDPOINT;
HttpURLConnection httpConnection = null;
BufferedReader connectionBuffer = null;
String requestPayload;
String dataFromBuffer;
StringBuilder responseMessage = new StringBuilder();
try {
String refreshToken = agentManager.getAgentConfigs().getRefreshToken();
String applicationScope = "device_type_" + AgentConstants.DEVICE_TYPE +
" device_" + agentManager.getAgentConfigs().getDeviceId();
requestPayload = APIManagerTokenUtils.GRANT_TYPE + "=" + APIManagerTokenUtils.REFRESH_TOKEN + "&" +
APIManagerTokenUtils.REFRESH_TOKEN + "=" + refreshToken + "&" +
APIManagerTokenUtils.SCOPE + "=" + applicationScope;
httpConnection = TransportUtils.getHttpConnection(tokenEndpoint);
httpConnection.setRequestMethod(AgentConstants.HTTP_POST);
httpConnection.setRequestProperty(AgentConstants.AUTHORIZATION_HEADER,
"Basic " + agentManager.getAgentConfigs().getApiApplicationKey());
httpConnection.setRequestProperty(AgentConstants.CONTENT_TYPE_HEADER, AgentConstants.X_WWW_FORM_URLENCODED);
httpConnection.setDoOutput(true);
DataOutputStream dataOutPutWriter = new DataOutputStream(httpConnection.getOutputStream());
dataOutPutWriter.writeBytes(requestPayload);
dataOutPutWriter.flush();
dataOutPutWriter.close();
log.info(AgentConstants.LOG_APPENDER + "Request to refresh OAuth token was sent to [" +
httpConnection.getURL() + "] with payload [" + requestPayload + "].");
log.info(AgentConstants.LOG_APPENDER + "Response [" + httpConnection.getResponseCode() + ":" +
httpConnection.getResponseMessage() + "] was received for token refresh attempt.");
if (httpConnection.getResponseCode() == HttpStatus.OK_200) {
connectionBuffer = new BufferedReader(new InputStreamReader(httpConnection.getInputStream()));
while ((dataFromBuffer = connectionBuffer.readLine()) != null) {
responseMessage.append(dataFromBuffer);
}
log.info(AgentConstants.LOG_APPENDER +
"Response " + responseMessage + " was received for the token refresh call.");
updateExistingTokens(responseMessage.toString());
} else if (httpConnection.getResponseCode() == HttpStatus.BAD_REQUEST_400) {
log.error(AgentConstants.LOG_APPENDER +
"Token refresh call returned with a [400 Bad Request].\nThe refresh-token has " +
"probably expired.\nPlease contact System-Admin to get a valid refresh-token.");
} else {
log.warn(AgentConstants.LOG_APPENDER + "There was an issue with refreshing the Access Token.");
}
} catch (TransportHandlerException e) {
throw new AgentCoreOperationException(e);
} catch (ProtocolException e) {
String errorMsg = "Protocol specific error occurred when trying to set method to " +
AgentConstants.HTTP_POST + " for endpoint at: " + tokenEndpoint;
log.error(AgentConstants.LOG_APPENDER + errorMsg);
throw new AgentCoreOperationException(errorMsg, e);
} catch (IOException e) {
String errorMsg = "An IO error occurred whilst trying to get the response code from: " + tokenEndpoint +
" for a HTTP " + AgentConstants.HTTP_POST + " call.";
log.error(AgentConstants.LOG_APPENDER + errorMsg);
throw new AgentCoreOperationException(errorMsg, e);
} finally {
if (connectionBuffer != null) {
try {
connectionBuffer.close();
} catch (IOException e) {
log.error(AgentConstants.LOG_APPENDER +
"Error encounter whilst attempting to close buffer to connection at: " +
tokenEndpoint);
}
}
if (httpConnection != null) {
httpConnection.disconnect();
}
}
}
private static void updateExistingTokens(String responseFromTokenEP) throws AgentCoreOperationException {
JSONObject jsonTokenObject = new JSONObject(responseFromTokenEP);
String newAccessToken = jsonTokenObject.get(APIManagerTokenUtils.ACCESS_TOKEN).toString();
String newRefreshToken = jsonTokenObject.get(APIManagerTokenUtils.REFRESH_TOKEN).toString();
if (newAccessToken == null || newRefreshToken == null) {
String msg =
"Neither Access-Token nor Refresh-Token was found in the response [" + responseFromTokenEP + "].";
log.error(AgentConstants.LOG_APPENDER + msg);
throw new AgentCoreOperationException(msg);
}
AgentManager.getInstance().getAgentConfigs().setAuthToken(newAccessToken);
AgentManager.getInstance().getAgentConfigs().setRefreshToken(newRefreshToken);
String deviceConfigFilePath =
AgentManager.getInstance().getRootPath() + AgentConstants.AGENT_PROPERTIES_FILE_NAME;
try {
PropertiesConfiguration propertyFileConfiguration = new PropertiesConfiguration(deviceConfigFilePath);
propertyFileConfiguration.setProperty(AgentConstants.AUTH_TOKEN_PROPERTY, newAccessToken);
propertyFileConfiguration.setProperty(AgentConstants.REFRESH_TOKEN_PROPERTY, newRefreshToken);
propertyFileConfiguration.save();
} catch (ConfigurationException e) {
String msg = "Error occurred whilst trying to update the [" + AgentConstants.AGENT_PROPERTIES_FILE_NAME +
"] at: " + deviceConfigFilePath + " will the new tokens.";
log.error(AgentConstants.LOG_APPENDER + msg);
throw new AgentCoreOperationException(msg);
}
}
private class APIManagerTokenUtils {
public static final String TOKEN_ENDPOINT = "/oauth2/token";
public static final String GRANT_TYPE = "grant_type";
public static final String ACCESS_TOKEN = "access_token";
public static final String REFRESH_TOKEN = "refresh_token";
public static final String SCOPE = "scope";
}
} }

@ -44,18 +44,24 @@ import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentManager;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.exception.AgentCoreOperationException; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.exception.AgentCoreOperationException;
import sun.security.x509.X509CertImpl; import sun.security.x509.X509CertImpl;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.security.Key;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.KeyPairGenerator; import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException; import java.security.NoSuchProviderException;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.Security; import java.security.Security;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertStore; import java.security.cert.CertStore;
import java.security.cert.CertStoreException; import java.security.cert.CertStoreException;
import java.security.cert.Certificate; import java.security.cert.Certificate;
@ -96,6 +102,7 @@ public class EnrollmentManager {
private PublicKey publicKey; private PublicKey publicKey;
private PublicKey serverPublicKey; private PublicKey serverPublicKey;
private X509Certificate SCEPCertificate; private X509Certificate SCEPCertificate;
private boolean isEnrolled = false;
/** /**
@ -104,6 +111,7 @@ public class EnrollmentManager {
*/ */
private EnrollmentManager() { private EnrollmentManager() {
this.SCEPUrl = AgentManager.getInstance().getEnrollmentEP(); this.SCEPUrl = AgentManager.getInstance().getEnrollmentEP();
setEnrollmentStatus();
} }
/** /**
@ -119,6 +127,63 @@ public class EnrollmentManager {
} }
public void setEnrollmentStatus() {
KeyStore keyStore;
try {
keyStore = KeyStore.getInstance(AgentConstants.DEVICE_KEYSTORE_TYPE);
keyStore.load(new FileInputStream(AgentConstants.DEVICE_KEYSTORE),
AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray());
this.isEnrolled = (keyStore.containsAlias(AgentConstants.DEVICE_CERT_ALIAS) &&
keyStore.containsAlias(AgentConstants.DEVICE_PRIVATE_KEY_ALIAS) &&
keyStore.containsAlias(AgentConstants.SERVER_CA_CERT_ALIAS));
} catch (KeyStoreException e) {
log.error(AgentConstants.LOG_APPENDER + "An error occurred whilst accessing the device KeyStore '" +
AgentConstants.DEVICE_KEYSTORE + "' with keystore type [" +
AgentConstants.DEVICE_KEYSTORE_TYPE + "] to ensure enrollment status.");
log.error(AgentConstants.LOG_APPENDER + e);
log.warn(AgentConstants.LOG_APPENDER + "Device will be re-enrolled.");
return;
} catch (CertificateException | NoSuchAlgorithmException e) {
log.error(AgentConstants.LOG_APPENDER + "An error occurred whilst trying to [load] the device KeyStore '" +
AgentConstants.DEVICE_KEYSTORE + "'.");
log.error(AgentConstants.LOG_APPENDER + e);
log.warn(AgentConstants.LOG_APPENDER + "Device will be re-enrolled.");
return;
} catch (IOException e) {
log.error(AgentConstants.LOG_APPENDER +
"An error occurred whilst trying to load input stream with the keystore file: " +
AgentConstants.DEVICE_KEYSTORE);
log.error(AgentConstants.LOG_APPENDER + e);
log.warn(AgentConstants.LOG_APPENDER + "Device will be re-enrolled.");
return;
}
try {
if (this.isEnrolled) {
this.SCEPCertificate = (X509Certificate) keyStore.getCertificate(AgentConstants.DEVICE_CERT_ALIAS);
this.privateKey = (PrivateKey) keyStore.getKey(AgentConstants.DEVICE_PRIVATE_KEY_ALIAS,
AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray());
this.publicKey = SCEPCertificate.getPublicKey();
X509Certificate serverCACert = (X509Certificate) keyStore.getCertificate(
AgentConstants.SERVER_CA_CERT_ALIAS);
this.serverPublicKey = serverCACert.getPublicKey();
log.info(AgentConstants.LOG_APPENDER +
"Device has already been enrolled. Hence, loaded certificate information from device" +
" trust-store.");
}
} catch (UnrecoverableKeyException | NoSuchAlgorithmException | KeyStoreException e) {
log.error(AgentConstants.LOG_APPENDER + "An error occurred whilst accessing the device KeyStore '" +
AgentConstants.DEVICE_KEYSTORE + "' to ensure enrollment status.");
log.error(AgentConstants.LOG_APPENDER + e);
log.warn(AgentConstants.LOG_APPENDER + "Device will be re-enrolled.");
this.isEnrolled = false;
}
}
/** /**
* Method to control the entire enrollment flow. This method calls the method to create the Private-Public Key * Method to control the entire enrollment flow. This method calls the method to create the Private-Public Key
* Pair, calls the specific method to generate the Certificate-Sign-Request, creates a one time self signed * Pair, calls the specific method to generate the Certificate-Sign-Request, creates a one time self signed
@ -181,14 +246,66 @@ public class EnrollmentManager {
this.SCEPCertificate = getSignedCertificateFromServer(tmpCert, certSignRequest); this.SCEPCertificate = getSignedCertificateFromServer(tmpCert, certSignRequest);
this.serverPublicKey = initPublicKeyOfServer(); this.serverPublicKey = initPublicKeyOfServer();
storeCertificateToStore(AgentConstants.DEVICE_CERT_ALIAS, SCEPCertificate);
storeKeyToKeyStore(AgentConstants.DEVICE_PRIVATE_KEY_ALIAS, this.privateKey, SCEPCertificate);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.info(AgentConstants.LOG_APPENDER +
"SCEPCertificate, DevicePrivateKey, ServerPublicKey was saved to device keystore [" +
AgentConstants.DEVICE_KEYSTORE + "]");
log.info(AgentConstants.LOG_APPENDER + "TemporaryCertPublicKey:\n[\n" + tmpCert.getPublicKey() + "\n]\n"); log.info(AgentConstants.LOG_APPENDER + "TemporaryCertPublicKey:\n[\n" + tmpCert.getPublicKey() + "\n]\n");
log.info(AgentConstants.LOG_APPENDER + "ServerPublicKey:\n[\n" + serverPublicKey + "\n]\n"); log.info(AgentConstants.LOG_APPENDER + "ServerPublicKey:\n[\n" + serverPublicKey + "\n]\n");
} }
}
private void storeCertificateToStore(String alias, Certificate certificate) {
KeyStore keyStore;
try {
keyStore = KeyStore.getInstance(AgentConstants.DEVICE_KEYSTORE_TYPE);
keyStore.load(new FileInputStream(AgentConstants.DEVICE_KEYSTORE),
AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray());
keyStore.setCertificateEntry(alias, certificate);
keyStore.store(new FileOutputStream(AgentConstants.DEVICE_KEYSTORE),
AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray());
} catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException e) {
log.error(AgentConstants.LOG_APPENDER +
"An error occurred whilst trying to store the Certificate received from the SCEP " +
"Enrollment.");
log.error(AgentConstants.LOG_APPENDER + e);
log.warn(AgentConstants.LOG_APPENDER +
"SCEP Certificate was not stored in the keystore; " +
"Hence the device will be re-enrolled during next restart.");
}
} }
private void storeKeyToKeyStore(String alias, Key cryptoKey, Certificate certInCertChain) {
KeyStore keyStore;
try {
keyStore = KeyStore.getInstance(AgentConstants.DEVICE_KEYSTORE_TYPE);
keyStore.load(new FileInputStream(AgentConstants.DEVICE_KEYSTORE),
AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray());
Certificate[] certChain = new Certificate[1];
certChain[0] = certInCertChain;
keyStore.setKeyEntry(alias, cryptoKey, AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray(), certChain);
keyStore.store(new FileOutputStream(AgentConstants.DEVICE_KEYSTORE),
AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray());
} catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException e) {
log.error(AgentConstants.LOG_APPENDER +
"An error occurred whilst trying to store the key with alias " +
"[" + alias + "] in the device keystore.");
log.error(AgentConstants.LOG_APPENDER + e);
log.warn(AgentConstants.LOG_APPENDER +
"Key [" + alias + "] was not stored in the keystore; " +
"Hence the device will be re-enrolled during next restart.");
}
}
/** /**
* This method creates the Public-Private Key pair for the current client. * This method creates the Public-Private Key pair for the current client.
* *
@ -382,6 +499,7 @@ public class EnrollmentManager {
// This is because the returned keystore may contain many certificates including RAs. // This is because the returned keystore may contain many certificates including RAs.
if (((Boolean) ((X509CertImpl) cert).getBasicConstraintsExtension().get(CERT_IS_CA_EXTENSION))) { if (((Boolean) ((X509CertImpl) cert).getBasicConstraintsExtension().get(CERT_IS_CA_EXTENSION))) {
serverCertPublicKey = cert.getPublicKey(); serverCertPublicKey = cert.getPublicKey();
storeCertificateToStore(AgentConstants.SERVER_CA_CERT_ALIAS, cert);
} }
} }
} }
@ -407,9 +525,9 @@ public class EnrollmentManager {
return serverCertPublicKey; return serverCertPublicKey;
} }
/** /**
* Gets the Public-Key of the client. * Gets the Public-Key of the client.
*
* @return the public key of the client. * @return the public key of the client.
*/ */
public PublicKey getPublicKey() { public PublicKey getPublicKey() {
@ -418,6 +536,7 @@ public class EnrollmentManager {
/** /**
* Gets the Private-Key of the client. * Gets the Private-Key of the client.
*
* @return the private key of the client. * @return the private key of the client.
*/ */
public PrivateKey getPrivateKey() { public PrivateKey getPrivateKey() {
@ -426,6 +545,7 @@ public class EnrollmentManager {
/** /**
* Gets the SCEP-Certificate of the client. * Gets the SCEP-Certificate of the client.
*
* @return the SCEP Certificate of the client. * @return the SCEP Certificate of the client.
*/ */
public X509Certificate getSCEPCertificate() { public X509Certificate getSCEPCertificate() {
@ -434,9 +554,19 @@ public class EnrollmentManager {
/** /**
* Gets the Public-Key of the Server. * Gets the Public-Key of the Server.
*
* @return the pubic key of the server. * @return the pubic key of the server.
*/ */
public PublicKey getServerPublicKey() { public PublicKey getServerPublicKey() {
return serverPublicKey; return serverPublicKey;
} }
/**
* Checks whether the device has already been enrolled with the SCEP Server.
*
* @return the enrollment status; 'TRUE' if already enrolled else 'FALSE'.
*/
public boolean isEnrolled() {
return isEnrolled;
}
} }

@ -20,6 +20,7 @@ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandlerException; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandlerException;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -67,9 +68,9 @@ public class TransportUtils {
throw new TransportHandlerException(errorMsg); throw new TransportHandlerException(errorMsg);
} }
ipPortMap.put("Protocol", ipPortArray[0]); ipPortMap.put(AgentConstants.PROTOCOL_PROPERTY, ipPortArray[0]);
ipPortMap.put("Host", ipPortArray[1].replace("/", "")); ipPortMap.put(AgentConstants.HOST_PROPERTY, ipPortArray[1].replace("/", ""));
ipPortMap.put("Port", ipPortArray[2]); ipPortMap.put(AgentConstants.PORT_PROPERTY, ipPortArray[2]);
return ipPortMap; return ipPortMap;
} }
@ -99,8 +100,7 @@ public class TransportUtils {
return !ipAddress.endsWith("."); return !ipAddress.endsWith(".");
} catch (NumberFormatException nfe) { } catch (NumberFormatException nfe) {
log.warn("The IP Address: " + ipAddress + " could not " + log.warn("The IP Address: " + ipAddress + " could not be validated against IPv4-style");
"be validated against IPv4-style");
return false; return false;
} }
} }

@ -52,7 +52,6 @@ import java.nio.charset.StandardCharsets;
public abstract class MQTTTransportHandler public abstract class MQTTTransportHandler
implements MqttCallback, TransportHandler<MqttMessage> { implements MqttCallback, TransportHandler<MqttMessage> {
private static final Log log = LogFactory.getLog(MQTTTransportHandler.class); private static final Log log = LogFactory.getLog(MQTTTransportHandler.class);
private static final String DEFAULT_PASSWORD = "";
public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0; public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0;
private MqttClient client; private MqttClient client;
@ -82,8 +81,6 @@ public abstract class MQTTTransportHandler
this.mqttBrokerEndPoint = mqttBrokerEndPoint; this.mqttBrokerEndPoint = mqttBrokerEndPoint;
this.timeoutInterval = DEFAULT_TIMEOUT_INTERVAL; this.timeoutInterval = DEFAULT_TIMEOUT_INTERVAL;
this.initSubscriber(); this.initSubscriber();
options.setUserName(AgentManager.getInstance().getAgentConfigs().getAuthToken());
options.setPassword(DEFAULT_PASSWORD.toCharArray());
} }
/** /**
@ -108,8 +105,6 @@ public abstract class MQTTTransportHandler
this.mqttBrokerEndPoint = mqttBrokerEndPoint; this.mqttBrokerEndPoint = mqttBrokerEndPoint;
this.timeoutInterval = intervalInMillis; this.timeoutInterval = intervalInMillis;
this.initSubscriber(); this.initSubscriber();
options.setUserName(AgentManager.getInstance().getAgentConfigs().getAuthToken());
options.setPassword(DEFAULT_PASSWORD.toCharArray());
} }
public void setTimeoutInterval(int timeoutInterval) { public void setTimeoutInterval(int timeoutInterval) {
@ -156,6 +151,12 @@ public abstract class MQTTTransportHandler
} }
protected void connectToQueue(String username, String password) throws TransportHandlerException {
options.setUserName(username);
options.setPassword(password.toCharArray());
connectToQueue();
}
/** /**
* Connects to the MQTT-Broker and if successfully established connection. * Connects to the MQTT-Broker and if successfully established connection.
* *
@ -248,8 +249,7 @@ public abstract class MQTTTransportHandler
try { try {
client.publish(topic, payLoad.getBytes(StandardCharsets.UTF_8), qos, retained); client.publish(topic, payLoad.getBytes(StandardCharsets.UTF_8), qos, retained);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Message: " + payLoad + " to MQTT topic [" + topic + log.debug("Message: " + payLoad + " to MQTT topic [" + topic + "] published successfully");
"] published successfully");
} }
} catch (MqttException ex) { } catch (MqttException ex) {
String errorMsg = String errorMsg =
@ -267,8 +267,7 @@ public abstract class MQTTTransportHandler
try { try {
client.publish(topic, message); client.publish(topic, message);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Message: " + message.toString() + " to MQTT topic [" + topic + log.debug("Message: " + message.toString() + " to MQTT topic [" + topic + "] published successfully");
"] published successfully");
} }
} catch (MqttException ex) { } catch (MqttException ex) {
//TODO:: Compulsory log of errors and remove formatted error //TODO:: Compulsory log of errors and remove formatted error
@ -291,8 +290,7 @@ public abstract class MQTTTransportHandler
@Override @Override
public void connectionLost(Throwable throwable) { public void connectionLost(Throwable throwable) {
log.warn("Lost Connection for client: " + this.clientId + log.warn("Lost Connection for client: " + this.clientId +
" to " + this.mqttBrokerEndPoint + ".\nThis was due to - " + " to " + this.mqttBrokerEndPoint + ".\nThis was due to - " + throwable.getMessage());
throwable.getMessage());
Thread reconnectThread = new Thread() { Thread reconnectThread = new Thread() {
public void run() { public void run() {
@ -340,8 +338,7 @@ public abstract class MQTTTransportHandler
} catch (MqttException e) { } catch (MqttException e) {
//TODO:: Throw errors //TODO:: Throw errors
log.error( log.error(
"Error occurred whilst trying to read the message from the MQTT delivery " + "Error occurred whilst trying to read the message from the MQTT delivery token.");
"token.");
} }
String topic = iMqttDeliveryToken.getTopics()[0]; String topic = iMqttDeliveryToken.getTopics()[0];
String client = iMqttDeliveryToken.getClient().getClientId(); String client = iMqttDeliveryToken.getClient().getClientId();

@ -1,4 +1,4 @@
# ad#
# Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. # Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");

@ -54,13 +54,27 @@ import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreException;
import javax.ws.rs.*; import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.util.*; import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;
public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService { public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
@ -136,7 +150,8 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
List<DeviceIdentifier> deviceIdentifiers = new ArrayList<>(); List<DeviceIdentifier> deviceIdentifiers = new ArrayList<>();
deviceIdentifiers.add(new DeviceIdentifier(deviceId, VirtualFireAlarmConstants.DEVICE_TYPE)); deviceIdentifiers.add(new DeviceIdentifier(deviceId, VirtualFireAlarmConstants.DEVICE_TYPE));
APIUtil.getDeviceManagementService().addOperation(VirtualFireAlarmConstants.DEVICE_TYPE, commandOp, deviceIdentifiers); APIUtil.getDeviceManagementService().addOperation(VirtualFireAlarmConstants.DEVICE_TYPE, commandOp,
deviceIdentifiers);
break; break;
} }
return Response.ok().build(); return Response.ok().build();
@ -319,14 +334,16 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
scopes); scopes);
String accessToken = accessTokenInfo.getAccessToken(); String accessToken = accessTokenInfo.getAccessToken();
String refreshToken = accessTokenInfo.getRefreshToken(); String refreshToken = accessTokenInfo.getRefreshToken();
//adding registering data
boolean status;
if (XmppConfig.getInstance().isEnabled()) {
XmppAccount newXmppAccount = new XmppAccount(); XmppAccount newXmppAccount = new XmppAccount();
newXmppAccount.setAccountName(deviceId); newXmppAccount.setAccountName(deviceId);
newXmppAccount.setUsername(deviceId); newXmppAccount.setUsername(deviceId);
newXmppAccount.setPassword(accessToken); newXmppAccount.setPassword(accessToken);
newXmppAccount.setEmail(deviceId + "@" + APIUtil.getTenantDomainOftheUser()); newXmppAccount.setEmail(deviceId + "@" + APIUtil.getTenantDomainOftheUser());
boolean status;
if (XmppConfig.getInstance().isEnabled()) {
status = XmppServerClient.createAccount(newXmppAccount); status = XmppServerClient.createAccount(newXmppAccount);
if (!status) { if (!status) {
String msg = "XMPP Account was not created for device - " + deviceId + " of owner - " + owner + String msg = "XMPP Account was not created for device - " + deviceId + " of owner - " + owner +
@ -335,14 +352,16 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
throw new DeviceManagementException(msg); throw new DeviceManagementException(msg);
} }
} }
status = register(deviceId, deviceName); status = register(deviceId, deviceName);
if (!status) { if (!status) {
String msg = "Error occurred while registering the device with " + "id: " + deviceId + " owner:" + owner; String msg = "Error occurred while registering the device with " + "id: " + deviceId + " owner:" + owner;
throw new DeviceManagementException(msg); throw new DeviceManagementException(msg);
} }
ZipUtil ziputil = new ZipUtil(); ZipUtil ziputil = new ZipUtil();
return ziputil.createZipFile(owner, APIUtil.getTenantDomainOftheUser(), sketchType, deviceId, return ziputil.createZipFile(owner, sketchType, deviceId, deviceName, apiApplicationKey.toString(),
deviceName, accessToken, refreshToken); accessToken, refreshToken);
} }
private static String shortUUID() { private static String shortUUID() {
@ -350,5 +369,4 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService {
long l = ByteBuffer.wrap(uuid.toString().getBytes(StandardCharsets.UTF_8)).getLong(); long l = ByteBuffer.wrap(uuid.toString().getBytes(StandardCharsets.UTF_8)).getLong();
return Long.toString(l, Character.MAX_RADIX); return Long.toString(l, Character.MAX_RADIX);
} }
} }

@ -0,0 +1,20 @@
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.xmpp.XmppConfig;
public class VirtualFireAlarmUtilConstants {
public static final String TENANT_DOMAIN = "TENANT_DOMAIN";
public static final String DEVICE_OWNER = "DEVICE_OWNER";
public static final String DEVICE_ID = "DEVICE_ID";
public static final String DEVICE_NAME = "DEVICE_NAME";
public static final String HTTPS_EP = "HTTPS_EP";
public static final String HTTP_EP = "HTTP_EP";
public static final String APIM_EP = "APIM_EP";
public static final String MQTT_EP = "MQTT_EP";
public static final String XMPP_EP = "XMPP_EP";
public static final String API_APPLICATION_KEY = "API_APPLICATION_KEY";
public static final String DEVICE_TOKEN = "DEVICE_TOKEN";
public static final String DEVICE_REFRESH_TOKEN = "DEVICE_REFRESH_TOKEN";
public static final String SERVER_NAME = "SERVER_NAME";
}

@ -18,6 +18,11 @@
package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util; package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;
import org.wso2.carbon.apimgt.application.extension.constants.ApiApplicationConstants;
import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.iot.util.Utils; import org.wso2.carbon.device.mgt.iot.util.Utils;
import org.wso2.carbon.device.mgt.iot.util.ZipArchive; import org.wso2.carbon.device.mgt.iot.util.ZipArchive;
@ -35,6 +40,7 @@ import java.util.Map;
*/ */
public class ZipUtil { public class ZipUtil {
private static final Log log = LogFactory.getLog(ZipUtil.class);
private static final String HTTPS_PORT_PROPERTY = "httpsPort"; private static final String HTTPS_PORT_PROPERTY = "httpsPort";
private static final String HTTP_PORT_PROPERTY = "httpPort"; private static final String HTTP_PORT_PROPERTY = "httpPort";
@ -42,12 +48,13 @@ public class ZipUtil {
private static final String HTTPS_PROTOCOL_APPENDER = "https://"; private static final String HTTPS_PROTOCOL_APPENDER = "https://";
private static final String HTTP_PROTOCOL_APPENDER = "http://"; private static final String HTTP_PROTOCOL_APPENDER = "http://";
public ZipArchive createZipFile(String owner, String tenantDomain, String deviceType, public ZipArchive createZipFile(String owner, String deviceType, String deviceId, String deviceName,
String deviceId, String deviceName, String token, String apiApplicationKey, String token, String refreshToken)
String refreshToken) throws DeviceManagementException { throws DeviceManagementException {
String sketchFolder = "repository" + File.separator + "resources" + File.separator + "sketches"; String sketchFolder = "repository" + File.separator + "resources" + File.separator + "sketches";
String archivesPath = CarbonUtils.getCarbonHome() + File.separator + sketchFolder + File.separator + "archives" + String archivesPath =
CarbonUtils.getCarbonHome() + File.separator + sketchFolder + File.separator + "archives" +
File.separator + deviceId; File.separator + deviceId;
String templateSketchPath = sketchFolder + File.separator + deviceType; String templateSketchPath = sketchFolder + File.separator + deviceType;
String iotServerIP; String iotServerIP;
@ -63,24 +70,29 @@ public class ZipUtil {
if (mqttEndpoint.contains(LOCALHOST)) { if (mqttEndpoint.contains(LOCALHOST)) {
mqttEndpoint = mqttEndpoint.replace(LOCALHOST, iotServerIP); mqttEndpoint = mqttEndpoint.replace(LOCALHOST, iotServerIP);
} }
String xmppEndpoint = XmppConfig.getInstance().getXmppServerIP() + ":" + String xmppEndpoint = XmppConfig.getInstance().getXmppServerIP() + ":" +
XmppConfig.getInstance().getXmppServerPort(); XmppConfig.getInstance().getXmppServerPort();
if (xmppEndpoint.contains(LOCALHOST)) { if (xmppEndpoint.contains(LOCALHOST)) {
xmppEndpoint = xmppEndpoint.replace(LOCALHOST, iotServerIP); xmppEndpoint = xmppEndpoint.replace(LOCALHOST, iotServerIP);
} }
String base64EncodedApplicationKey = getBase64EncodedAPIAppKey(apiApplicationKey).trim();
Map<String, String> contextParams = new HashMap<>(); Map<String, String> contextParams = new HashMap<>();
contextParams.put("TENANT_DOMAIN", APIUtil.getTenantDomainOftheUser()); contextParams.put(VirtualFireAlarmUtilConstants.TENANT_DOMAIN, APIUtil.getTenantDomainOftheUser());
contextParams.put("DEVICE_OWNER", owner); contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_OWNER, owner);
contextParams.put("DEVICE_ID", deviceId); contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_ID, deviceId);
contextParams.put("DEVICE_NAME", deviceName); contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_NAME, deviceName);
contextParams.put("HTTPS_EP", httpsServerEP); contextParams.put(VirtualFireAlarmUtilConstants.HTTPS_EP, httpsServerEP);
contextParams.put("HTTP_EP", httpServerEP); contextParams.put(VirtualFireAlarmUtilConstants.HTTP_EP, httpServerEP);
contextParams.put("APIM_EP", apimEndpoint); contextParams.put(VirtualFireAlarmUtilConstants.APIM_EP, apimEndpoint);
contextParams.put("MQTT_EP", mqttEndpoint); contextParams.put(VirtualFireAlarmUtilConstants.MQTT_EP, mqttEndpoint);
contextParams.put("XMPP_EP", "XMPP:" + xmppEndpoint); contextParams.put(VirtualFireAlarmUtilConstants.XMPP_EP, "XMPP:" + xmppEndpoint);
contextParams.put("DEVICE_TOKEN", token); contextParams.put(VirtualFireAlarmUtilConstants.API_APPLICATION_KEY, base64EncodedApplicationKey);
contextParams.put("DEVICE_REFRESH_TOKEN", refreshToken); contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_TOKEN, token);
contextParams.put("SERVER_NAME", XmppConfig.getInstance().getXmppServerName()); contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_REFRESH_TOKEN, refreshToken);
contextParams.put(VirtualFireAlarmUtilConstants.SERVER_NAME, XmppConfig.getInstance().getXmppServerName());
ZipArchive zipFile; ZipArchive zipFile;
zipFile = Utils.getSketchArchive(archivesPath, templateSketchPath, contextParams, deviceName); zipFile = Utils.getSketchArchive(archivesPath, templateSketchPath, contextParams, deviceName);
return zipFile; return zipFile;
@ -88,4 +100,13 @@ public class ZipUtil {
throw new DeviceManagementException("Zip File Creation Failed", e); throw new DeviceManagementException("Zip File Creation Failed", e);
} }
} }
private String getBase64EncodedAPIAppKey(String apiAppCredentialsAsJSONString) {
JSONObject jsonObject = new JSONObject(apiAppCredentialsAsJSONString);
String consumerKey = jsonObject.get(ApiApplicationConstants.OAUTH_CLIENT_ID).toString();
String consumerSecret = jsonObject.get(ApiApplicationConstants.OAUTH_CLIENT_SECRET).toString();
String stringToEncode = consumerKey + ":" + consumerSecret;
return Base64.encodeBase64String(stringToEncode.getBytes());
}
} }

@ -6,6 +6,7 @@ import org.wso2.carbon.device.mgt.iot.input.adapter.extension.ContentTransformer
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.exception.VirtualFirealarmDeviceMgtPluginException;
import java.math.BigInteger;
import java.security.PublicKey; import java.security.PublicKey;
import java.util.Map; import java.util.Map;
@ -22,7 +23,7 @@ public class VirtualFirealarmMqttContentTransformer implements ContentTransforme
PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
ctx.setTenantDomain(tenantDomain, true); ctx.setTenantDomain(tenantDomain, true);
Long serialNo = (Long) jsonPayload.get(VirtualFireAlarmConstants.JSON_SERIAL_KEY); Integer serialNo = (Integer) jsonPayload.get(VirtualFireAlarmConstants.JSON_SERIAL_KEY);
// the hash-code of the deviceId is used as the alias for device certificates during SCEP enrollment. // the hash-code of the deviceId is used as the alias for device certificates during SCEP enrollment.
// hence, the same is used here to fetch the device-specific-certificate from the key store. // hence, the same is used here to fetch the device-specific-certificate from the key store.
PublicKey clientPublicKey = VirtualFireAlarmUtils.getDevicePublicKey("" + serialNo); PublicKey clientPublicKey = VirtualFireAlarmUtils.getDevicePublicKey("" + serialNo);

@ -28,6 +28,7 @@ apim-ep=${APIM_EP}
mqtt-ep=${MQTT_EP} mqtt-ep=${MQTT_EP}
xmpp-ep=${XMPP_EP} xmpp-ep=${XMPP_EP}
auth-method=token auth-method=token
application-key=${API_APPLICATION_KEY}
auth-token=${DEVICE_TOKEN} auth-token=${DEVICE_TOKEN}
refresh-token=${DEVICE_REFRESH_TOKEN} refresh-token=${DEVICE_REFRESH_TOKEN}
push-interval=15 push-interval=15

@ -28,6 +28,7 @@ apim-ep=${APIM_EP}
mqtt-ep=${MQTT_EP} mqtt-ep=${MQTT_EP}
xmpp-ep=${XMPP_EP} xmpp-ep=${XMPP_EP}
auth-method=token auth-method=token
application-key=${API_APPLICATION_KEY}
auth-token=${DEVICE_TOKEN} auth-token=${DEVICE_TOKEN}
refresh-token=${DEVICE_REFRESH_TOKEN} refresh-token=${DEVICE_REFRESH_TOKEN}
push-interval=15 push-interval=15

Loading…
Cancel
Save