From 75914aee4ecaf9cc6e4a9c4a5cfd4ddc17275546 Mon Sep 17 00:00:00 2001 From: Shabirmean Date: Sat, 21 May 2016 01:46:34 +0530 Subject: [PATCH 1/4] Changes to the VirtualFirealarm Agent + the API to enable token refresh upon expiration --- .../http/FireAlarmHTTPCommunicator.java | 53 ++-- .../mqtt/FireAlarmMQTTCommunicator.java | 2 +- .../agent/core/AgentConfiguration.java | 283 +++++++++--------- .../agent/core/AgentConstants.java | 176 +++++------ .../agent/core/AgentManager.java | 16 +- .../agent/core/AgentUtilOperations.java | 180 ++++++++++- .../main/resources/deviceConfig.properties | 2 +- .../impl/VirtualFireAlarmServiceImpl.java | 42 ++- .../util/VirtualFireAlarmUtilConstants.java | 20 ++ .../service/impl/util/ZipUtil.java | 53 +++- .../advanced_agent/deviceConfig.properties | 1 + 11 files changed, 526 insertions(+), 302 deletions(-) create mode 100644 components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/VirtualFireAlarmUtilConstants.java diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/communication/http/FireAlarmHTTPCommunicator.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/communication/http/FireAlarmHTTPCommunicator.java index 0f920e0d0..98dbc6dc7 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/communication/http/FireAlarmHTTPCommunicator.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/communication/http/FireAlarmHTTPCommunicator.java @@ -23,12 +23,12 @@ import org.apache.commons.logging.LogFactory; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.server.Request; 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.AgentManager; 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.http.HttpServletRequest; @@ -191,21 +191,19 @@ public class FireAlarmHTTPCommunicator extends HTTPTransportHandler { private void executeDataPush(String pushDataPayload) { AgentManager agentManager = AgentManager.getInstance(); - int responseCode = -1; String pushDataEndPointURL = agentManager.getPushDataAPIEP(); - HttpURLConnection httpConnection = null; + HttpURLConnection httpConnection; + int responseCode = -1; try { httpConnection = TransportUtils.getHttpConnection(agentManager.getPushDataAPIEP()); httpConnection.setRequestMethod(AgentConstants.HTTP_POST); - httpConnection.setRequestProperty("Authorization", "Bearer " + - agentManager.getAgentConfigs().getAuthToken()); - httpConnection.setRequestProperty("Content-Type", - AgentConstants.APPLICATION_JSON_TYPE); + httpConnection.setRequestProperty("Authorization", + "Bearer " + agentManager.getAgentConfigs().getAuthToken()); + httpConnection.setRequestProperty("Content-Type", AgentConstants.APPLICATION_JSON); httpConnection.setDoOutput(true); - DataOutputStream dataOutPutWriter = new DataOutputStream( - httpConnection.getOutputStream()); + DataOutputStream dataOutPutWriter = new DataOutputStream(httpConnection.getOutputStream()); dataOutPutWriter.writeBytes(pushDataPayload); dataOutPutWriter.flush(); dataOutPutWriter.close(); @@ -225,39 +223,34 @@ public class FireAlarmHTTPCommunicator extends HTTPTransportHandler { } catch (IOException exception) { String errorMsg = "An IO error occurred whilst trying to get the response code from: " + - pushDataEndPointURL + " for a " + AgentConstants.HTTP_POST + - " " + "method."; + pushDataEndPointURL + " for a " + AgentConstants.HTTP_POST + " method."; log.error(AgentConstants.LOG_APPENDER + errorMsg); } catch (TransportHandlerException exception) { log.error(AgentConstants.LOG_APPENDER + - "Error encountered whilst trying to create HTTP-Connection " + - "to IoT-Server EP at: " + + "Error encountered whilst trying to create HTTP-Connection to IoT-Server EP at: " + pushDataEndPointURL); } if (responseCode == HttpStatus.CONFLICT_409 || responseCode == HttpStatus.PRECONDITION_FAILED_412) { log.warn(AgentConstants.LOG_APPENDER + - "DeviceIP is being Re-Registered due to Push-Data failure " + - "with response code: " + + "DeviceIP is being Re-Registered due to Push-Data failure with response code: " + responseCode); registerThisDevice(); } else if (responseCode != HttpStatus.NO_CONTENT_204) { if (log.isDebugEnabled()) { log.error(AgentConstants.LOG_APPENDER + "Status Code: " + responseCode + - " encountered whilst trying to Push-Device-Data to IoT " + - "Server at: " + + " encountered whilst trying to Push-Device-Data to IoT Server at: " + agentManager.getPushDataAPIEP()); } agentManager.updateAgentStatus(AgentConstants.SERVER_NOT_RESPONDING); } if (log.isDebugEnabled()) { - log.debug(AgentConstants.LOG_APPENDER + "Push-Data call with payload - " + - pushDataPayload + ", to IoT Server returned status " + - responseCode); + log.debug(AgentConstants.LOG_APPENDER + "Push-Data call with payload - " + pushDataPayload + + ", to IoT Server returned status " + responseCode); } } @@ -272,16 +265,14 @@ public class FireAlarmHTTPCommunicator extends HTTPTransportHandler { closeConnection(); } catch (Exception e) { if (log.isDebugEnabled()) { - log.warn(AgentConstants.LOG_APPENDER + - "Unable to 'STOP' HTTP server at port: " + port); + log.warn(AgentConstants.LOG_APPENDER + "Unable to 'STOP' HTTP server at port: " + port); } try { Thread.sleep(timeoutInterval); } catch (InterruptedException e1) { - log.error(AgentConstants.LOG_APPENDER + - "HTTP-Termination: Thread Sleep Interrupt " + - "Exception"); + log.error( + AgentConstants.LOG_APPENDER + "HTTP-Termination: Thread Sleep Interrupt Exception"); } } } @@ -398,8 +389,7 @@ public class FireAlarmHTTPCommunicator extends HTTPTransportHandler { } catch (TransportHandlerException e) { String errorMsg = "Protocol specific error occurred when trying to fetch an HTTPConnection to:" + - " " + - registerEndpointURLString; + " " + registerEndpointURLString; log.error(AgentConstants.LOG_APPENDER + errorMsg); throw new AgentCoreOperationException(); } @@ -419,8 +409,7 @@ public class FireAlarmHTTPCommunicator extends HTTPTransportHandler { } catch (IOException exception) { 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); throw new AgentCoreOperationException(errorMsg, exception); } @@ -436,7 +425,7 @@ public class FireAlarmHTTPCommunicator extends HTTPTransportHandler { /*------------------------------------------------------------------------------------------*/ /* Utility methods relevant to creating and sending HTTP requests to the Iot-Server */ - /*------------------------------------------------------------------------------------------*/ + /*------------------------------------------------------------------------------------------*/ /** * This method is used to get the IP of the device in which the agent is run on. diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/communication/mqtt/FireAlarmMQTTCommunicator.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/communication/mqtt/FireAlarmMQTTCommunicator.java index 665319d75..8db409b7e 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/communication/mqtt/FireAlarmMQTTCommunicator.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/communication/mqtt/FireAlarmMQTTCommunicator.java @@ -35,7 +35,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; 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 { private static final Log log = LogFactory.getLog(FireAlarmMQTTCommunicator.class); diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConfiguration.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConfiguration.java index 64b52b8b7..04939edbb 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConfiguration.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConfiguration.java @@ -24,150 +24,159 @@ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core; * downloading the device agent from the IoT-Server. */ public class AgentConfiguration { - private String tenantDomain; - private String deviceOwner; - private String deviceId; - private String deviceName; - private String controllerContext; - private String scepContext; - private String HTTPS_ServerEndpoint; - private String HTTP_ServerEndpoint; - private String apimGatewayEndpoint; - private String mqttBrokerEndpoint; - private String xmppServerEndpoint; - private String authMethod; - private String authToken; - private String refreshToken; - private int dataPushInterval; - private String xmppServerName; - - public String getTenantDomain() { - return tenantDomain; - } - - public void setTenantDomain(String tenantDomain) { - this.tenantDomain = tenantDomain; - } - - public String getDeviceOwner() { - return deviceOwner; - } - - public void setDeviceOwner(String deviceOwner) { - this.deviceOwner = deviceOwner; - } - - public String getDeviceId() { - return deviceId; - } - - public void setDeviceId(String deviceId) { - this.deviceId = deviceId; - } - - public String getDeviceName() { - return deviceName; - } - - public void setDeviceName(String deviceName) { - this.deviceName = deviceName; - } - - public String getControllerContext() { - return controllerContext; - } - - public void setControllerContext(String controllerContext) { - this.controllerContext = controllerContext; - } - - public String getHTTPS_ServerEndpoint() { - return HTTPS_ServerEndpoint; - } - - public void setHTTPS_ServerEndpoint(String HTTPS_ServerEndpoint) { - this.HTTPS_ServerEndpoint = HTTPS_ServerEndpoint; - } - - public String getHTTP_ServerEndpoint() { - return HTTP_ServerEndpoint; - } - - public void setHTTP_ServerEndpoint(String HTTP_ServerEndpoint) { - this.HTTP_ServerEndpoint = HTTP_ServerEndpoint; - } - - public String getApimGatewayEndpoint() { - return apimGatewayEndpoint; - } - - public void setApimGatewayEndpoint(String apimGatewayEndpoint) { - this.apimGatewayEndpoint = apimGatewayEndpoint; - } - - public String getMqttBrokerEndpoint() { - return mqttBrokerEndpoint; - } - - public void setMqttBrokerEndpoint(String mqttBrokerEndpoint) { - this.mqttBrokerEndpoint = mqttBrokerEndpoint; - } - - public String getXmppServerEndpoint() { - return xmppServerEndpoint; - } - - public void setXmppServerEndpoint(String xmppServerEndpoint) { - this.xmppServerEndpoint = xmppServerEndpoint; - } - - public String getAuthMethod() { - return authMethod; - } - - public void setAuthMethod(String authMethod) { - this.authMethod = authMethod; - } - - public String getAuthToken() { - return authToken; - } - - public void setAuthToken(String authToken) { - this.authToken = authToken; - } - - public String getRefreshToken() { - return refreshToken; - } + private String tenantDomain; + private String deviceOwner; + private String deviceId; + private String deviceName; + private String controllerContext; + private String scepContext; + private String HTTPS_ServerEndpoint; + private String HTTP_ServerEndpoint; + private String apimGatewayEndpoint; + private String mqttBrokerEndpoint; + private String xmppServerEndpoint; + private String apiApplicationKey; + private String authMethod; + private String authToken; + private String refreshToken; + private int dataPushInterval; + private String xmppServerName; + + public String getTenantDomain() { + return tenantDomain; + } + + public void setTenantDomain(String tenantDomain) { + this.tenantDomain = tenantDomain; + } + + public String getDeviceOwner() { + return deviceOwner; + } + + public void setDeviceOwner(String deviceOwner) { + this.deviceOwner = deviceOwner; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getControllerContext() { + return controllerContext; + } + + public void setControllerContext(String controllerContext) { + this.controllerContext = controllerContext; + } + + public String getHTTPS_ServerEndpoint() { + return HTTPS_ServerEndpoint; + } + + public void setHTTPS_ServerEndpoint(String HTTPS_ServerEndpoint) { + this.HTTPS_ServerEndpoint = HTTPS_ServerEndpoint; + } + + public String getHTTP_ServerEndpoint() { + return HTTP_ServerEndpoint; + } + + public void setHTTP_ServerEndpoint(String HTTP_ServerEndpoint) { + this.HTTP_ServerEndpoint = HTTP_ServerEndpoint; + } + + public String getApimGatewayEndpoint() { + return apimGatewayEndpoint; + } + + public void setApimGatewayEndpoint(String apimGatewayEndpoint) { + this.apimGatewayEndpoint = apimGatewayEndpoint; + } + + public String getMqttBrokerEndpoint() { + return mqttBrokerEndpoint; + } + + public void setMqttBrokerEndpoint(String mqttBrokerEndpoint) { + this.mqttBrokerEndpoint = mqttBrokerEndpoint; + } + + public String getXmppServerEndpoint() { + return xmppServerEndpoint; + } + + public void setXmppServerEndpoint(String xmppServerEndpoint) { + this.xmppServerEndpoint = xmppServerEndpoint; + } + + public String getApiApplicationKey() { + return apiApplicationKey; + } + + public void setApiApplicationKey(String apiApplicationKey) { + this.apiApplicationKey = apiApplicationKey; + } + + public String getAuthMethod() { + return authMethod; + } + + public void setAuthMethod(String authMethod) { + this.authMethod = authMethod; + } + + public String getAuthToken() { + return authToken; + } - public void setRefreshToken(String refreshToken) { - this.refreshToken = refreshToken; - } + public void setAuthToken(String authToken) { + this.authToken = authToken; + } - public int getDataPushInterval() { - return dataPushInterval; - } + public String getRefreshToken() { + return refreshToken; + } - public void setDataPushInterval(int dataPushInterval) { - this.dataPushInterval = dataPushInterval; - } + public void setRefreshToken(String refreshToken) { + this.refreshToken = refreshToken; + } - public String getScepContext() { - return scepContext; - } + public int getDataPushInterval() { + return dataPushInterval; + } - public void setScepContext(String scepContext) { - this.scepContext = scepContext; - } + public void setDataPushInterval(int dataPushInterval) { + this.dataPushInterval = dataPushInterval; + } - public String getXmppServerName() { - return xmppServerName; - } + public String getScepContext() { + return scepContext; + } - public void setXmppServerName(String xmppServerName) { - this.xmppServerName = xmppServerName; - } + public void setScepContext(String scepContext) { + this.scepContext = scepContext; + } + + public String getXmppServerName() { + return xmppServerName; + } + + public void setXmppServerName(String xmppServerName) { + this.xmppServerName = xmppServerName; + } } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConstants.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConstants.java index 681f4f2e6..ddf63b21d 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConstants.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConstants.java @@ -19,94 +19,98 @@ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core; public class AgentConstants { - public static final String DEVICE_TYPE = "virtual_firealarm"; - public static final String LOG_APPENDER = "AGENT_LOG:: "; - public static final String PROPERTIES_FILE_PATH = ""; - public static final int DEFAULT_RETRY_THREAD_INTERVAL = 5000; // time in millis - /* --------------------------------------------------------------------------------------- - 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_REGISTER_API_EP = "/register"; - public static final String DEVICE_PUSH_TEMPERATURE_API_EP = "/temperature"; - public static final String PUSH_DATA_PAYLOAD = - "{\"owner\":\"%s\",\"deviceId\":\"%s\",\"reply\":\"%s\",\"value\":\"%s\"}"; + public static final String DEVICE_TYPE = "virtual_firealarm"; + public static final String LOG_APPENDER = "AGENT_LOG:: "; + public static final String PROPERTIES_FILE_PATH = ""; + public static final int DEFAULT_RETRY_THREAD_INTERVAL = 5000; // time in millis + public static final String TOKEN_AUTHENTICATION_METHOD = "token"; + /* --------------------------------------------------------------------------------------- + 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_REGISTER_API_EP = "/register"; + public static final String DEVICE_PUSH_TEMPERATURE_API_EP = "/temperature"; + public static final String PUSH_DATA_PAYLOAD = + "{\"owner\":\"%s\",\"deviceId\":\"%s\",\"reply\":\"%s\",\"value\":\"%s\"}"; - public static final String PUSH_SIMULATION_DATA_PAYLOAD = - "{\"owner\":\"%s\",\"deviceId\":\"%s\",\"reply\":\"%s\",\"value\":\"%s\",\"isSimulated\":\"%s\",\"duration\":\"%s\",\"frequency\":\"%s\"}"; + public static final String PUSH_SIMULATION_DATA_PAYLOAD = + "{\"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_ANALYTICS_PAGE_URL = "/devicemgt/device/virtual_firealarm/analytics?deviceId=%s&deviceName=%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_ANALYTICS_PAGE_URL = + "/devicemgt/device/virtual_firealarm/analytics?deviceId=%s&deviceName=%s"; - /* --------------------------------------------------------------------------------------- - HTTP Connection specific information for communicating with IoT-Server - --------------------------------------------------------------------------------------- */ - public static final String HTTP_POST = "POST"; - public static final String HTTP_GET = "GET"; - public static final String APPLICATION_JSON_TYPE = "application/json"; - public static final String REGISTERED = "Registered"; - public static final String NOT_REGISTERED = "Not-Registered"; - public static final String REGISTRATION_FAILED = "Registration Failed"; - public static final String RETRYING_TO_REGISTER = "Registration Failed. Re-trying.."; - public static final String SERVER_NOT_RESPONDING = "Server not responding.."; + /* --------------------------------------------------------------------------------------- + HTTP Connection specific information for communicating with IoT-Server + --------------------------------------------------------------------------------------- */ + public static final String HTTP_POST = "POST"; + public static final String HTTP_GET = "GET"; + 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 = "x-www-form-urlencoded"; + public static final String REGISTERED = "Registered"; + public static final String NOT_REGISTERED = "Not-Registered"; + public static final String REGISTRATION_FAILED = "Registration Failed"; + public static final String RETRYING_TO_REGISTER = "Registration Failed. Re-trying.."; + public static final String SERVER_NOT_RESPONDING = "Server not responding.."; - /* --------------------------------------------------------------------------------------- - MQTT Connection specific information - --------------------------------------------------------------------------------------- */ - public static final int DEFAULT_MQTT_RECONNECTION_INTERVAL = 2; // time in seconds - public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0; - public static final String MQTT_SUBSCRIBE_TOPIC = "%s/" + DEVICE_TYPE + "/%s"; - 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 - --------------------------------------------------------------------------------------- */ - public static final String AGENT_PROPERTIES_FILE_NAME = "deviceConfig.properties"; - public static final String TENANT_DOMAIN = "tenantDomain"; - public static final String DEVICE_OWNER_PROPERTY = "owner"; - public static final String DEVICE_ID_PROPERTY = "deviceId"; - public static final String DEVICE_NAME_PROPERTY = "device-name"; - public static final String DEVICE_CONTROLLER_CONTEXT_PROPERTY = "controller-context"; - public static final String DEVICE_SCEP_CONTEXT_PROPERTY = "scep-context"; - public static final String SERVER_HTTPS_EP_PROPERTY = "https-ep"; - public static final String SERVER_HTTP_EP_PROPERTY = "http-ep"; - public static final String APIM_GATEWAY_EP_PROPERTY = "apim-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_NAME_PROPERTY = "xmpp-server-name"; - public static final String AUTH_METHOD_PROPERTY = "auth-method"; - public static final String AUTH_TOKEN_PROPERTY = "auth-token"; - public static final String REFRESH_TOKEN_PROPERTY = "refresh-token"; - public static final String NETWORK_INTERFACE_PROPERTY = "network-interface"; - public static final String PUSH_INTERVAL_PROPERTY = "push-interval"; - /* --------------------------------------------------------------------------------------- - Default values for the Device/Agent specific configurations listed above - --------------------------------------------------------------------------------------- */ - public static final String DEFAULT_NETWORK_INTERFACE = "en0"; - public static final int DEFAULT_DATA_PUBLISH_INTERVAL = 15; // seconds - public static final String DEFAULT_PROTOCOL = "MQTT"; - /* --------------------------------------------------------------------------------------- - Control Signal specific constants to match the request context - --------------------------------------------------------------------------------------- */ - public static final String BULB_CONTROL = "BULB"; - public static final String TEMPERATURE_CONTROL = "TEMPERATURE"; - public static final String POLICY_SIGNAL = "POLICY"; - public static final String HUMIDITY_CONTROL = "HUMIDITY"; - public static final String CONTROL_ON = "ON"; - public static final String CONTROL_OFF = "OFF"; - public static final String AUDIO_FILE_NAME = "fireAlarmSound.mid"; - /* --------------------------------------------------------------------------------------- - Communication protocol specific Strings - --------------------------------------------------------------------------------------- */ - public static final String TCP_PREFIX = "tcp://"; - public static final String HTTP_PREFIX = "http://"; - public static final String HTTPS_PREFIX = "https://"; - public static final String HTTP_PROTOCOL = "HTTP"; - public static final String MQTT_PROTOCOL = "MQTT"; - public static final String XMPP_PROTOCOL = "XMPP"; + /* --------------------------------------------------------------------------------------- + MQTT Connection specific information + --------------------------------------------------------------------------------------- */ + public static final int DEFAULT_MQTT_RECONNECTION_INTERVAL = 2; // time in seconds + public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0; + public static final String MQTT_SUBSCRIBE_TOPIC = "%s/" + DEVICE_TYPE + "/%s"; + public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/publisher"; + + /* --------------------------------------------------------------------------------------- + Device/Agent specific properties to be read from the 'deviceConfig.properties' file + --------------------------------------------------------------------------------------- */ + public static final String AGENT_PROPERTIES_FILE_NAME = "deviceConfig.properties"; + public static final String TENANT_DOMAIN = "tenantDomain"; + public static final String DEVICE_OWNER_PROPERTY = "owner"; + public static final String DEVICE_ID_PROPERTY = "deviceId"; + public static final String DEVICE_NAME_PROPERTY = "device-name"; + public static final String DEVICE_CONTROLLER_CONTEXT_PROPERTY = "controller-context"; + public static final String DEVICE_SCEP_CONTEXT_PROPERTY = "scep-context"; + public static final String SERVER_HTTPS_EP_PROPERTY = "https-ep"; + public static final String SERVER_HTTP_EP_PROPERTY = "http-ep"; + public static final String APIM_GATEWAY_EP_PROPERTY = "apim-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_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_TOKEN_PROPERTY = "auth-token"; + public static final String REFRESH_TOKEN_PROPERTY = "refresh-token"; + public static final String NETWORK_INTERFACE_PROPERTY = "network-interface"; + public static final String PUSH_INTERVAL_PROPERTY = "push-interval"; + /* --------------------------------------------------------------------------------------- + Default values for the Device/Agent specific configurations listed above + --------------------------------------------------------------------------------------- */ + public static final String DEFAULT_NETWORK_INTERFACE = "en0"; + public static final int DEFAULT_DATA_PUBLISH_INTERVAL = 15; // seconds + public static final String DEFAULT_PROTOCOL = "MQTT"; + /* --------------------------------------------------------------------------------------- + Control Signal specific constants to match the request context + --------------------------------------------------------------------------------------- */ + public static final String BULB_CONTROL = "BULB"; + public static final String TEMPERATURE_CONTROL = "TEMPERATURE"; + public static final String POLICY_SIGNAL = "POLICY"; + public static final String HUMIDITY_CONTROL = "HUMIDITY"; + public static final String CONTROL_ON = "ON"; + public static final String CONTROL_OFF = "OFF"; + public static final String AUDIO_FILE_NAME = "fireAlarmSound.mid"; + /* --------------------------------------------------------------------------------------- + Communication protocol specific Strings + --------------------------------------------------------------------------------------- */ + public static final String TCP_PREFIX = "tcp://"; + public static final String HTTP_PREFIX = "http://"; + public static final String HTTPS_PREFIX = "https://"; + public static final String HTTP_PROTOCOL = "HTTP"; + public static final String MQTT_PROTOCOL = "MQTT"; + public static final String XMPP_PROTOCOL = "XMPP"; } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentManager.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentManager.java index 4dca0913e..7ae5b0119 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentManager.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentManager.java @@ -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.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.exception.AgentCoreOperationException; 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.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 java.util.ArrayList; @@ -217,12 +217,16 @@ public class AgentManager { /*------------------------------------------------------------------------------------------*/ /* Getter and Setter Methods for the private variables */ - /*------------------------------------------------------------------------------------------*/ + /*------------------------------------------------------------------------------------------*/ public void setRootPath(String rootPath) { this.rootPath = rootPath; } + public String getRootPath() { + return rootPath; + } + public void setDeviceReady(boolean deviceReady) { this.deviceReady = deviceReady; } @@ -324,6 +328,7 @@ public class AgentManager { /** * Get temperature reading from device + * * @return Temperature */ public int getTemperature() { @@ -332,9 +337,10 @@ public class AgentManager { /** * Get humidity reading from device + * * @return Humidity */ - public int getHumidity(){ + public int getHumidity() { return VirtualHardwareManager.getInstance().getHumidity(); } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentUtilOperations.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentUtilOperations.java index 656ce8490..45003b55f 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentUtilOperations.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentUtilOperations.java @@ -26,12 +26,18 @@ import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.enrollment.Enrollme 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.TransportHandlerException; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportUtils; -import java.io.File; +import java.io.BufferedReader; +import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.ProtocolException; import java.net.URL; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; @@ -67,18 +73,19 @@ public class AgentUtilOperations { Properties properties = new Properties(); InputStream propertiesInputStream = null; String propertiesFileName = AgentConstants.AGENT_PROPERTIES_FILE_NAME; + String rootPath = ""; try { ClassLoader loader = AgentUtilOperations.class.getClassLoader(); URL path = loader.getResource(propertiesFileName); System.out.println(path); - String root = path.getPath().replace("wso2-firealarm-virtual-agent.jar!/deviceConfig.properties", "") - .replace("jar:", "").replace("file:", ""); + rootPath = path.getPath().replace("wso2-firealarm-virtual-agent.jar!/deviceConfig.properties", "") + .replace("jar:", "").replace("file:", ""); - root = URLDecoder.decode(root, StandardCharsets.UTF_8.toString()); - agentManager.setRootPath(root); + rootPath = URLDecoder.decode(rootPath, StandardCharsets.UTF_8.toString()); + agentManager.setRootPath(rootPath); - String deviceConfigFilePath = root + AgentConstants.AGENT_PROPERTIES_FILE_NAME; + String deviceConfigFilePath = rootPath + AgentConstants.AGENT_PROPERTIES_FILE_NAME; propertiesInputStream = new FileInputStream(deviceConfigFilePath); //load a properties file from class path, inside static method @@ -108,6 +115,8 @@ public class AgentUtilOperations { AgentConstants.XMPP_SERVER_EP_PROPERTY)); iotServerConfigs.setXmppServerName(properties.getProperty( AgentConstants.XMPP_SERVER_NAME_PROPERTY)); + iotServerConfigs.setApiApplicationKey(properties.getProperty( + AgentConstants.API_APPLICATION_KEY)); iotServerConfigs.setAuthMethod(properties.getProperty( AgentConstants.AUTH_METHOD_PROPERTY)); iotServerConfigs.setAuthToken(properties.getProperty( @@ -138,6 +147,8 @@ public class AgentUtilOperations { iotServerConfigs.getXmppServerEndpoint()); log.info(AgentConstants.LOG_APPENDER + "Authentication Method: " + iotServerConfigs.getAuthMethod()); + log.info(AgentConstants.LOG_APPENDER + "Base64Encoded API Application Key: " + + iotServerConfigs.getApiApplicationKey()); log.info(AgentConstants.LOG_APPENDER + "Authentication Token: " + iotServerConfigs.getAuthToken()); log.info(AgentConstants.LOG_APPENDER + "Refresh Token: " + @@ -148,13 +159,13 @@ public class AgentUtilOperations { iotServerConfigs.getXmppServerName()); } 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); throw new AgentCoreOperationException(errorMsg); } catch (IOException ex) { String errorMsg = "Error occurred whilst trying to fetch [" + propertiesFileName + "] from: " + - AgentConstants.PROPERTIES_FILE_PATH; + AgentConstants.PROPERTIES_FILE_PATH; log.error(AgentConstants.LOG_APPENDER + errorMsg); throw new AgentCoreOperationException(errorMsg); } finally { @@ -174,10 +185,6 @@ public class AgentUtilOperations { /** * This method constructs the URLs for each of the API Endpoints called by the device agent * 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() { AgentManager agentManager = AgentManager.getInstance(); @@ -265,6 +272,155 @@ public class AgentUtilOperations { 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 boolean refreshOAuthToken() throws AgentCoreOperationException { + + AgentManager agentManager = AgentManager.getInstance(); + String tokenEndpoint = agentManager.getAgentConfigs().getApimGatewayEndpoint() + "/token"; + HttpURLConnection httpConnection = null; + BufferedReader connectionBuffer = null; + String requestPayload; + String dataFromBuffer; + StringBuilder responseMessage = new StringBuilder(); + boolean refreshStatus = false; + + try { + httpConnection = TransportUtils.getHttpConnection(tokenEndpoint); + httpConnection.setRequestMethod(AgentConstants.HTTP_POST); + httpConnection.setRequestProperty(AgentConstants.AUTHORIZATION_HEADER, + "Bearer " + agentManager.getAgentConfigs().getApiApplicationKey()); + httpConnection.setRequestProperty(AgentConstants.CONTENT_TYPE_HEADER, AgentConstants.X_WWW_FORM_URLENCODED); + httpConnection.setDoOutput(true); + + 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; + + 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."); + + 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."); + + refreshStatus = updateExistingTokens(responseMessage.toString()); + + } 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(); + } + } + return refreshStatus; + } + + + private static boolean updateExistingTokens(String responseFromTokenEP) { + 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) { + log.error( + AgentConstants.LOG_APPENDER + "Neither Access-Token nor Refresh-Token was found in the response [" + + responseFromTokenEP + "]."); + return false; + } + + AgentManager.getInstance().getAgentConfigs().setAuthToken(newAccessToken); + AgentManager.getInstance().getAgentConfigs().setRefreshToken(newRefreshToken); + String deviceConfigFilePath = + AgentManager.getInstance().getRootPath() + AgentConstants.AGENT_PROPERTIES_FILE_NAME; + + Properties deviceProperties = new Properties(); + FileOutputStream fileOutputStream = null; + + try { + fileOutputStream = new FileOutputStream(deviceConfigFilePath); + deviceProperties.setProperty(AgentConstants.AUTH_TOKEN_PROPERTY, newAccessToken); + deviceProperties.setProperty(AgentConstants.REFRESH_TOKEN_PROPERTY, newRefreshToken); + deviceProperties.store(fileOutputStream, null); + + } catch (FileNotFoundException ex) { + String errorMsg = + "[" + AgentConstants.AGENT_PROPERTIES_FILE_NAME + "] file not found at: " + deviceConfigFilePath; + log.error(AgentConstants.LOG_APPENDER + errorMsg); + return false; + + } catch (IOException ex) { + String errorMsg = "Error occurred whilst trying to write to [" + AgentConstants.AGENT_PROPERTIES_FILE_NAME + + "] at: " + deviceConfigFilePath; + log.error(AgentConstants.LOG_APPENDER + errorMsg); + return false; + } finally { + if (fileOutputStream != null) { + try { + fileOutputStream.close(); + } catch (IOException e) { + log.error(AgentConstants.LOG_APPENDER + + "Error occurred whilst trying to close InputStream resource used to read the '" + + AgentConstants.AGENT_PROPERTIES_FILE_NAME + "' file"); + } + } + } + return true; + } + + + private class APIManagerTokenUtils { + 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"; + } } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/resources/deviceConfig.properties b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/resources/deviceConfig.properties index 4eba166c1..ba7e9922b 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/resources/deviceConfig.properties +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/resources/deviceConfig.properties @@ -1,4 +1,4 @@ -# +ad# # Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmServiceImpl.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmServiceImpl.java index 324be52da..7080151d2 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmServiceImpl.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmServiceImpl.java @@ -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.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 java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; 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 { @@ -136,7 +150,8 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService { List deviceIdentifiers = new ArrayList<>(); 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; } return Response.ok().build(); @@ -319,14 +334,16 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService { scopes); String accessToken = accessTokenInfo.getAccessToken(); String refreshToken = accessTokenInfo.getRefreshToken(); - //adding registering data - XmppAccount newXmppAccount = new XmppAccount(); - newXmppAccount.setAccountName(deviceId); - newXmppAccount.setUsername(deviceId); - newXmppAccount.setPassword(accessToken); - newXmppAccount.setEmail(deviceId + "@" + APIUtil.getTenantDomainOftheUser()); + boolean status; if (XmppConfig.getInstance().isEnabled()) { + + XmppAccount newXmppAccount = new XmppAccount(); + newXmppAccount.setAccountName(deviceId); + newXmppAccount.setUsername(deviceId); + newXmppAccount.setPassword(accessToken); + newXmppAccount.setEmail(deviceId + "@" + APIUtil.getTenantDomainOftheUser()); + status = XmppServerClient.createAccount(newXmppAccount); if (!status) { 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); } } + status = register(deviceId, deviceName); if (!status) { String msg = "Error occurred while registering the device with " + "id: " + deviceId + " owner:" + owner; throw new DeviceManagementException(msg); } + ZipUtil ziputil = new ZipUtil(); - return ziputil.createZipFile(owner, APIUtil.getTenantDomainOftheUser(), sketchType, deviceId, - deviceName, accessToken, refreshToken); + return ziputil.createZipFile(owner, sketchType, deviceId, deviceName, apiApplicationKey.toString(), + accessToken, refreshToken); } private static String shortUUID() { @@ -350,5 +369,4 @@ public class VirtualFireAlarmServiceImpl implements VirtualFireAlarmService { long l = ByteBuffer.wrap(uuid.toString().getBytes(StandardCharsets.UTF_8)).getLong(); return Long.toString(l, Character.MAX_RADIX); } - } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/VirtualFireAlarmUtilConstants.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/VirtualFireAlarmUtilConstants.java new file mode 100644 index 000000000..2f1fe8030 --- /dev/null +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/VirtualFireAlarmUtilConstants.java @@ -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"; +} diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java index 4d7fed54c..07d055e16 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java @@ -18,6 +18,11 @@ 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.iot.util.Utils; import org.wso2.carbon.device.mgt.iot.util.ZipArchive; @@ -35,6 +40,7 @@ import java.util.Map; */ public class ZipUtil { + private static final Log log = LogFactory.getLog(ZipUtil.class); private static final String HTTPS_PORT_PROPERTY = "httpsPort"; 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 HTTP_PROTOCOL_APPENDER = "http://"; - public ZipArchive createZipFile(String owner, String tenantDomain, String deviceType, - String deviceId, String deviceName, String token, - String refreshToken) throws DeviceManagementException { + public ZipArchive createZipFile(String owner, String deviceType, String deviceId, String deviceName, + String apiApplicationKey, String token, String refreshToken) + throws DeviceManagementException { 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; String templateSketchPath = sketchFolder + File.separator + deviceType; String iotServerIP; @@ -63,24 +70,29 @@ public class ZipUtil { if (mqttEndpoint.contains(LOCALHOST)) { mqttEndpoint = mqttEndpoint.replace(LOCALHOST, iotServerIP); } + String xmppEndpoint = XmppConfig.getInstance().getXmppServerIP() + ":" + XmppConfig.getInstance().getXmppServerPort(); if (xmppEndpoint.contains(LOCALHOST)) { xmppEndpoint = xmppEndpoint.replace(LOCALHOST, iotServerIP); } + + String base64EncodedApplicationKey = getBase64EncodedAPIAppKey(apiApplicationKey); + Map contextParams = new HashMap<>(); - contextParams.put("TENANT_DOMAIN", APIUtil.getTenantDomainOftheUser()); - contextParams.put("DEVICE_OWNER", owner); - contextParams.put("DEVICE_ID", deviceId); - contextParams.put("DEVICE_NAME", deviceName); - contextParams.put("HTTPS_EP", httpsServerEP); - contextParams.put("HTTP_EP", httpServerEP); - contextParams.put("APIM_EP", apimEndpoint); - contextParams.put("MQTT_EP", mqttEndpoint); - contextParams.put("XMPP_EP", "XMPP:" + xmppEndpoint); - contextParams.put("DEVICE_TOKEN", token); - contextParams.put("DEVICE_REFRESH_TOKEN", refreshToken); - contextParams.put("SERVER_NAME", XmppConfig.getInstance().getXmppServerName()); + contextParams.put(VirtualFireAlarmUtilConstants.TENANT_DOMAIN, APIUtil.getTenantDomainOftheUser()); + contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_OWNER, owner); + contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_ID, deviceId); + contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_NAME, deviceName); + contextParams.put(VirtualFireAlarmUtilConstants.HTTPS_EP, httpsServerEP); + contextParams.put(VirtualFireAlarmUtilConstants.HTTP_EP, httpServerEP); + contextParams.put(VirtualFireAlarmUtilConstants.APIM_EP, apimEndpoint); + contextParams.put(VirtualFireAlarmUtilConstants.MQTT_EP, mqttEndpoint); + contextParams.put(VirtualFireAlarmUtilConstants.XMPP_EP, "XMPP:" + xmppEndpoint); + contextParams.put(VirtualFireAlarmUtilConstants.API_APPLICATION_KEY, base64EncodedApplicationKey); + contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_TOKEN, token); + contextParams.put(VirtualFireAlarmUtilConstants.DEVICE_REFRESH_TOKEN, refreshToken); + contextParams.put(VirtualFireAlarmUtilConstants.SERVER_NAME, XmppConfig.getInstance().getXmppServerName()); ZipArchive zipFile; zipFile = Utils.getSketchArchive(archivesPath, templateSketchPath, contextParams, deviceName); return zipFile; @@ -88,4 +100,13 @@ public class ZipUtil { 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()); + } } diff --git a/features/iot-plugins-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/advanced_agent/deviceConfig.properties b/features/iot-plugins-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/advanced_agent/deviceConfig.properties index 47a3a73a6..1ee0aa15f 100644 --- a/features/iot-plugins-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/advanced_agent/deviceConfig.properties +++ b/features/iot-plugins-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/advanced_agent/deviceConfig.properties @@ -28,6 +28,7 @@ apim-ep=${APIM_EP} mqtt-ep=${MQTT_EP} xmpp-ep=${XMPP_EP} auth-method=token +application-key=${API_APPLICATION_KEY} auth-token=${DEVICE_TOKEN} refresh-token=${DEVICE_REFRESH_TOKEN} push-interval=15 From a117ae37c71f61d0161aa66a2bd9ab3aa17e7cc4 Mon Sep 17 00:00:00 2001 From: Shabirmean Date: Thu, 2 Jun 2016 14:19:48 +0530 Subject: [PATCH 2/4] Modifications to the Token Refresh Flow & the Enrolment flow in the VFAlarm --- .../pom.xml | 7 + .../mqtt/FireAlarmMQTTCommunicator.java | 39 ++- .../agent/core/AgentConstants.java | 17 +- .../agent/core/AgentManager.java | 9 +- .../agent/core/AgentUtilOperations.java | 284 +++++++++--------- .../agent/enrollment/EnrollmentManager.java | 127 +++++++- .../agent/transport/TransportUtils.java | 10 +- .../transport/mqtt/MQTTTransportHandler.java | 23 +- .../service/impl/util/ZipUtil.java | 2 +- .../resources/agent/deviceConfig.properties | 1 + .../resources/agent/virtual_firealarm.jks | Bin 0 -> 635 bytes 11 files changed, 349 insertions(+), 170 deletions(-) create mode 100644 features/iot-plugins-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/agent/virtual_firealarm.jks diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/pom.xml b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/pom.xml index 4ec107071..f3287ab2d 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/pom.xml +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/pom.xml @@ -175,6 +175,13 @@ json + + commons-configuration + commons-configuration + 1.10 + + + diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/communication/mqtt/FireAlarmMQTTCommunicator.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/communication/mqtt/FireAlarmMQTTCommunicator.java index 8db409b7e..5b24783e7 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/communication/mqtt/FireAlarmMQTTCommunicator.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/communication/mqtt/FireAlarmMQTTCommunicator.java @@ -22,6 +22,7 @@ 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.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.AgentManager; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentUtilOperations; @@ -42,6 +43,7 @@ public class FireAlarmMQTTCommunicator extends MQTTTransportHandler { private ScheduledExecutorService service = Executors.newScheduledThreadPool(2); private ScheduledFuture dataPushServiceHandler; + private static final String DEFAULT_PASSWORD = ""; public FireAlarmMQTTCommunicator(String deviceOwner, String deviceType, String mqttBrokerEndPoint, String subscribeTopic) { @@ -68,18 +70,23 @@ public class FireAlarmMQTTCommunicator extends MQTTTransportHandler { public void run() { while (!isConnected()) { try { - connectToQueue(); + connectToQueue(agentManager.getAgentConfigs().getAuthToken(), DEFAULT_PASSWORD); agentManager.updateAgentStatus("Connected to MQTT Queue"); } catch (TransportHandlerException e) { log.warn(AgentConstants.LOG_APPENDER + "Connection to MQTT Broker at: " + mqttBrokerEndPoint + " failed.\n Will retry in " + timeoutInterval + " milli-seconds."); - } - try{ - subscribeToQueue(); - agentManager.updateAgentStatus("Subscribed to MQTT Queue"); - publishDeviceData(); + if (e.getCause() != null && e.getCause() instanceof MqttSecurityException) { + refreshOAuthToken((MqttSecurityException) e.getCause()); + } + } + try { + if (isConnected()) { + subscribeToQueue(); + agentManager.updateAgentStatus("Subscribed to MQTT Queue"); + publishDeviceData(); + } } catch (TransportHandlerException e) { log.warn(AgentConstants.LOG_APPENDER + "Subscription to MQTT Broker at: " + mqttBrokerEndPoint + " failed"); @@ -100,6 +107,26 @@ public class FireAlarmMQTTCommunicator extends MQTTTransportHandler { 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 public void processIncomingMessage(MqttMessage message, String... messageParams) { diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConstants.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConstants.java index ddf63b21d..3c661c6d7 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConstants.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConstants.java @@ -27,7 +27,6 @@ public class AgentConstants { /* --------------------------------------------------------------------------------------- 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_REGISTER_API_EP = "/register"; public static final String DEVICE_PUSH_TEMPERATURE_API_EP = "/temperature"; @@ -38,7 +37,6 @@ public class AgentConstants { "{\"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_ANALYTICS_PAGE_URL = "/devicemgt/device/virtual_firealarm/analytics?deviceId=%s&deviceName=%s"; @@ -51,7 +49,7 @@ public class AgentConstants { 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 = "x-www-form-urlencoded"; + public static final String X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded"; public static final String REGISTERED = "Registered"; public static final String NOT_REGISTERED = "Not-Registered"; public static final String REGISTRATION_FAILED = "Registration Failed"; @@ -113,4 +111,17 @@ public class AgentConstants { public static final String HTTP_PROTOCOL = "HTTP"; public static final String MQTT_PROTOCOL = "MQTT"; 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_PUBLIC_KEY_ALIAS = "iotServer_key"; } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentManager.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentManager.java index 7ae5b0119..422ed85d0 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentManager.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentManager.java @@ -74,18 +74,19 @@ public class AgentManager { public void init() { agentCommunicator = new HashMap<>(); - // Read IoT-Server specific configurations from the 'deviceConfig.properties' file try { this.agentConfigs = AgentUtilOperations.readIoTServerConfigs(); } 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); System.exit(0); } // Initialise IoT-Server URL endpoints from the configuration read from file 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, agentConfigs.getDeviceId(), @@ -153,7 +154,9 @@ public class AgentManager { } try { - EnrollmentManager.getInstance().beginEnrollmentFlow(); + if (!EnrollmentManager.getInstance().isEnrolled()) { + EnrollmentManager.getInstance().beginEnrollmentFlow(); + } } catch (AgentCoreOperationException e) { log.error("Device Enrollment Failed:\n"); log.error(e); diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentUtilOperations.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentUtilOperations.java index 45003b55f..7f407f5ca 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentUtilOperations.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentUtilOperations.java @@ -19,8 +19,11 @@ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core; 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.LogFactory; +import org.eclipse.jetty.http.HttpStatus; import org.json.JSONObject; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.enrollment.EnrollmentManager; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.exception.AgentCoreOperationException; @@ -28,11 +31,13 @@ import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.Communica import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandlerException; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportUtils; +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.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -78,86 +83,91 @@ public class AgentUtilOperations { try { ClassLoader loader = AgentUtilOperations.class.getClassLoader(); URL path = loader.getResource(propertiesFileName); - System.out.println(path); - rootPath = path.getPath().replace("wso2-firealarm-virtual-agent.jar!/deviceConfig.properties", "") - .replace("jar:", "").replace("file:", ""); - - rootPath = URLDecoder.decode(rootPath, StandardCharsets.UTF_8.toString()); - agentManager.setRootPath(rootPath); - - String deviceConfigFilePath = rootPath + AgentConstants.AGENT_PROPERTIES_FILE_NAME; - propertiesInputStream = new FileInputStream(deviceConfigFilePath); - - //load a properties file from class path, inside static method - properties.load(propertiesInputStream); - - iotServerConfigs.setTenantDomain(properties.getProperty( - AgentConstants.TENANT_DOMAIN)); - iotServerConfigs.setDeviceOwner(properties.getProperty( - AgentConstants.DEVICE_OWNER_PROPERTY)); - iotServerConfigs.setDeviceId(properties.getProperty( - AgentConstants.DEVICE_ID_PROPERTY)); - iotServerConfigs.setDeviceName(properties.getProperty( - AgentConstants.DEVICE_NAME_PROPERTY)); - iotServerConfigs.setControllerContext(properties.getProperty( - AgentConstants.DEVICE_CONTROLLER_CONTEXT_PROPERTY)); - iotServerConfigs.setScepContext(properties.getProperty( - AgentConstants.DEVICE_SCEP_CONTEXT_PROPERTY)); - iotServerConfigs.setHTTPS_ServerEndpoint(properties.getProperty( - AgentConstants.SERVER_HTTPS_EP_PROPERTY)); - iotServerConfigs.setHTTP_ServerEndpoint(properties.getProperty( - AgentConstants.SERVER_HTTP_EP_PROPERTY)); - iotServerConfigs.setApimGatewayEndpoint(properties.getProperty( - AgentConstants.APIM_GATEWAY_EP_PROPERTY)); - iotServerConfigs.setMqttBrokerEndpoint(properties.getProperty( - AgentConstants.MQTT_BROKER_EP_PROPERTY)); - iotServerConfigs.setXmppServerEndpoint(properties.getProperty( - AgentConstants.XMPP_SERVER_EP_PROPERTY)); - iotServerConfigs.setXmppServerName(properties.getProperty( - AgentConstants.XMPP_SERVER_NAME_PROPERTY)); - iotServerConfigs.setApiApplicationKey(properties.getProperty( - AgentConstants.API_APPLICATION_KEY)); - iotServerConfigs.setAuthMethod(properties.getProperty( - AgentConstants.AUTH_METHOD_PROPERTY)); - iotServerConfigs.setAuthToken(properties.getProperty( - AgentConstants.AUTH_TOKEN_PROPERTY)); - iotServerConfigs.setRefreshToken(properties.getProperty( - AgentConstants.REFRESH_TOKEN_PROPERTY)); - iotServerConfigs.setDataPushInterval(Integer.parseInt(properties.getProperty( - AgentConstants.PUSH_INTERVAL_PROPERTY))); - - log.info(AgentConstants.LOG_APPENDER + "Tenant Domain: " + - iotServerConfigs.getTenantDomain()); - log.info(AgentConstants.LOG_APPENDER + "Device Owner: " + - iotServerConfigs.getDeviceOwner()); - log.info(AgentConstants.LOG_APPENDER + "Device ID: " + iotServerConfigs.getDeviceId()); - log.info(AgentConstants.LOG_APPENDER + "Device Name: " + - iotServerConfigs.getDeviceName()); - log.info(AgentConstants.LOG_APPENDER + "Device Controller Context: " + - iotServerConfigs.getControllerContext()); - log.info(AgentConstants.LOG_APPENDER + "IoT Server HTTPS EndPoint: " + - iotServerConfigs.getHTTPS_ServerEndpoint()); - log.info(AgentConstants.LOG_APPENDER + "IoT Server HTTP EndPoint: " + - iotServerConfigs.getHTTP_ServerEndpoint()); - log.info(AgentConstants.LOG_APPENDER + "API-Manager Gateway EndPoint: " + - iotServerConfigs.getApimGatewayEndpoint()); - log.info(AgentConstants.LOG_APPENDER + "MQTT Broker EndPoint: " + - iotServerConfigs.getMqttBrokerEndpoint()); - log.info(AgentConstants.LOG_APPENDER + "XMPP Server EndPoint: " + - iotServerConfigs.getXmppServerEndpoint()); - log.info(AgentConstants.LOG_APPENDER + "Authentication Method: " + - iotServerConfigs.getAuthMethod()); - log.info(AgentConstants.LOG_APPENDER + "Base64Encoded API Application Key: " + - iotServerConfigs.getApiApplicationKey()); - log.info(AgentConstants.LOG_APPENDER + "Authentication Token: " + - iotServerConfigs.getAuthToken()); - log.info(AgentConstants.LOG_APPENDER + "Refresh Token: " + - iotServerConfigs.getRefreshToken()); - log.info(AgentConstants.LOG_APPENDER + "Data Push Interval: " + - iotServerConfigs.getDataPushInterval()); - log.info(AgentConstants.LOG_APPENDER + "XMPP Server Name: " + - iotServerConfigs.getXmppServerName()); + if (path != null) { + log.info(AgentConstants.LOG_APPENDER + path); + rootPath = path.getPath().replace("wso2-firealarm-virtual-agent.jar!/deviceConfig.properties", "") + .replace("jar:", "").replace("file:", ""); + + rootPath = URLDecoder.decode(rootPath, StandardCharsets.UTF_8.toString()); + agentManager.setRootPath(rootPath); + + String deviceConfigFilePath = rootPath + AgentConstants.AGENT_PROPERTIES_FILE_NAME; + propertiesInputStream = new FileInputStream(deviceConfigFilePath); + + //load a properties file from class path, inside static method + properties.load(propertiesInputStream); + + iotServerConfigs.setTenantDomain(properties.getProperty( + AgentConstants.TENANT_DOMAIN)); + iotServerConfigs.setDeviceOwner(properties.getProperty( + AgentConstants.DEVICE_OWNER_PROPERTY)); + iotServerConfigs.setDeviceId(properties.getProperty( + AgentConstants.DEVICE_ID_PROPERTY)); + iotServerConfigs.setDeviceName(properties.getProperty( + AgentConstants.DEVICE_NAME_PROPERTY)); + iotServerConfigs.setControllerContext(properties.getProperty( + AgentConstants.DEVICE_CONTROLLER_CONTEXT_PROPERTY)); + iotServerConfigs.setScepContext(properties.getProperty( + AgentConstants.DEVICE_SCEP_CONTEXT_PROPERTY)); + iotServerConfigs.setHTTPS_ServerEndpoint(properties.getProperty( + AgentConstants.SERVER_HTTPS_EP_PROPERTY)); + iotServerConfigs.setHTTP_ServerEndpoint(properties.getProperty( + AgentConstants.SERVER_HTTP_EP_PROPERTY)); + iotServerConfigs.setApimGatewayEndpoint(properties.getProperty( + AgentConstants.APIM_GATEWAY_EP_PROPERTY)); + iotServerConfigs.setMqttBrokerEndpoint(properties.getProperty( + AgentConstants.MQTT_BROKER_EP_PROPERTY)); + iotServerConfigs.setXmppServerEndpoint(properties.getProperty( + AgentConstants.XMPP_SERVER_EP_PROPERTY)); + iotServerConfigs.setXmppServerName(properties.getProperty( + AgentConstants.XMPP_SERVER_NAME_PROPERTY)); + iotServerConfigs.setApiApplicationKey(properties.getProperty( + AgentConstants.API_APPLICATION_KEY)); + iotServerConfigs.setAuthMethod(properties.getProperty( + AgentConstants.AUTH_METHOD_PROPERTY)); + iotServerConfigs.setAuthToken(properties.getProperty( + AgentConstants.AUTH_TOKEN_PROPERTY)); + iotServerConfigs.setRefreshToken(properties.getProperty( + AgentConstants.REFRESH_TOKEN_PROPERTY)); + iotServerConfigs.setDataPushInterval(Integer.parseInt(properties.getProperty( + AgentConstants.PUSH_INTERVAL_PROPERTY))); + + log.info(AgentConstants.LOG_APPENDER + "Tenant Domain: " + + iotServerConfigs.getTenantDomain()); + log.info(AgentConstants.LOG_APPENDER + "Device Owner: " + + iotServerConfigs.getDeviceOwner()); + log.info(AgentConstants.LOG_APPENDER + "Device ID: " + iotServerConfigs.getDeviceId()); + log.info(AgentConstants.LOG_APPENDER + "Device Name: " + + iotServerConfigs.getDeviceName()); + log.info(AgentConstants.LOG_APPENDER + "Device Controller Context: " + + iotServerConfigs.getControllerContext()); + log.info(AgentConstants.LOG_APPENDER + "IoT Server HTTPS EndPoint: " + + iotServerConfigs.getHTTPS_ServerEndpoint()); + log.info(AgentConstants.LOG_APPENDER + "IoT Server HTTP EndPoint: " + + iotServerConfigs.getHTTP_ServerEndpoint()); + log.info(AgentConstants.LOG_APPENDER + "API-Manager Gateway EndPoint: " + + iotServerConfigs.getApimGatewayEndpoint()); + log.info(AgentConstants.LOG_APPENDER + "MQTT Broker EndPoint: " + + iotServerConfigs.getMqttBrokerEndpoint()); + log.info(AgentConstants.LOG_APPENDER + "XMPP Server EndPoint: " + + iotServerConfigs.getXmppServerEndpoint()); + log.info(AgentConstants.LOG_APPENDER + "Authentication Method: " + + iotServerConfigs.getAuthMethod()); + log.info(AgentConstants.LOG_APPENDER + "Base64Encoded API Application Key: " + + iotServerConfigs.getApiApplicationKey()); + log.info(AgentConstants.LOG_APPENDER + "Authentication Token: " + + iotServerConfigs.getAuthToken()); + log.info(AgentConstants.LOG_APPENDER + "Refresh Token: " + + iotServerConfigs.getRefreshToken()); + log.info(AgentConstants.LOG_APPENDER + "Data Push Interval: " + + iotServerConfigs.getDataPushInterval()); + log.info(AgentConstants.LOG_APPENDER + "XMPP Server Name: " + + iotServerConfigs.getXmppServerName()); + } else { + throw new AgentCoreOperationException( + "Failed to load path of resource [" + propertiesFileName + "] from this classpath."); + } } catch (FileNotFoundException ex) { String errorMsg = "[" + propertiesFileName + "] file not found at: " + rootPath; log.error(AgentConstants.LOG_APPENDER + errorMsg); @@ -216,6 +226,26 @@ public class AgentUtilOperations { 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 { PrivateKey devicePrivateKey = EnrollmentManager.getInstance().getPrivateKey(); @@ -234,7 +264,6 @@ public class AgentUtilOperations { jsonPayload.put(JSON_SIGNATURE_KEY, signedPayload); //below statements are temporary fix. jsonPayload.put(JSON_SERIAL_KEY, EnrollmentManager.getInstance().getSCEPCertificate().getSerialNumber()); - return jsonPayload.toString(); } @@ -282,26 +311,19 @@ public class AgentUtilOperations { } } - - public static boolean refreshOAuthToken() throws AgentCoreOperationException { + public static void refreshOAuthToken() throws AgentCoreOperationException { AgentManager agentManager = AgentManager.getInstance(); - String tokenEndpoint = agentManager.getAgentConfigs().getApimGatewayEndpoint() + "/token"; + String tokenEndpoint = agentManager.getAgentConfigs().getApimGatewayEndpoint(); + tokenEndpoint = tokenEndpoint + APIManagerTokenUtils.TOKEN_ENDPOINT; + HttpURLConnection httpConnection = null; BufferedReader connectionBuffer = null; String requestPayload; String dataFromBuffer; StringBuilder responseMessage = new StringBuilder(); - boolean refreshStatus = false; try { - httpConnection = TransportUtils.getHttpConnection(tokenEndpoint); - httpConnection.setRequestMethod(AgentConstants.HTTP_POST); - httpConnection.setRequestProperty(AgentConstants.AUTHORIZATION_HEADER, - "Bearer " + agentManager.getAgentConfigs().getApiApplicationKey()); - httpConnection.setRequestProperty(AgentConstants.CONTENT_TYPE_HEADER, AgentConstants.X_WWW_FORM_URLENCODED); - httpConnection.setDoOutput(true); - String refreshToken = agentManager.getAgentConfigs().getRefreshToken(); String applicationScope = "device_type_" + AgentConstants.DEVICE_TYPE + " device_" + agentManager.getAgentConfigs().getDeviceId(); @@ -310,6 +332,13 @@ public class AgentUtilOperations { 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(); @@ -320,17 +349,19 @@ public class AgentUtilOperations { log.info(AgentConstants.LOG_APPENDER + "Response [" + httpConnection.getResponseCode() + ":" + httpConnection.getResponseMessage() + "] was received for token refresh attempt."); - connectionBuffer = new BufferedReader(new InputStreamReader(httpConnection.getInputStream())); + if (httpConnection.getResponseCode() == HttpStatus.OK_200) { + connectionBuffer = new BufferedReader(new InputStreamReader(httpConnection.getInputStream())); + while ((dataFromBuffer = connectionBuffer.readLine()) != null) { + responseMessage.append(dataFromBuffer); + } - 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 { + log.info(AgentConstants.LOG_APPENDER + "There was an issue with refreshing the Access Token."); } - log.info(AgentConstants.LOG_APPENDER + "Response [" + responseMessage + - "] was received for the token refresh call."); - - refreshStatus = updateExistingTokens(responseMessage.toString()); - } catch (TransportHandlerException e) { throw new AgentCoreOperationException(e); } catch (ProtocolException e) { @@ -359,20 +390,18 @@ public class AgentUtilOperations { httpConnection.disconnect(); } } - return refreshStatus; } - - private static boolean updateExistingTokens(String responseFromTokenEP) { + 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) { - log.error( - AgentConstants.LOG_APPENDER + "Neither Access-Token nor Refresh-Token was found in the response [" + - responseFromTokenEP + "]."); - return false; + 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); @@ -380,42 +409,21 @@ public class AgentUtilOperations { String deviceConfigFilePath = AgentManager.getInstance().getRootPath() + AgentConstants.AGENT_PROPERTIES_FILE_NAME; - Properties deviceProperties = new Properties(); - FileOutputStream fileOutputStream = null; - try { - fileOutputStream = new FileOutputStream(deviceConfigFilePath); - deviceProperties.setProperty(AgentConstants.AUTH_TOKEN_PROPERTY, newAccessToken); - deviceProperties.setProperty(AgentConstants.REFRESH_TOKEN_PROPERTY, newRefreshToken); - deviceProperties.store(fileOutputStream, null); - - } catch (FileNotFoundException ex) { - String errorMsg = - "[" + AgentConstants.AGENT_PROPERTIES_FILE_NAME + "] file not found at: " + deviceConfigFilePath; - log.error(AgentConstants.LOG_APPENDER + errorMsg); - return false; - - } catch (IOException ex) { - String errorMsg = "Error occurred whilst trying to write to [" + AgentConstants.AGENT_PROPERTIES_FILE_NAME + - "] at: " + deviceConfigFilePath; - log.error(AgentConstants.LOG_APPENDER + errorMsg); - return false; - } finally { - if (fileOutputStream != null) { - try { - fileOutputStream.close(); - } catch (IOException e) { - log.error(AgentConstants.LOG_APPENDER + - "Error occurred whilst trying to close InputStream resource used to read the '" + - AgentConstants.AGENT_PROPERTIES_FILE_NAME + "' file"); - } - } + 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); } - return true; } - 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"; diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/enrollment/EnrollmentManager.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/enrollment/EnrollmentManager.java index 345743ac4..4132e503f 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/enrollment/EnrollmentManager.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/enrollment/EnrollmentManager.java @@ -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 sun.security.x509.X509CertImpl; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.math.BigInteger; import java.net.MalformedURLException; import java.net.URL; +import java.security.Key; import java.security.KeyPair; import java.security.KeyPairGenerator; +import java.security.KeyStore; +import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; +import java.security.UnrecoverableKeyException; import java.security.cert.CertStore; import java.security.cert.CertStoreException; import java.security.cert.Certificate; @@ -96,6 +102,7 @@ public class EnrollmentManager { private PublicKey publicKey; private PublicKey serverPublicKey; private X509Certificate SCEPCertificate; + private boolean isEnrolled = false; /** @@ -104,6 +111,7 @@ public class EnrollmentManager { */ private EnrollmentManager() { this.SCEPUrl = AgentManager.getInstance().getEnrollmentEP(); + setEnrollmentStatus(); } /** @@ -119,6 +127,58 @@ 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)); + + } 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.serverPublicKey = (PublicKey) keyStore.getKey(AgentConstants.SERVER_PUBLIC_KEY_ALIAS, + AgentConstants.DEVICE_KEYSTORE_PASSWORD + .toCharArray()); + this.publicKey = SCEPCertificate.getPublicKey(); + } + } 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 * Pair, calls the specific method to generate the Certificate-Sign-Request, creates a one time self signed @@ -181,14 +241,67 @@ public class EnrollmentManager { this.SCEPCertificate = getSignedCertificateFromServer(tmpCert, certSignRequest); this.serverPublicKey = initPublicKeyOfServer(); + storeCertificateToStore(AgentConstants.DEVICE_CERT_ALIAS, SCEPCertificate); + storeKeyToKeyStore(AgentConstants.DEVICE_PRIVATE_KEY_ALIAS, this.privateKey, SCEPCertificate); + storeKeyToKeyStore(AgentConstants.SERVER_PUBLIC_KEY_ALIAS, this.serverPublicKey, SCEPCertificate); + 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 + "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. * @@ -407,9 +520,9 @@ public class EnrollmentManager { return serverCertPublicKey; } - /** * Gets the Public-Key of the client. + * * @return the public key of the client. */ public PublicKey getPublicKey() { @@ -418,6 +531,7 @@ public class EnrollmentManager { /** * Gets the Private-Key of the client. + * * @return the private key of the client. */ public PrivateKey getPrivateKey() { @@ -426,6 +540,7 @@ public class EnrollmentManager { /** * Gets the SCEP-Certificate of the client. + * * @return the SCEP Certificate of the client. */ public X509Certificate getSCEPCertificate() { @@ -434,9 +549,19 @@ public class EnrollmentManager { /** * Gets the Public-Key of the Server. + * * @return the pubic key of the server. */ public PublicKey getServerPublicKey() { 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; + } } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/transport/TransportUtils.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/transport/TransportUtils.java index 050b8a578..11ebc04bf 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/transport/TransportUtils.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/transport/TransportUtils.java @@ -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.LogFactory; +import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.core.AgentConstants; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.transport.TransportHandlerException; import java.io.BufferedReader; @@ -67,9 +68,9 @@ public class TransportUtils { throw new TransportHandlerException(errorMsg); } - ipPortMap.put("Protocol", ipPortArray[0]); - ipPortMap.put("Host", ipPortArray[1].replace("/", "")); - ipPortMap.put("Port", ipPortArray[2]); + ipPortMap.put(AgentConstants.PROTOCOL_PROPERTY, ipPortArray[0]); + ipPortMap.put(AgentConstants.HOST_PROPERTY, ipPortArray[1].replace("/", "")); + ipPortMap.put(AgentConstants.PORT_PROPERTY, ipPortArray[2]); return ipPortMap; } @@ -99,8 +100,7 @@ public class TransportUtils { return !ipAddress.endsWith("."); } catch (NumberFormatException nfe) { - log.warn("The IP Address: " + ipAddress + " could not " + - "be validated against IPv4-style"); + log.warn("The IP Address: " + ipAddress + " could not be validated against IPv4-style"); return false; } } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/transport/mqtt/MQTTTransportHandler.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/transport/mqtt/MQTTTransportHandler.java index e25324ea1..f7c6864c1 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/transport/mqtt/MQTTTransportHandler.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/transport/mqtt/MQTTTransportHandler.java @@ -52,7 +52,6 @@ import java.nio.charset.StandardCharsets; public abstract class MQTTTransportHandler implements MqttCallback, TransportHandler { 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; private MqttClient client; @@ -82,8 +81,6 @@ public abstract class MQTTTransportHandler this.mqttBrokerEndPoint = mqttBrokerEndPoint; this.timeoutInterval = DEFAULT_TIMEOUT_INTERVAL; 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.timeoutInterval = intervalInMillis; this.initSubscriber(); - options.setUserName(AgentManager.getInstance().getAgentConfigs().getAuthToken()); - options.setPassword(DEFAULT_PASSWORD.toCharArray()); } 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. * @@ -248,8 +249,7 @@ public abstract class MQTTTransportHandler try { client.publish(topic, payLoad.getBytes(StandardCharsets.UTF_8), qos, retained); if (log.isDebugEnabled()) { - log.debug("Message: " + payLoad + " to MQTT topic [" + topic + - "] published successfully"); + log.debug("Message: " + payLoad + " to MQTT topic [" + topic + "] published successfully"); } } catch (MqttException ex) { String errorMsg = @@ -267,8 +267,7 @@ public abstract class MQTTTransportHandler try { client.publish(topic, message); if (log.isDebugEnabled()) { - log.debug("Message: " + message.toString() + " to MQTT topic [" + topic + - "] published successfully"); + log.debug("Message: " + message.toString() + " to MQTT topic [" + topic + "] published successfully"); } } catch (MqttException ex) { //TODO:: Compulsory log of errors and remove formatted error @@ -291,8 +290,7 @@ public abstract class MQTTTransportHandler @Override public void connectionLost(Throwable throwable) { log.warn("Lost Connection for client: " + this.clientId + - " to " + this.mqttBrokerEndPoint + ".\nThis was due to - " + - throwable.getMessage()); + " to " + this.mqttBrokerEndPoint + ".\nThis was due to - " + throwable.getMessage()); Thread reconnectThread = new Thread() { public void run() { @@ -340,8 +338,7 @@ public abstract class MQTTTransportHandler } catch (MqttException e) { //TODO:: Throw errors log.error( - "Error occurred whilst trying to read the message from the MQTT delivery " + - "token."); + "Error occurred whilst trying to read the message from the MQTT delivery token."); } String topic = iMqttDeliveryToken.getTopics()[0]; String client = iMqttDeliveryToken.getClient().getClientId(); diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java index 07d055e16..36444611d 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java @@ -77,7 +77,7 @@ public class ZipUtil { xmppEndpoint = xmppEndpoint.replace(LOCALHOST, iotServerIP); } - String base64EncodedApplicationKey = getBase64EncodedAPIAppKey(apiApplicationKey); + String base64EncodedApplicationKey = getBase64EncodedAPIAppKey(apiApplicationKey).trim(); Map contextParams = new HashMap<>(); contextParams.put(VirtualFireAlarmUtilConstants.TENANT_DOMAIN, APIUtil.getTenantDomainOftheUser()); diff --git a/features/iot-plugins-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/agent/deviceConfig.properties b/features/iot-plugins-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/agent/deviceConfig.properties index 47a3a73a6..1ee0aa15f 100644 --- a/features/iot-plugins-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/agent/deviceConfig.properties +++ b/features/iot-plugins-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/agent/deviceConfig.properties @@ -28,6 +28,7 @@ apim-ep=${APIM_EP} mqtt-ep=${MQTT_EP} xmpp-ep=${XMPP_EP} auth-method=token +application-key=${API_APPLICATION_KEY} auth-token=${DEVICE_TOKEN} refresh-token=${DEVICE_REFRESH_TOKEN} push-interval=15 diff --git a/features/iot-plugins-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/agent/virtual_firealarm.jks b/features/iot-plugins-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/agent/virtual_firealarm.jks new file mode 100644 index 0000000000000000000000000000000000000000..7ce3e66ad809d6cd225af49aa201262d1fe8894a GIT binary patch literal 635 zcmezO_TO6u1_mY|W(3omnfWEfsYPX}ML>~|d-uF1FtA4GnHpFE6m?<$jZRn*vnwh*vZt`$S`I3FVSmX=Y0P1 z#8IPRua(}0Gv|!k*05(R-L`jvR?qY9X;a1Cn|?Uur#nge!)A4V)1^~pzt7+cWMI$C zahUzPpS5>G+$Cwbz{{0#bM)ubAC5j2Q;_}Sd6AXXuH7vg)?c0YcE^JilQ@e1u)J

Rd_Z+cf2pnXKsRr`tWWWK{TXH#K@FtlY7J=Tv9%<8+6* F4*;FQ(GLIs literal 0 HcmV?d00001 From dca55d692c5770f94ee6db7767b32ba1110e7a7b Mon Sep 17 00:00:00 2001 From: Shabirmean Date: Thu, 2 Jun 2016 17:12:06 +0530 Subject: [PATCH 3/4] Changes following the hashCode of the deviceId being used as the certificate alias --- .../impl/util/VirtualFirealarmMqttContentTransformer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmMqttContentTransformer.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmMqttContentTransformer.java index 24d534536..4a5240835 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmMqttContentTransformer.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmMqttContentTransformer.java @@ -25,7 +25,7 @@ public class VirtualFirealarmMqttContentTransformer implements ContentTransforme Long serialNo = (Long) jsonPayload.get(VirtualFireAlarmConstants.JSON_SERIAL_KEY); // the hash-code of the deviceId is used as the alias for device certificates during SCEP enrollment. // hence, the same is used here to fetch the device-specific-certificate from the key store. - PublicKey clientPublicKey = VirtualFireAlarmUtils.getDevicePublicKey("" + serialNo); + PublicKey clientPublicKey = VirtualFireAlarmUtils.getDevicePublicKey("" + serialNo.hashCode()); // the MQTT-messages from VirtualFireAlarm devices are in the form {"Msg":, "Sig":} String actualMessage = VirtualFireAlarmUtils.extractMessageFromPayload((String) message, clientPublicKey); From 38c087ebc1d4b299b3a0f977fc907c34cafc1b18 Mon Sep 17 00:00:00 2001 From: Shabirmean Date: Wed, 8 Jun 2016 12:00:32 +0530 Subject: [PATCH 4/4] Added necessary changes to store CA_CERT and handle expired refresh-token scenario --- .../agent/core/AgentConstants.java | 2 +- .../agent/core/AgentUtilOperations.java | 6 +++++- .../agent/enrollment/EnrollmentManager.java | 15 ++++++++++----- .../VirtualFirealarmMqttContentTransformer.java | 5 +++-- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConstants.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConstants.java index 3c661c6d7..af697504e 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConstants.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentConstants.java @@ -123,5 +123,5 @@ public class AgentConstants { 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_PUBLIC_KEY_ALIAS = "iotServer_key"; + public static final String SERVER_CA_CERT_ALIAS = "ca_iotServer"; } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentUtilOperations.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentUtilOperations.java index 7f407f5ca..84890a52e 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentUtilOperations.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/core/AgentUtilOperations.java @@ -358,8 +358,12 @@ public class AgentUtilOperations { 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.info(AgentConstants.LOG_APPENDER + "There was an issue with refreshing the Access Token."); + log.warn(AgentConstants.LOG_APPENDER + "There was an issue with refreshing the Access Token."); } } catch (TransportHandlerException e) { diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/enrollment/EnrollmentManager.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/enrollment/EnrollmentManager.java index 4132e503f..6059483bc 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/enrollment/EnrollmentManager.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/agent/enrollment/EnrollmentManager.java @@ -136,7 +136,8 @@ public class EnrollmentManager { AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray()); this.isEnrolled = (keyStore.containsAlias(AgentConstants.DEVICE_CERT_ALIAS) && - keyStore.containsAlias(AgentConstants.DEVICE_PRIVATE_KEY_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 '" + @@ -165,10 +166,14 @@ public class EnrollmentManager { 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.serverPublicKey = (PublicKey) keyStore.getKey(AgentConstants.SERVER_PUBLIC_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 '" + @@ -243,7 +248,6 @@ public class EnrollmentManager { storeCertificateToStore(AgentConstants.DEVICE_CERT_ALIAS, SCEPCertificate); storeKeyToKeyStore(AgentConstants.DEVICE_PRIVATE_KEY_ALIAS, this.privateKey, SCEPCertificate); - storeKeyToKeyStore(AgentConstants.SERVER_PUBLIC_KEY_ALIAS, this.serverPublicKey, SCEPCertificate); if (log.isDebugEnabled()) { log.info(AgentConstants.LOG_APPENDER + @@ -495,6 +499,7 @@ public class EnrollmentManager { // This is because the returned keystore may contain many certificates including RAs. if (((Boolean) ((X509CertImpl) cert).getBasicConstraintsExtension().get(CERT_IS_CA_EXTENSION))) { serverCertPublicKey = cert.getPublicKey(); + storeCertificateToStore(AgentConstants.SERVER_CA_CERT_ALIAS, cert); } } } diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmMqttContentTransformer.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmMqttContentTransformer.java index 4a5240835..1be978c16 100644 --- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmMqttContentTransformer.java +++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/util/VirtualFirealarmMqttContentTransformer.java @@ -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.exception.VirtualFirealarmDeviceMgtPluginException; +import java.math.BigInteger; import java.security.PublicKey; import java.util.Map; @@ -22,10 +23,10 @@ public class VirtualFirealarmMqttContentTransformer implements ContentTransforme PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); 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. // hence, the same is used here to fetch the device-specific-certificate from the key store. - PublicKey clientPublicKey = VirtualFireAlarmUtils.getDevicePublicKey("" + serialNo.hashCode()); + PublicKey clientPublicKey = VirtualFireAlarmUtils.getDevicePublicKey("" + serialNo); // the MQTT-messages from VirtualFireAlarm devices are in the form {"Msg":, "Sig":} String actualMessage = VirtualFireAlarmUtils.extractMessageFromPayload((String) message, clientPublicKey);