From c3f23fa564aca196128d0fae33107201ffa9ebb7 Mon Sep 17 00:00:00 2001 From: ayyoob Date: Mon, 29 May 2017 01:00:16 +0530 Subject: [PATCH] fixed multi tenant issues after testing custom device type impl --- .../extension/api/util/APIUtil.java | 2 + .../mqtt/MQTTNotificationStrategy.java | 9 +- .../service/EventsPublisherServiceImpl.java | 37 +- .../org.wso2.carbon.device.mgt.api/pom.xml | 5 + .../mgt/jaxrs/beans/EventBeanWrapper.java | 44 ++ .../jaxrs/service/api/DeviceAgentService.java | 543 ++++++++++++++++++ .../service/api/DeviceManagementService.java | 345 ----------- .../service/impl/DeviceAgentServiceImpl.java | 441 ++++++++++++++ .../DeviceEventManagementServiceImpl.java | 334 ++--------- .../impl/DeviceManagementServiceImpl.java | 231 -------- .../device/mgt/jaxrs/util/Constants.java | 2 + .../mgt/jaxrs/util/DeviceMgtAPIUtils.java | 300 ++++++++++ .../src/main/webapp/WEB-INF/cxf-servlet.xml | 2 + .../dao/DeviceTypePluginDAOManager.java | 13 +- .../jaggeryapps/devicemgt/api/device-api.jag | 1 - .../devicemgt/app/conf/config.json | 35 +- .../modules/business-controllers/device.js | 5 +- .../public/js/devicetype-listing.js | 5 +- .../dataTables.extended.serversidepaging.js | 8 +- .../analytics-view.hbs | 2 +- .../analytics-view.js | 14 +- .../public/js/type-view.js | 4 +- .../type-view.hbs | 55 +- .../type-view.js | 14 + 24 files changed, 1512 insertions(+), 939 deletions(-) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/EventBeanWrapper.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceAgentService.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceImpl.java diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/util/APIUtil.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/util/APIUtil.java index 8b888a010d..54d68e7baa 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/util/APIUtil.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/util/APIUtil.java @@ -42,6 +42,7 @@ public class APIUtil { private static Log log = LogFactory.getLog(APIUtil.class); private static final String DEFAULT_CDMF_API_TAG = "device_management"; + private static final String DEFAULT_AGENT_API_TAG = "device_agent"; private static final String DEFAULT_CERT_API_TAG = "scep_management"; public static final String PERMISSION_PROPERTY_NAME = "name"; @@ -106,6 +107,7 @@ public class APIUtil { List allowedApisTags = getDeviceManagementProviderService().getAvailableDeviceTypes(); allowedApisTags.add(DEFAULT_CDMF_API_TAG); allowedApisTags.add(DEFAULT_CERT_API_TAG); + allowedApisTags.add(DEFAULT_AGENT_API_TAG); return allowedApisTags; } diff --git a/components/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt/src/main/java/org/wso2/carbon/device/mgt/extensions/push/notification/provider/mqtt/MQTTNotificationStrategy.java b/components/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt/src/main/java/org/wso2/carbon/device/mgt/extensions/push/notification/provider/mqtt/MQTTNotificationStrategy.java index 044f41bcb9..a2c4c0c305 100644 --- a/components/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt/src/main/java/org/wso2/carbon/device/mgt/extensions/push/notification/provider/mqtt/MQTTNotificationStrategy.java +++ b/components/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt/src/main/java/org/wso2/carbon/device/mgt/extensions/push/notification/provider/mqtt/MQTTNotificationStrategy.java @@ -159,11 +159,14 @@ public class MQTTNotificationStrategy implements NotificationStrategy { + ctx.getDeviceId().getType() + "/" + ctx.getDeviceId().getId() + "/operation/" + operation.getType().toString().toLowerCase() + "/" + operation.getCode(); dynamicProperties.put("topic", topic); - if (operation.getPayLoad() == null) { - operation.setPayLoad(operation.getCode()); + Object payload; + if ("command".equals(operation.getType().toString().toLowerCase())) { + payload = operation.getCode(); + } else { + payload = operation.getPayLoad(); } MQTTDataHolder.getInstance().getOutputEventAdapterService().publish(adapterName, dynamicProperties, - operation.getPayLoad()); + payload); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/service/EventsPublisherServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/service/EventsPublisherServiceImpl.java index 63e5bee1a6..8c4d5da3e2 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/service/EventsPublisherServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/service/EventsPublisherServiceImpl.java @@ -21,10 +21,12 @@ package org.wso2.carbon.device.mgt.analytics.data.publisher.service; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.databridge.agent.DataPublisher; import org.wso2.carbon.databridge.commons.utils.DataBridgeCommonsUtils; import org.wso2.carbon.device.mgt.analytics.data.publisher.DeviceDataPublisher; import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException; +import org.wso2.carbon.utils.multitenancy.MultitenantConstants; /** * This is the implementation of Osgi Service which can be used to publish and retireved @@ -46,15 +48,32 @@ public class EventsPublisherServiceImpl implements EventsPublisherService { public boolean publishEvent(String streamName, String version, Object[] metaDataArray, Object[] correlationDataArray, Object[] payloadDataArray) throws DataPublisherConfigurationException { - DataPublisher dataPublisher = DeviceDataPublisher.getInstance().getDataPublisher(); - if (dataPublisher != null) { - String streamId = DataBridgeCommonsUtils.generateStreamId(streamName, version); - return dataPublisher.tryPublish(streamId, System.currentTimeMillis(), metaDataArray, correlationDataArray, - payloadDataArray); - } else { - return false; - } - } + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) { + if (metaDataArray == null || metaDataArray.length == 0) { + throw new DataPublisherConfigurationException("meta data[0] should have the device Id field"); + } else { + metaDataArray[0] = tenantDomain + "@" + metaDataArray[0]; + } + } + + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext() + .setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true); + try { + DataPublisher dataPublisher = DeviceDataPublisher.getInstance().getDataPublisher(); + if (dataPublisher != null) { + String streamId = DataBridgeCommonsUtils.generateStreamId(streamName, version); + return dataPublisher.tryPublish(streamId, System.currentTimeMillis(), metaDataArray, + correlationDataArray, + payloadDataArray); + } else { + return false; + } + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/pom.xml b/components/device-mgt/org.wso2.carbon.device.mgt.api/pom.xml index 6a5010e362..58553b3894 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/pom.xml +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/pom.xml @@ -167,6 +167,11 @@ org.wso2.carbon.device.mgt.common provided + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.analytics.data.publisher + provided + org.wso2.carbon.devicemgt org.wso2.carbon.device.mgt.extensions diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/EventBeanWrapper.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/EventBeanWrapper.java new file mode 100644 index 0000000000..7dc667008e --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/EventBeanWrapper.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http:www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.Size; + +/** + * This class is used to wrap the events which receive from the agent application. + */ +@ApiModel(value = "EventBeanWrapper", + description = "agent's event related Information.") +public class EventBeanWrapper { + + @ApiModelProperty(name = "payloadData", value = "Event payload payload.", required = true) + Object[] payloadData; + + public Object[] getPayloadData() { + return payloadData; + } + + public void setPayloadData(Object[] payloadData) { + this.payloadData = payloadData; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceAgentService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceAgentService.java new file mode 100644 index 0000000000..9f2905fbaf --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceAgentService.java @@ -0,0 +1,543 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.api; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Info; +import io.swagger.annotations.ResponseHeader; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.EventBeanWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.OperationList; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.validation.Valid; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +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.MediaType; +import javax.ws.rs.core.Response; + +@SwaggerDefinition( + info = @Info( + version = "1.0.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "DeviceAgent Service"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v1.0/device/agent"), + }) + } + ), + tags = { + @Tag(name = "device_agent, device_management", description = "") + } +) +@Api(value = "Device Agent", description = "Device Agent Service") +@Path("/device/agent") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Scopes( + scopes = { + @Scope( + name = "Enroll Device", + description = "Register a device", + key = "perm:device:enroll", + permissions = {"/device-mgt/devices/owning-device/add"} + ), + @Scope( + name = "Modify Device", + description = "Modify a device", + key = "perm:device:modify", + permissions = {"/device-mgt/devices/owning-device/modify"} + ), + @Scope( + name = "Getting Device Operation Details", + description = "Getting Device Operation Details", + key = "perm:devices:operations", + permissions = {"/device-mgt/devices/owning-device/view"} + ), + @Scope( + name = "Disenroll Device", + description = "Disenroll a device", + key = "perm:device:disenroll", + permissions = {"/device-mgt/devices/owning-device/remove"} + ) + } +) +public interface DeviceAgentService { + + @POST + @Path("/enroll") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Create a device instance", + notes = "Create a device Instance", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:enroll") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully created a device instance.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest version" + + " of the requested resource.\n"), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n A deviceType with the specified device type was not found.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving the device details.", + response = ErrorResponse.class) + }) + Response enrollDevice(@ApiParam(name = "device", value = "Device object with data.", required = true) + @Valid Device device); + + @DELETE + @Path("/enroll/{type}/{id}") + @ApiOperation( + httpMethod = "DELETE", + value = "Unregistering a Device", + notes = "Use this REST API to unregister a device.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:disenroll") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully disenrolled the device."), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while dis-enrolling the device.") + }) + Response disEnrollDevice( + @ApiParam(name = "type", value = "The unique device identifier.") @PathParam("type") String type, + @ApiParam(name = "id", value = "The unique device identifier.") @PathParam("id") String id); + + @PUT + @Path("/enroll/{type}/{id}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "modify device", + notes = "modify device", + tags = "Device Agent Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:modify") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully updated device instance.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest version" + + " of the requested resource.\n"), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n A deviceType with the specified device type was not found.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving the device details.", + response = ErrorResponse.class) + }) + Response updateDevice(@ApiParam(name = "type", value = "The device type, such as ios, android or windows....etc", required = true) + @PathParam("type") String type, + @ApiParam(name = "id", value = "The device id.", required = true) + @PathParam("id") String deviceId, + @ApiParam(name = "device", value = "Device object with data.", required = true) + @Valid Device updateDevice); + + @POST + @Path("/events/publish/{type}/{deviceId}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Publishing Events", + notes = "Publish events received by the device client to the WSO2 Data Analytics Server (DAS) using this API.", + tags = "Device Agent Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:enroll") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = 201, message = "Created. \n Successfully published the event. Location header " + + "contains URL of newly enrolled device", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The URL of the added policy."), + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.") + }), + @ApiResponse( + code = 303, + message = "See Other. \n The source can be retrieved from the URL specified in the location header.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The Source URL of the document.")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error."), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while publishing events.") + }) + Response publishEvents( + @ApiParam( + name = "eventBeanWrapper", + value = "Information of the agent event to be published on DAS.") + @Valid + EventBeanWrapper eventBeanWrapper, + @ApiParam( + name = "type", + value = "name of the device type") + @PathParam("type") String type, + @ApiParam( + name = "deviceId", + value = "deviceId of the device") + @PathParam("deviceId") String deviceId); + + @GET + @Path("/pending/operations/{type}/{id}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Get pending operation of the given device", + notes = "Returns the Operations.", + tags = "Device Agent Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved the operations.", + response = OperationList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response getPendingOperations(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) + @PathParam("type") String type, + @ApiParam(name = "id", value = "The device id.", required = true) + @PathParam("id") String deviceId); + + @GET + @Path("/last-pending/operation/{type}/{id}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Get pending operation of the given device", + notes = "Returns the Operation.", + tags = "Device Agent Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved the operation.", + response = Operation.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response getNextPendingOperation(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) + @PathParam("type") String type, + @ApiParam(name = "id", value = "The device id.", required = true) + @PathParam("id") String deviceId); + + @PUT + @Path("/operations/{type}/{id}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Update Operation", + notes = "Update the Operations.", + tags = "Device Agent Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully updated the operations.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response updateOperation(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) + @PathParam("type") String type, + @ApiParam(name = "id", value = "The device id.", required = true) + @PathParam("id") String deviceId, + @ApiParam(name = "operation", value = "Operation object with data.", required = true) + @Valid Operation operation); + + @GET + @Path("/status/operations/{type}/{id}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Get pending operation of the given device", + notes = "Returns the Operations.", + tags = "Device Agent Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved the operations.", + response = OperationList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response getOperationsByDeviceAndStatus(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) + @PathParam("type") String type, + @ApiParam(name = "id", value = "The device id.", required = true) + @PathParam("id") String deviceId, + @ApiParam(name = "status", value = "status of the operation.", required = true) + @QueryParam("status")Operation.Status status); + + + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java index 8117a47d0f..e74bc20073 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java @@ -143,12 +143,6 @@ import java.util.List; key = "perm:devices:compliance-data", permissions = {"/device-mgt/devices/owning-device/view"} ), - @Scope( - name = "Create a new device Instance", - description = "Create a new device Instance", - key = "perm:devices:add", - permissions = {"/device-mgt/devices/owning-device/add"} - ), @Scope( name = "Change device status.", description = "Change device status.", @@ -435,115 +429,6 @@ public interface DeviceManagementService { @HeaderParam("If-Modified-Since") String ifModifiedSince); - @POST - @ApiOperation( - produces = MediaType.APPLICATION_JSON, - httpMethod = "POST", - value = "Create a device instance", - notes = "Create a device Instance", - tags = "Device Management", - extensions = { - @Extension(properties = { - @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:add") - }) - } - ) - @ApiResponses( - value = { - @ApiResponse( - code = 200, - message = "OK. \n Successfully created a device instance.", - responseHeaders = { - @ResponseHeader( - name = "Content-Type", - description = "The content type of the body"), - @ResponseHeader( - name = "ETag", - description = "Entity Tag of the response resource.\n" + - "Used by caches, or in conditional requests."), - @ResponseHeader( - name = "Last-Modified", - description = "Date and time the resource was last modified.\n" + - "Used by caches, or in conditional requests."), - }), - @ApiResponse( - code = 304, - message = "Not Modified. Empty body because the client already has the latest version" + - " of the requested resource.\n"), - @ApiResponse( - code = 400, - message = "Bad Request. \n Invalid request or validation error.", - response = ErrorResponse.class), - @ApiResponse( - code = 404, - message = "Not Found. \n A deviceType with the specified device type was not found.", - response = ErrorResponse.class), - @ApiResponse( - code = 500, - message = "Internal Server Error. \n " + - "Server error occurred while retrieving the device details.", - response = ErrorResponse.class) - }) - Response enrollDevice(@ApiParam(name = "device", value = "Device object with data.", required = true) - @Valid Device device); - - @GET - @Path("/{type}/{id}/status") - @ApiOperation( - produces = MediaType.APPLICATION_JSON, - httpMethod = "GET", - value = "Get device enrollment status", - notes = "Get device enrollment status", - tags = "Device Management", - extensions = { - @Extension(properties = { - @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:view") - }) - } - ) - @ApiResponses( - value = { - @ApiResponse( - code = 200, - message = "OK. \n Successfully created a device instance.", - responseHeaders = { - @ResponseHeader( - name = "Content-Type", - description = "The content type of the body"), - @ResponseHeader( - name = "ETag", - description = "Entity Tag of the response resource.\n" + - "Used by caches, or in conditional requests."), - @ResponseHeader( - name = "Last-Modified", - description = "Date and time the resource was last modified.\n" + - "Used by caches, or in conditional requests."), - }), - @ApiResponse( - code = 304, - message = "Not Modified. Empty body because the client already has the latest version" + - " of the requested resource.\n"), - @ApiResponse( - code = 400, - message = "Bad Request. \n Invalid request or validation error.", - response = ErrorResponse.class), - @ApiResponse( - code = 404, - message = "Not Found. \n A deviceType with the specified device type was not found.", - response = ErrorResponse.class), - @ApiResponse( - code = 500, - message = "Internal Server Error. \n " + - "Server error occurred while retrieving the device details.", - response = ErrorResponse.class) - }) - Response updateDevice(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) - @PathParam("type") String type, - @ApiParam(name = "id", value = "The device id.", required = true) - @PathParam("id") String deviceId, - @ApiParam(name = "device", value = "Device object with data.", required = true) - @Valid Device updateDevice); - @PUT @Path("/{type}/{id}") @ApiOperation( @@ -1465,235 +1350,5 @@ public interface DeviceManagementService { @ApiParam(name = "deviceOperation", value = "Operation object with device ids.", required = true) @Valid OperationRequest operationRequest); - @GET - @Path("/{type}/{id}/pending/operations") - @ApiOperation( - produces = MediaType.APPLICATION_JSON, - consumes = MediaType.APPLICATION_JSON, - httpMethod = "GET", - value = "Get pending operation of the given device", - notes = "Returns the Operations.", - tags = "Device Management", - extensions = { - @Extension(properties = { - @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") - }) - } - ) - @ApiResponses( - value = { - @ApiResponse( - code = 200, - message = "OK. \n Successfully retrieved the operations.", - response = OperationList.class, - responseHeaders = { - @ResponseHeader( - name = "Content-Type", - description = "The content type of the body"), - @ResponseHeader( - name = "ETag", - description = "Entity Tag of the response resource.\n" + - "Used by caches, or in conditional requests."), - @ResponseHeader( - name = "Last-Modified", - description = "Date and time the resource has been modified the last time.\n" + - "Used by caches, or in conditional requests."), - }), - @ApiResponse( - code = 304, - message = "Not Modified. Empty body because the client already has the latest " + - "version of the requested resource."), - @ApiResponse( - code = 400, - message = "Bad Request. \n Invalid request or validation error.", - response = ErrorResponse.class), - @ApiResponse( - code = 404, - message = "Not Found. \n No device is found under the provided type and id.", - response = ErrorResponse.class), - @ApiResponse( - code = 500, - message = "Internal Server Error. \n " + - "Server error occurred while retrieving information requested device.", - response = ErrorResponse.class) - }) - Response getPendingOperations(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) - @PathParam("type") String type, - @ApiParam(name = "id", value = "The device id.", required = true) - @PathParam("id") String deviceId); - - @GET - @Path("/{type}/{id}/last-pending/operation") - @ApiOperation( - produces = MediaType.APPLICATION_JSON, - consumes = MediaType.APPLICATION_JSON, - httpMethod = "GET", - value = "Get pending operation of the given device", - notes = "Returns the Operation.", - tags = "Device Management", - extensions = { - @Extension(properties = { - @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") - }) - } - ) - @ApiResponses( - value = { - @ApiResponse( - code = 200, - message = "OK. \n Successfully retrieved the operation.", - response = Operation.class, - responseHeaders = { - @ResponseHeader( - name = "Content-Type", - description = "The content type of the body"), - @ResponseHeader( - name = "ETag", - description = "Entity Tag of the response resource.\n" + - "Used by caches, or in conditional requests."), - @ResponseHeader( - name = "Last-Modified", - description = "Date and time the resource has been modified the last time.\n" + - "Used by caches, or in conditional requests."), - }), - @ApiResponse( - code = 304, - message = "Not Modified. Empty body because the client already has the latest " + - "version of the requested resource."), - @ApiResponse( - code = 400, - message = "Bad Request. \n Invalid request or validation error.", - response = ErrorResponse.class), - @ApiResponse( - code = 404, - message = "Not Found. \n No device is found under the provided type and id.", - response = ErrorResponse.class), - @ApiResponse( - code = 500, - message = "Internal Server Error. \n " + - "Server error occurred while retrieving information requested device.", - response = ErrorResponse.class) - }) - Response getNextPendingOperation(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) - @PathParam("type") String type, - @ApiParam(name = "id", value = "The device id.", required = true) - @PathParam("id") String deviceId); - - @PUT - @Path("/{type}/{id}/operations") - @ApiOperation( - produces = MediaType.APPLICATION_JSON, - consumes = MediaType.APPLICATION_JSON, - httpMethod = "PUT", - value = "Update Operation", - notes = "Update the Operations.", - tags = "Device Management", - extensions = { - @Extension(properties = { - @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") - }) - } - ) - @ApiResponses( - value = { - @ApiResponse( - code = 200, - message = "OK. \n Successfully updated the operations.", - responseHeaders = { - @ResponseHeader( - name = "Content-Type", - description = "The content type of the body"), - @ResponseHeader( - name = "ETag", - description = "Entity Tag of the response resource.\n" + - "Used by caches, or in conditional requests."), - @ResponseHeader( - name = "Last-Modified", - description = "Date and time the resource has been modified the last time.\n" + - "Used by caches, or in conditional requests."), - }), - @ApiResponse( - code = 304, - message = "Not Modified. Empty body because the client already has the latest " + - "version of the requested resource."), - @ApiResponse( - code = 400, - message = "Bad Request. \n Invalid request or validation error.", - response = ErrorResponse.class), - @ApiResponse( - code = 404, - message = "Not Found. \n No device is found under the provided type and id.", - response = ErrorResponse.class), - @ApiResponse( - code = 500, - message = "Internal Server Error. \n " + - "Server error occurred while retrieving information requested device.", - response = ErrorResponse.class) - }) - Response updateOperation(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) - @PathParam("type") String type, - @ApiParam(name = "id", value = "The device id.", required = true) - @PathParam("id") String deviceId, - @ApiParam(name = "operation", value = "Operation object with data.", required = true) - @Valid Operation operation); - - @GET - @Path("/{type}/{id}/status/operations") - @ApiOperation( - produces = MediaType.APPLICATION_JSON, - consumes = MediaType.APPLICATION_JSON, - httpMethod = "GET", - value = "Get pending operation of the given device", - notes = "Returns the Operations.", - tags = "Device Management", - extensions = { - @Extension(properties = { - @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") - }) - } - ) - @ApiResponses( - value = { - @ApiResponse( - code = 200, - message = "OK. \n Successfully retrieved the operations.", - response = OperationList.class, - responseHeaders = { - @ResponseHeader( - name = "Content-Type", - description = "The content type of the body"), - @ResponseHeader( - name = "ETag", - description = "Entity Tag of the response resource.\n" + - "Used by caches, or in conditional requests."), - @ResponseHeader( - name = "Last-Modified", - description = "Date and time the resource has been modified the last time.\n" + - "Used by caches, or in conditional requests."), - }), - @ApiResponse( - code = 304, - message = "Not Modified. Empty body because the client already has the latest " + - "version of the requested resource."), - @ApiResponse( - code = 400, - message = "Bad Request. \n Invalid request or validation error.", - response = ErrorResponse.class), - @ApiResponse( - code = 404, - message = "Not Found. \n No device is found under the provided type and id.", - response = ErrorResponse.class), - @ApiResponse( - code = 500, - message = "Internal Server Error. \n " + - "Server error occurred while retrieving information requested device.", - response = ErrorResponse.class) - }) - Response getOperationsByDeviceAndStatus(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) - @PathParam("type") String type, - @ApiParam(name = "id", value = "The device id.", required = true) - @PathParam("id") String deviceId, - @ApiParam(name = "status", value = "status of the operation.", required = true) - @QueryParam("status")Operation.Status status); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceImpl.java new file mode 100644 index 0000000000..44b55cd53e --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceImpl.java @@ -0,0 +1,441 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.apache.axis2.AxisFault; +import org.apache.axis2.client.Options; +import org.apache.axis2.java.security.SSLProtocolSocketFactory; +import org.apache.axis2.transport.http.HTTPConstants; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.core.util.Utils; +import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.EventBeanWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.OperationList; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.Attribute; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.AttributeType; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.EventAttributeList; +import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceAgentService; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.event.stream.stub.EventStreamAdminServiceStub; +import org.wso2.carbon.event.stream.stub.types.EventStreamAttributeDto; +import org.wso2.carbon.event.stream.stub.types.EventStreamDefinitionDto; +import org.wso2.carbon.identity.jwt.client.extension.JWTClient; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.user.api.UserStoreException; + +import javax.cache.Cache; +import javax.cache.Caching; +import javax.validation.Valid; +import javax.ws.rs.DELETE; +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.QueryParam; +import javax.ws.rs.core.Response; +import java.rmi.RemoteException; +import java.util.ArrayList; +import java.util.List; + +@Path("/device/agent") +public class DeviceAgentServiceImpl implements DeviceAgentService { + private static final Log log = LogFactory.getLog(DeviceAgentServiceImpl.class); + + @POST + @Path("/enroll") + @Override + public Response enrollDevice(@Valid Device device) { + if (device == null) { + String errorMessage = "The payload of the device enrollment is incorrect."; + return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build(); + } + try { + DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); + if (device.getType() == null || device.getDeviceIdentifier() == null) { + String errorMessage = "The payload of the device enrollment is incorrect."; + return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build(); + } + Device existingDevice = dms.getDevice(new DeviceIdentifier(device.getType(), device.getType())); + if (existingDevice != null && existingDevice.getEnrolmentInfo() != null && existingDevice + .getEnrolmentInfo().getStatus().equals(EnrolmentInfo.Status.ACTIVE)) { + String errorMessage = "An active enrolment exists"; + return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build(); + } + device.getEnrolmentInfo().setOwner(DeviceMgtAPIUtils.getAuthenticatedUser()); + device.getEnrolmentInfo().setDateOfEnrolment(System.currentTimeMillis()); + device.getEnrolmentInfo().setDateOfLastUpdate(System.currentTimeMillis()); + boolean status = dms.enrollDevice(device); + return Response.status(Response.Status.OK).entity(status).build(); + } catch (DeviceManagementException e) { + String msg = "Error occurred while enrolling the device, which carries the id '" + + device.getDeviceIdentifier() + "'"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @DELETE + @Path("/enroll/{type}/{id}") + @Override + public Response disEnrollDevice(@PathParam("type") String type, @PathParam("id") String id) { + boolean result; + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(id, type); + try { + result = DeviceMgtAPIUtils.getDeviceManagementService().disenrollDevice(deviceIdentifier); + if (result) { + return Response.status(Response.Status.OK).build(); + } else { + return Response.status(Response.Status.NO_CONTENT).entity(type + " device that carries id '" + id + + "' has not been dis-enrolled").build(); + } + } catch (DeviceManagementException e) { + String msg = "Error occurred while enrolling the device, which carries the id '" + id + "'"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @PUT + @Path("/enroll/{type}/{id}") + @Override + public Response updateDevice(@PathParam("type") String type, @PathParam("id") String id, @Valid Device updateDevice) { + Device device; + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(id); + deviceIdentifier.setType(type); + try { + device = DeviceMgtAPIUtils.getDeviceManagementService().getDevice(deviceIdentifier); + } catch (DeviceManagementException e) { + String msg = "Error occurred while getting enrollment details of the Android device that carries the id '" + + id + "'"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + + if (updateDevice == null) { + String errorMessage = "The payload of the device enrollment is incorrect."; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build(); + } + if (device == null) { + String errorMessage = "The device to be modified doesn't exist."; + log.error(errorMessage); + return Response.status(Response.Status.NOT_FOUND).entity(errorMessage).build(); + } + if (device.getEnrolmentInfo().getStatus() == EnrolmentInfo.Status.ACTIVE ) { + DeviceAccessAuthorizationService deviceAccessAuthorizationService = + DeviceMgtAPIUtils.getDeviceAccessAuthorizationService(); + boolean status; + try { + status = deviceAccessAuthorizationService.isUserAuthorized(new DeviceIdentifier(id, type)); + } catch (DeviceAccessAuthorizationException e) { + String msg = "Error occurred while modifying enrollment of the Android device that carries the id '" + + id + "'"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + if (!status) { + return Response.status(Response.Status.UNAUTHORIZED).build(); + } + } + if(updateDevice.getEnrolmentInfo() != null) { + device.getEnrolmentInfo().setDateOfLastUpdate(System.currentTimeMillis()); + device.setEnrolmentInfo(device.getEnrolmentInfo()); + } + device.getEnrolmentInfo().setOwner(DeviceMgtAPIUtils.getAuthenticatedUser()); + if(updateDevice.getDeviceInfo() != null) { + device.setDeviceInfo(updateDevice.getDeviceInfo()); + } + device.setDeviceIdentifier(id); + if(updateDevice.getDescription() != null) { + device.setDescription(updateDevice.getDescription()); + } + if(updateDevice.getName() != null) { + device.setName(updateDevice.getName()); + } + if(updateDevice.getFeatures() != null) { + device.setFeatures(updateDevice.getFeatures()); + } + if(updateDevice.getProperties() != null) { + device.setProperties(updateDevice.getProperties()); + } + boolean result; + try { + device.setType(type); + result = DeviceMgtAPIUtils.getDeviceManagementService().modifyEnrollment(device); + if (result) { + return Response.status(Response.Status.ACCEPTED).build(); + } else { + return Response.status(Response.Status.NOT_MODIFIED).build(); + } + } catch (DeviceManagementException e) { + String msg = "Error occurred while modifying enrollment of the Android device that carries the id '" + + id + "'"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @POST + @Path("/events/publish/{type}/{deviceId}") + @Override + public Response publishEvents(@Valid EventBeanWrapper eventBeanWrapper, @PathParam("type") String type + , @PathParam("deviceId") String deviceId) { + + + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + try { + if (eventBeanWrapper == null) { + String msg = "invalid payload structure"; + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } else { + boolean authorized = DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized + (new DeviceIdentifier(type, deviceId)); + if (!authorized) { + String msg = "does not have permission to access the device."; + return Response.status(Response.Status.UNAUTHORIZED).entity(msg).build(); + } + } + Object metaData[] = new Object[1]; + metaData[0] = deviceId; + EventAttributeList eventAttributeList = DeviceMgtAPIUtils.getDynamicEventCache().get(type); + if (eventAttributeList == null) { + String streamName = DeviceMgtAPIUtils.getStreamDefinition(type, tenantDomain); + EventStreamAdminServiceStub eventStreamAdminServiceStub = + DeviceMgtAPIUtils.getEventStreamAdminServiceStub(); + EventStreamDefinitionDto eventStreamDefinitionDto = eventStreamAdminServiceStub.getStreamDefinitionDto( + streamName + ":" + Constants.DEFAULT_STREAM_VERSION); + if (eventStreamDefinitionDto == null) { + return Response.status(Response.Status.BAD_REQUEST).build(); + } else { + EventStreamAttributeDto[] eventStreamAttributeDtos = eventStreamDefinitionDto.getPayloadData(); + List attributes = new ArrayList<>(); + for (EventStreamAttributeDto eventStreamAttributeDto : eventStreamAttributeDtos) { + attributes.add(new Attribute(eventStreamAttributeDto.getAttributeName() + , AttributeType.valueOf(eventStreamAttributeDto.getAttributeType().toUpperCase()))); + + } + if (eventBeanWrapper.getPayloadData().length != attributes.size()) { + String msg = "payload does not match the stream definition"; + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + eventAttributeList = new EventAttributeList(); + eventAttributeList.setList(attributes); + DeviceMgtAPIUtils.getDynamicEventCache().put(type, eventAttributeList); + } + } + Object[] payload = eventBeanWrapper.getPayloadData(); + int i = 0; + for (Attribute attribute : eventAttributeList.getList()) { + if (attribute.getType() == AttributeType.INT) { + payload[i] = ((Double) payload[i]).intValue(); + } else if (attribute.getType() == AttributeType.LONG) { + payload[i] = ((Double) payload[i]).longValue(); + } + i++; + } + eventBeanWrapper.setPayloadData(payload); + + if (DeviceMgtAPIUtils.getEventPublisherService().publishEvent(DeviceMgtAPIUtils.getStreamDefinition(type + , PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain()) + , Constants.DEFAULT_STREAM_VERSION, metaData + , null, eventBeanWrapper.getPayloadData())) { + return Response.status(Response.Status.OK).build(); + } else { + String msg = "Error occurred while publishing the event."; + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } catch (DataPublisherConfigurationException e) { + String msg = "Error occurred while publishing the event."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (DeviceAccessAuthorizationException e) { + String msg = "Error occurred when checking for authorization"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (AxisFault e) { + log.error("failed to retrieve event definitions for tenantDomain:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (RemoteException e) { + log.error("Failed to connect with the remote services:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (JWTClientException e) { + log.error("Failed to generate jwt token for tenantDomain:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (UserStoreException e) { + log.error("Failed to connect with the user store, tenantDomain: " + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + + } + } + + @GET + @Path("/pending/operations/{type}/{id}") + public Response getPendingOperations(@PathParam("type") String type, @PathParam("id") String deviceId) { + try { + if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { + String errorMessage = "Device identifier list is empty"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, type); + if (!DeviceMgtAPIUtils.isValidDeviceIdentifier(deviceIdentifier)) { + String msg = "Device not found for identifier '" + deviceId + "'"; + log.error(msg); + return Response.status(Response.Status.NO_CONTENT).entity(msg).build(); + } + List operations = DeviceMgtAPIUtils.getDeviceManagementService().getPendingOperations( + deviceIdentifier); + OperationList operationsList = new OperationList(); + operationsList.setList(operations); + operationsList.setCount(operations.size()); + return Response.status(Response.Status.OK).entity(operationsList).build(); + } catch (OperationManagementException e) { + String errorMessage = "Issue in retrieving operation management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); + } catch (DeviceManagementException e) { + String errorMessage = "Issue in retrieving deivce management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); + } + } + + @GET + @Path("/last-pending/operation/{type}/{id}") + public Response getNextPendingOperation(@PathParam("type") String type, @PathParam("id") String deviceId) { + try { + if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { + String errorMessage = "Device identifier list is empty"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, type); + if (!DeviceMgtAPIUtils.isValidDeviceIdentifier(deviceIdentifier)) { + String msg = "Device not found for identifier '" + deviceId + "'"; + log.error(msg); + return Response.status(Response.Status.NO_CONTENT).entity(msg).build(); + } + Operation operation = DeviceMgtAPIUtils.getDeviceManagementService().getNextPendingOperation( + deviceIdentifier); + return Response.status(Response.Status.OK).entity(operation).build(); + } catch (OperationManagementException e) { + String errorMessage = "Issue in retrieving operation management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); + } catch (DeviceManagementException e) { + String errorMessage = "Issue in retrieving deivce management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); + } + } + + @PUT + @Path("/operations/{type}/{id}") + public Response updateOperation(@PathParam("type") String type, @PathParam("id") String deviceId, @Valid Operation operation) { + try { + if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { + String errorMessage = "Device identifier list is empty"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + if (operation == null) { + String errorMessage = "Device identifier list is empty"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, type); + if (!DeviceMgtAPIUtils.isValidDeviceIdentifier(deviceIdentifier)) { + String msg = "Device not found for identifier '" + deviceId + "'"; + log.error(msg); + return Response.status(Response.Status.NO_CONTENT).entity(msg).build(); + } + DeviceMgtAPIUtils.getDeviceManagementService().updateOperation + (deviceIdentifier, operation); + return Response.status(Response.Status.ACCEPTED).build(); + } catch (OperationManagementException e) { + String errorMessage = "Issue in retrieving operation management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); + } catch (DeviceManagementException e) { + String errorMessage = "Issue in retrieving deivce management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); + } + } + + @GET + @Path("/status/operations/{type}/{id}") + public Response getOperationsByDeviceAndStatus(@PathParam("type") String type, @PathParam("id") String deviceId, + @QueryParam("status")Operation.Status status) { + if (status == null) { + String errorMessage = "status is empty"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + + try { + if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { + String errorMessage = "Device identifier list is empty"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + List operations = DeviceMgtAPIUtils.getDeviceManagementService() + .getOperationsByDeviceAndStatus(new DeviceIdentifier(deviceId, type), status); + OperationList operationsList = new OperationList(); + operationsList.setList(operations); + operationsList.setCount(operations.size()); + return Response.status(Response.Status.OK).entity(operationsList).build(); + } catch (OperationManagementException e) { + String errorMessage = "Issue in retrieving operation management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); + } catch (DeviceManagementException e) { + String errorMessage = "Issue in retrieving device management service"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); + } + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceEventManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceEventManagementServiceImpl.java index 306a427252..5f41267509 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceEventManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceEventManagementServiceImpl.java @@ -1,14 +1,7 @@ package org.wso2.carbon.device.mgt.jaxrs.service.impl; import org.apache.axis2.AxisFault; -import org.apache.axis2.client.Options; import org.apache.axis2.client.Stub; -import org.apache.axis2.transport.http.HTTPConstants; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.httpclient.Header; -import org.apache.commons.httpclient.protocol.Protocol; -import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; -import org.apache.axis2.java.security.SSLProtocolSocketFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.analytics.api.AnalyticsDataAPI; @@ -37,10 +30,11 @@ import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.AttributeType; import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.EventAttributeList; import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.TransportType; import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceEventManagementService; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; import org.wso2.carbon.event.publisher.stub.EventPublisherAdminServiceCallbackHandler; import org.wso2.carbon.event.publisher.stub.EventPublisherAdminServiceStub; -import org.wso2.carbon.event.receiver.stub.types.EventMappingPropertyDto; +import org.wso2.carbon.event.publisher.stub.types.EventMappingPropertyDto; import org.wso2.carbon.event.receiver.stub.EventReceiverAdminServiceCallbackHandler; import org.wso2.carbon.event.receiver.stub.EventReceiverAdminServiceStub; import org.wso2.carbon.event.receiver.stub.types.BasicInputAdapterPropertyDto; @@ -67,15 +61,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; import java.rmi.RemoteException; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -89,55 +75,14 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe private static final Log log = LogFactory.getLog(DeviceEventManagementServiceImpl.class); - private static final String DAS_PORT = "${iot.analytics.https.port}"; - private static final String DAS_HOST_NAME = "${iot.analytics.host}"; - private static final String DEFAULT_HTTP_PROTOCOL = "https"; - private static final String DAS_ADMIN_SERVICE_EP = DEFAULT_HTTP_PROTOCOL + "://" + DAS_HOST_NAME - + ":" + DAS_PORT + "/services/"; - private static final String EVENT_RECIEVER_CONTEXT = "EventReceiverAdminService/"; - private static final String EVENT_PUBLISHER_CONTEXT = "EventPublisherAdminService/"; - private static final String EVENT_STREAM_CONTEXT = "EventStreamAdminService/"; - private static final String EVENT_PERSISTENCE_CONTEXT = "EventStreamPersistenceAdminService/"; - private static final String AUTHORIZATION_HEADER = "Authorization"; - private static final String AUTHORIZATION_HEADER_VALUE = "Bearer"; - private static final String KEY_STORE_TYPE = "JKS"; - private static final String TRUST_STORE_TYPE = "JKS"; - private static final String KEY_MANAGER_TYPE = "SunX509"; //Default Key Manager Type - private static final String TRUST_MANAGER_TYPE = "SunX509"; //Default Trust Manager Type - private static final String SSLV3 = "SSLv3"; - private static final String DEFAULT_STREAM_VERSION = "1.0.0"; private static final String DEFAULT_EVENT_STORE_NAME = "EVENT_STORE"; private static final String DEFAULT_WEBSOCKET_PUBLISHER_ADAPTER_TYPE = "secured-websocket"; private static final String OAUTH_MQTT_ADAPTER_TYPE = "oauth-mqtt"; - private static final String OAUTH_HTTP_ADAPTER_TYPE = "oauth-http"; + private static final String THRIFT_ADAPTER_TYPE = "iot-event"; private static final String DEFAULT_DEVICE_ID_ATTRIBUTE = "deviceId"; private static final String DEFAULT_META_DEVICE_ID_ATTRIBUTE = "meta_deviceId"; - private static KeyStore keyStore; - private static KeyStore trustStore; - private static char[] keyStorePassword; - private static SSLContext sslContext; - static { - String keyStorePassword = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Password"); - String trustStorePassword = ServerConfiguration.getInstance().getFirstProperty( - "Security.TrustStore.Password"); - String keyStoreLocation = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Location"); - String trustStoreLocation = ServerConfiguration.getInstance().getFirstProperty( - "Security.TrustStore.Location"); - - //Call to load the keystore. - try { - loadKeyStore(keyStoreLocation, keyStorePassword); - //Call to load the TrustStore. - loadTrustStore(trustStoreLocation, trustStorePassword); - //Create the SSL context with the loaded TrustStore/keystore. - initSSLConnection(); - } catch (KeyStoreException | IOException | CertificateException | NoSuchAlgorithmException - | UnrecoverableKeyException | KeyManagementException e) { - log.error("publishing dynamic event receiver is failed due to " + e.getMessage(), e); - } - } @GET @Path("/{type}") @@ -153,13 +98,14 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe log.error(errorMessage); return Response.status(Response.Status.BAD_REQUEST).build(); } - String streamName = getStreamDefinition(deviceType, tenantDomain); - eventStreamAdminServiceStub = getEventStreamAdminServiceStub(); + String streamName = DeviceMgtAPIUtils.getStreamDefinition(deviceType, tenantDomain); + eventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub(); EventStreamDefinitionDto eventStreamDefinitionDto = eventStreamAdminServiceStub.getStreamDefinitionDto( - streamName + ":" + DEFAULT_STREAM_VERSION); + streamName + ":" + Constants.DEFAULT_STREAM_VERSION); if (eventStreamDefinitionDto == null) { return Response.status(Response.Status.NO_CONTENT).build(); } + EventStreamAttributeDto[] eventStreamAttributeDtos = eventStreamDefinitionDto.getPayloadData(); EventAttributeList eventAttributeList = new EventAttributeList(); List attributes = new ArrayList<>(); @@ -168,10 +114,11 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe , AttributeType.valueOf(eventStreamAttributeDto.getAttributeType().toUpperCase()))); } eventAttributeList.setList(attributes); + DeviceTypeEvent deviceTypeEvent = new DeviceTypeEvent(); deviceTypeEvent.setEventAttributeList(eventAttributeList); deviceTypeEvent.setTransportType(TransportType.HTTP); - eventReceiverAdminServiceStub = getEventReceiverAdminServiceStub(); + eventReceiverAdminServiceStub = DeviceMgtAPIUtils.getEventReceiverAdminServiceStub(); EventReceiverConfigurationDto eventReceiverConfigurationDto = eventReceiverAdminServiceStub .getActiveEventReceiverConfiguration(getReceiverName(deviceType, tenantDomain)); if (eventReceiverConfigurationDto != null) { @@ -224,21 +171,27 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe return Response.status(Response.Status.BAD_REQUEST).build(); } String eventReceiverName = getReceiverName(deviceType, tenantDomain); - String streamName = getStreamDefinition(deviceType, tenantDomain); - String streamNameWithVersion = streamName + ":" + DEFAULT_STREAM_VERSION; - publishStreamDefinitons(streamName, DEFAULT_STREAM_VERSION, deviceType, eventAttributes); + String streamName = DeviceMgtAPIUtils.getStreamDefinition(deviceType, tenantDomain); + String streamNameWithVersion = streamName + ":" + Constants.DEFAULT_STREAM_VERSION; + publishStreamDefinitons(streamName, Constants.DEFAULT_STREAM_VERSION, deviceType, eventAttributes); publishEventReceivers(eventReceiverName, streamNameWithVersion, transportType, tenantDomain, deviceType); - publishEventStore(streamName, DEFAULT_STREAM_VERSION, eventAttributes); + publishEventStore(streamName, Constants.DEFAULT_STREAM_VERSION, eventAttributes); publishWebsocketPublisherDefinition(streamNameWithVersion, deviceType); superTenantMode = true; PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain( MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true); if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { - publishStreamDefinitons(streamName, DEFAULT_STREAM_VERSION, deviceType, eventAttributes); - publishEventReceivers(eventReceiverName, streamNameWithVersion, transportType, tenantDomain, - deviceType); + if (transportType == TransportType.MQTT) { + publishStreamDefinitons(streamName, Constants.DEFAULT_STREAM_VERSION, deviceType, eventAttributes); + publishEventReceivers(eventReceiverName, streamNameWithVersion, transportType, tenantDomain, + deviceType); + } else { + publishStreamDefinitons(streamName, Constants.DEFAULT_STREAM_VERSION, deviceType, eventAttributes); + } + } + DeviceMgtAPIUtils.getDynamicEventCache().remove(deviceType); return Response.ok().build(); } catch (AxisFault e) { log.error("failed to create event definitions for tenantDomain:" + tenantDomain, e); @@ -286,22 +239,22 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe } String eventReceiverName = getReceiverName(deviceType, tenantDomain); String eventPublisherName = deviceType.trim().replace(" ", "_") + "_websocket_publisher"; - String streamName = getStreamDefinition(deviceType, tenantDomain); - eventStreamAdminServiceStub = getEventStreamAdminServiceStub(); - if (eventStreamAdminServiceStub.getStreamDefinitionDto(streamName + ":" + DEFAULT_STREAM_VERSION) == null) { + String streamName = DeviceMgtAPIUtils.getStreamDefinition(deviceType, tenantDomain); + eventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub(); + if (eventStreamAdminServiceStub.getStreamDefinitionDto(streamName + ":" + Constants.DEFAULT_STREAM_VERSION) == null) { return Response.status(Response.Status.NO_CONTENT).build(); } - eventStreamAdminServiceStub.removeEventStreamDefinition(streamName, DEFAULT_STREAM_VERSION); + eventStreamAdminServiceStub.removeEventStreamDefinition(streamName, Constants.DEFAULT_STREAM_VERSION); EventReceiverAdminServiceCallbackHandler eventReceiverAdminServiceCallbackHandler = new EventReceiverAdminServiceCallbackHandler() {}; EventPublisherAdminServiceCallbackHandler eventPublisherAdminServiceCallbackHandler = new EventPublisherAdminServiceCallbackHandler() {}; - eventReceiverAdminServiceStub = getEventReceiverAdminServiceStub(); + eventReceiverAdminServiceStub = DeviceMgtAPIUtils.getEventReceiverAdminServiceStub(); eventReceiverAdminServiceStub.startundeployInactiveEventReceiverConfiguration(eventReceiverName , eventReceiverAdminServiceCallbackHandler); - eventPublisherAdminServiceStub = getEventPublisherAdminServiceStub(); + eventPublisherAdminServiceStub = DeviceMgtAPIUtils.getEventPublisherAdminServiceStub(); eventPublisherAdminServiceStub.startundeployInactiveEventPublisherConfiguration(eventPublisherName , eventPublisherAdminServiceCallbackHandler); @@ -310,9 +263,9 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain( MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true); if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { - tenantBasedEventReceiverAdminServiceStub = getEventReceiverAdminServiceStub(); - tenantBasedEventStreamAdminServiceStub = getEventStreamAdminServiceStub(); - tenantBasedEventStreamAdminServiceStub.removeEventStreamDefinition(streamName, DEFAULT_STREAM_VERSION); + tenantBasedEventReceiverAdminServiceStub = DeviceMgtAPIUtils.getEventReceiverAdminServiceStub(); + tenantBasedEventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub(); + tenantBasedEventStreamAdminServiceStub.removeEventStreamDefinition(streamName, Constants.DEFAULT_STREAM_VERSION); tenantBasedEventReceiverAdminServiceStub.startundeployInactiveEventReceiverConfiguration( eventReceiverName , eventReceiverAdminServiceCallbackHandler); @@ -363,7 +316,7 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe String query = DEFAULT_META_DEVICE_ID_ATTRIBUTE + ":" + deviceId + " AND _timestamp : [" + fromDate + " TO " + toDate + "]"; String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - String sensorTableName = getTableName(getStreamDefinition(deviceType, tenantDomain)); + String sensorTableName = getTableName(DeviceMgtAPIUtils.getStreamDefinition(deviceType, tenantDomain)); try { if (deviceType == null || !DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(deviceType)) { @@ -400,7 +353,7 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe public Response getLastKnownData(@PathParam("deviceId") String deviceId, @PathParam("type") String deviceType) { String query = DEFAULT_META_DEVICE_ID_ATTRIBUTE + ":" + deviceId; String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - String sensorTableName = getTableName(getStreamDefinition(deviceType, tenantDomain)); + String sensorTableName = getTableName(DeviceMgtAPIUtils.getStreamDefinition(deviceType, tenantDomain)); try { if (deviceType == null || !DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(deviceType)) { @@ -432,10 +385,10 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe } private void publishEventReceivers(String eventRecieverName, String streamNameWithVersion, - TransportType transportType - , String requestedTenantDomain, String deviceType) + TransportType transportType, String requestedTenantDomain, + String deviceType) throws RemoteException, UserStoreException, JWTClientException { - EventReceiverAdminServiceStub receiverAdminServiceStub = getEventReceiverAdminServiceStub(); + EventReceiverAdminServiceStub receiverAdminServiceStub = DeviceMgtAPIUtils.getEventReceiverAdminServiceStub(); try { EventReceiverConfigurationDto eventReceiverConfigurationDto = receiverAdminServiceStub .getActiveEventReceiverConfiguration(getReceiverName(deviceType, requestedTenantDomain)); @@ -447,7 +400,7 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe return; } - } else if (OAUTH_HTTP_ADAPTER_TYPE.equals(eventAdapterType)) { + } else if (THRIFT_ADAPTER_TYPE.equals(eventAdapterType)) { if (transportType == TransportType.HTTP) { return; } @@ -459,20 +412,24 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe String adapterType = OAUTH_MQTT_ADAPTER_TYPE; BasicInputAdapterPropertyDto basicInputAdapterPropertyDtos[]; if (transportType == TransportType.MQTT) { - basicInputAdapterPropertyDtos = new BasicInputAdapterPropertyDto[4]; + basicInputAdapterPropertyDtos = new BasicInputAdapterPropertyDto[1]; basicInputAdapterPropertyDtos[0] = getBasicInputAdapterPropertyDto("topic", requestedTenantDomain + "/" + deviceType + "/+/events"); - basicInputAdapterPropertyDtos[1] = getBasicInputAdapterPropertyDto("contentValidator", "iot-mqtt"); - basicInputAdapterPropertyDtos[2] = getBasicInputAdapterPropertyDto("cleanSession", "true"); - basicInputAdapterPropertyDtos[3] = getBasicInputAdapterPropertyDto("clientId", generateUUID()); } else { - adapterType = OAUTH_HTTP_ADAPTER_TYPE; + adapterType = THRIFT_ADAPTER_TYPE; basicInputAdapterPropertyDtos = new BasicInputAdapterPropertyDto[1]; - basicInputAdapterPropertyDtos[0] = getBasicInputAdapterPropertyDto("contentValidator", "iot-http"); + basicInputAdapterPropertyDtos[0] = getBasicInputAdapterPropertyDto("events.duplicated.in.cluster", "false"); } if (receiverAdminServiceStub.getActiveEventReceiverConfiguration(eventRecieverName) == null) { - receiverAdminServiceStub.deployJsonEventReceiverConfiguration(eventRecieverName, streamNameWithVersion - , adapterType, null, basicInputAdapterPropertyDtos, false); + if (transportType == TransportType.MQTT) { + receiverAdminServiceStub.deployJsonEventReceiverConfiguration(eventRecieverName, streamNameWithVersion + , adapterType, null, basicInputAdapterPropertyDtos, false); + } else { + EventMappingPropertyDto eventMappingPropertyDto = new EventMappingPropertyDto(); + + receiverAdminServiceStub.deployWso2EventReceiverConfiguration(eventRecieverName, streamNameWithVersion + , adapterType, null, null, null, basicInputAdapterPropertyDtos, false, null); + } } } finally { cleanup(receiverAdminServiceStub); @@ -482,7 +439,7 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe private void publishStreamDefinitons(String streamName, String version, String deviceType , EventAttributeList eventAttributes) throws RemoteException, UserStoreException, JWTClientException { - EventStreamAdminServiceStub eventStreamAdminServiceStub = getEventStreamAdminServiceStub(); + EventStreamAdminServiceStub eventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub(); try { EventStreamDefinitionDto eventStreamDefinitionDto = new EventStreamDefinitionDto(); eventStreamDefinitionDto.setName(streamName); @@ -521,7 +478,7 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe throws RemoteException, UserStoreException, JWTClientException, EventStreamPersistenceAdminServiceEventStreamPersistenceAdminServiceExceptionException { EventStreamPersistenceAdminServiceStub eventStreamPersistenceAdminServiceStub = - getEventStreamPersistenceAdminServiceStub(); + DeviceMgtAPIUtils.getEventStreamPersistenceAdminServiceStub(); try { AnalyticsTable analyticsTable = new AnalyticsTable(); analyticsTable.setRecordStoreName(DEFAULT_EVENT_STORE_NAME); @@ -561,7 +518,8 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe private void publishWebsocketPublisherDefinition(String streamNameWithVersion, String deviceType) throws RemoteException, UserStoreException, JWTClientException { - EventPublisherAdminServiceStub eventPublisherAdminServiceStub = getEventPublisherAdminServiceStub(); + EventPublisherAdminServiceStub eventPublisherAdminServiceStub = DeviceMgtAPIUtils + .getEventPublisherAdminServiceStub(); try { String eventPublisherName = deviceType.trim().replace(" ", "_") + "_websocket_publisher"; if (eventPublisherAdminServiceStub.getActiveEventPublisherConfiguration(eventPublisherName) == null) { @@ -574,188 +532,6 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe } } - private EventStreamAdminServiceStub getEventStreamAdminServiceStub() - throws AxisFault, UserStoreException, JWTClientException { - EventStreamAdminServiceStub eventStreamAdminServiceStub = new EventStreamAdminServiceStub( - Utils.replaceSystemProperty(DAS_ADMIN_SERVICE_EP + EVENT_STREAM_CONTEXT)); - Options streamOptions = eventStreamAdminServiceStub._getServiceClient().getOptions(); - if (streamOptions == null) { - streamOptions = new Options(); - } - String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() - .getRealmConfiguration().getAdminUserName() + "@" + tenantDomain; - JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient(); - - String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64( - jwtClient.getJwtToken(username).getBytes())); - - List
list = new ArrayList<>(); - Header httpHeader = new Header(); - httpHeader.setName(AUTHORIZATION_HEADER); - httpHeader.setValue(authValue); - list.add(httpHeader);//"https" - streamOptions.setProperty(HTTPConstants.HTTP_HEADERS, list); - streamOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER - , new Protocol(DEFAULT_HTTP_PROTOCOL - , (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext) - , Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT)))); - eventStreamAdminServiceStub._getServiceClient().setOptions(streamOptions); - return eventStreamAdminServiceStub; - } - - private EventReceiverAdminServiceStub getEventReceiverAdminServiceStub() - throws AxisFault, UserStoreException, JWTClientException { - EventReceiverAdminServiceStub receiverAdminServiceStub = new EventReceiverAdminServiceStub( - Utils.replaceSystemProperty(DAS_ADMIN_SERVICE_EP + EVENT_RECIEVER_CONTEXT)); - Options eventReciverOptions = receiverAdminServiceStub._getServiceClient().getOptions(); - if (eventReciverOptions == null) { - eventReciverOptions = new Options(); - } - String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() - .getRealmConfiguration().getAdminUserName() + "@" + tenantDomain; - JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient(); - - String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64( - jwtClient.getJwtToken(username).getBytes())); - - List
list = new ArrayList<>(); - Header httpHeader = new Header(); - httpHeader.setName(AUTHORIZATION_HEADER); - httpHeader.setValue(authValue); - list.add(httpHeader);//"https" - - eventReciverOptions.setProperty(HTTPConstants.HTTP_HEADERS, list); - eventReciverOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER - , new Protocol(DEFAULT_HTTP_PROTOCOL - , (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext) - , Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT)))); - receiverAdminServiceStub._getServiceClient().setOptions(eventReciverOptions); - return receiverAdminServiceStub; - } - - private EventPublisherAdminServiceStub getEventPublisherAdminServiceStub() - throws AxisFault, UserStoreException, JWTClientException { - EventPublisherAdminServiceStub eventPublisherAdminServiceStub = new EventPublisherAdminServiceStub( - Utils.replaceSystemProperty(DAS_ADMIN_SERVICE_EP + EVENT_PUBLISHER_CONTEXT)); - Options eventReciverOptions = eventPublisherAdminServiceStub._getServiceClient().getOptions(); - if (eventReciverOptions == null) { - eventReciverOptions = new Options(); - } - String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() - .getRealmConfiguration().getAdminUserName() + "@" + tenantDomain; - JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient(); - - String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64( - jwtClient.getJwtToken(username).getBytes())); - - List
list = new ArrayList<>(); - Header httpHeader = new Header(); - httpHeader.setName(AUTHORIZATION_HEADER); - httpHeader.setValue(authValue); - list.add(httpHeader);//"https" - - eventReciverOptions.setProperty(HTTPConstants.HTTP_HEADERS, list); - eventReciverOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER - , new Protocol(DEFAULT_HTTP_PROTOCOL - , (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext) - , Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT)))); - eventPublisherAdminServiceStub._getServiceClient().setOptions(eventReciverOptions); - return eventPublisherAdminServiceStub; - } - - private EventStreamPersistenceAdminServiceStub getEventStreamPersistenceAdminServiceStub() - throws AxisFault, UserStoreException, JWTClientException { - EventStreamPersistenceAdminServiceStub eventStreamPersistenceAdminServiceStub - = new EventStreamPersistenceAdminServiceStub( - Utils.replaceSystemProperty(DAS_ADMIN_SERVICE_EP + EVENT_PERSISTENCE_CONTEXT)); - Options eventReciverOptions = eventStreamPersistenceAdminServiceStub._getServiceClient().getOptions(); - if (eventReciverOptions == null) { - eventReciverOptions = new Options(); - } - String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); - String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() - .getRealmConfiguration().getAdminUserName() + "@" + tenantDomain; - JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient(); - - String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64( - jwtClient.getJwtToken(username).getBytes())); - - List
list = new ArrayList<>(); - Header httpHeader = new Header(); - httpHeader.setName(AUTHORIZATION_HEADER); - httpHeader.setValue(authValue); - list.add(httpHeader);//"https" - - eventReciverOptions.setProperty(HTTPConstants.HTTP_HEADERS, list); - eventReciverOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER - , new Protocol(DEFAULT_HTTP_PROTOCOL - , (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext) - , Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT)))); - eventStreamPersistenceAdminServiceStub._getServiceClient().setOptions(eventReciverOptions); - return eventStreamPersistenceAdminServiceStub; - } - - /** - * Loads the keystore. - * - * @param keyStorePath - the path of the keystore - * @param ksPassword - the keystore password - */ - private static void loadKeyStore(String keyStorePath, String ksPassword) - throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException { - InputStream fis = null; - try { - keyStorePassword = ksPassword.toCharArray(); - keyStore = KeyStore.getInstance(KEY_STORE_TYPE); - fis = new FileInputStream(keyStorePath); - keyStore.load(fis, keyStorePassword); - } finally { - if (fis != null) { - fis.close(); - } - } - } - - /** - * Loads the trustore - * - * @param trustStorePath - the trustore path in the filesystem. - * @param tsPassword - the truststore password - */ - private static void loadTrustStore(String trustStorePath, String tsPassword) - throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException { - - InputStream fis = null; - try { - trustStore = KeyStore.getInstance(TRUST_STORE_TYPE); - fis = new FileInputStream(trustStorePath); - trustStore.load(fis, tsPassword.toCharArray()); - } finally { - if (fis != null) { - fis.close(); - } - } - } - - /** - * Initializes the SSL Context - */ - private static void initSSLConnection() throws NoSuchAlgorithmException, UnrecoverableKeyException, - KeyStoreException, KeyManagementException { - KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KEY_MANAGER_TYPE); - keyManagerFactory.init(keyStore, keyStorePassword); - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TRUST_MANAGER_TYPE); - trustManagerFactory.init(trustStore); - - // Create and initialize SSLContext for HTTPS communication - sslContext = SSLContext.getInstance(SSLV3); - sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); - SSLContext.setDefault(sslContext); - } - private BasicInputAdapterPropertyDto getBasicInputAdapterPropertyDto(String key, String value) { BasicInputAdapterPropertyDto basicInputAdapterPropertyDto = new BasicInputAdapterPropertyDto(); basicInputAdapterPropertyDto.setKey(key); @@ -769,10 +545,6 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe return Long.toString(l, Character.MAX_RADIX); } - private String getStreamDefinition(String deviceType, String tenantDomain) { - return "iot.per.device.stream." + tenantDomain + "." + deviceType.replace(" ", "."); - } - private String getTableName(String streamName) { return streamName.toUpperCase().replace('.', '_'); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java index 0ae988be45..dfe0432a85 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -89,38 +89,6 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { private static final Log log = LogFactory.getLog(DeviceManagementServiceImpl.class); - @POST - @Override - public Response enrollDevice(@Valid Device device) { - if (device == null) { - String errorMessage = "The payload of the device enrollment is incorrect."; - return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build(); - } - try { - DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); - if (device.getType() == null || device.getDeviceIdentifier() == null) { - String errorMessage = "The payload of the device enrollment is incorrect."; - return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build(); - } - Device existingDevice = dms.getDevice(new DeviceIdentifier(device.getType(), device.getType())); - if (existingDevice != null && existingDevice.getEnrolmentInfo() != null && existingDevice - .getEnrolmentInfo().getStatus().equals(EnrolmentInfo.Status.ACTIVE)) { - String errorMessage = "An active enrolment exists"; - return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build(); - } - device.getEnrolmentInfo().setOwner(DeviceMgtAPIUtils.getAuthenticatedUser()); - device.getEnrolmentInfo().setDateOfEnrolment(System.currentTimeMillis()); - device.getEnrolmentInfo().setDateOfLastUpdate(System.currentTimeMillis()); - boolean status = dms.enrollDevice(device); - return Response.status(Response.Status.OK).entity(status).build(); - } catch (DeviceManagementException e) { - String msg = "Error occurred while enrolling the android, which carries the id '" + - device.getDeviceIdentifier() + "'"; - log.error(msg, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); - } - } - @GET @Path("/{type}/{id}/status") @Override @@ -141,87 +109,6 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { } } - @PUT - @Path("/{type}/{id}") - @Override - public Response updateDevice(@PathParam("type") String type, @PathParam("id") String id, @Valid Device updateDevice) { - Device device; - DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); - deviceIdentifier.setId(id); - deviceIdentifier.setType(type); - try { - device = DeviceMgtAPIUtils.getDeviceManagementService().getDevice(deviceIdentifier); - } catch (DeviceManagementException e) { - String msg = "Error occurred while getting enrollment details of the Android device that carries the id '" + - id + "'"; - log.error(msg, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); - } - - if (updateDevice == null) { - String errorMessage = "The payload of the device enrollment is incorrect."; - log.error(errorMessage); - return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build(); - } - if (device == null) { - String errorMessage = "The device to be modified doesn't exist."; - log.error(errorMessage); - return Response.status(Response.Status.NOT_FOUND).entity(errorMessage).build(); - } - if (device.getEnrolmentInfo().getStatus() == EnrolmentInfo.Status.ACTIVE ) { - DeviceAccessAuthorizationService deviceAccessAuthorizationService = - DeviceMgtAPIUtils.getDeviceAccessAuthorizationService(); - boolean status = false; - try { - status = deviceAccessAuthorizationService.isUserAuthorized(new DeviceIdentifier(id, type)); - } catch (DeviceAccessAuthorizationException e) { - String msg = "Error occurred while modifying enrollment of the Android device that carries the id '" + - id + "'"; - log.error(msg, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); - } - if (!status) { - return Response.status(Response.Status.UNAUTHORIZED).build(); - } - } - if(updateDevice.getEnrolmentInfo() != null) { - device.getEnrolmentInfo().setDateOfLastUpdate(System.currentTimeMillis()); - device.setEnrolmentInfo(device.getEnrolmentInfo()); - } - device.getEnrolmentInfo().setOwner(DeviceMgtAPIUtils.getAuthenticatedUser()); - if(updateDevice.getDeviceInfo() != null) { - device.setDeviceInfo(updateDevice.getDeviceInfo()); - } - device.setDeviceIdentifier(id); - if(updateDevice.getDescription() != null) { - device.setDescription(updateDevice.getDescription()); - } - if(updateDevice.getName() != null) { - device.setName(updateDevice.getName()); - } - if(updateDevice.getFeatures() != null) { - device.setFeatures(updateDevice.getFeatures()); - } - if(updateDevice.getProperties() != null) { - device.setProperties(updateDevice.getProperties()); - } - boolean result; - try { - device.setType(type); - result = DeviceMgtAPIUtils.getDeviceManagementService().modifyEnrollment(device); - if (result) { - return Response.status(Response.Status.ACCEPTED).build(); - } else { - return Response.status(Response.Status.NOT_MODIFIED).build(); - } - } catch (DeviceManagementException e) { - String msg = "Error occurred while modifying enrollment of the Android device that carries the id '" + - id + "'"; - log.error(msg, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); - } - } - @GET @Override public Response getDevices( @@ -787,122 +674,4 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); } } - - @GET - @Path("/{type}/{id}/pending/operations") - public Response getPendingOperations(@PathParam("type") String type, @PathParam("id") String deviceId) { - try { - if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { - String errorMessage = "Device identifier list is empty"; - log.error(errorMessage); - return Response.status(Response.Status.BAD_REQUEST).build(); - } - List operations = DeviceMgtAPIUtils.getDeviceManagementService().getPendingOperations( - new DeviceIdentifier(deviceId, type)); - OperationList operationsList = new OperationList(); - operationsList.setList(operations); - operationsList.setCount(operations.size()); - return Response.status(Response.Status.OK).entity(operationsList).build(); - } catch (OperationManagementException e) { - String errorMessage = "Issue in retrieving operation management service instance"; - log.error(errorMessage, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); - } catch (DeviceManagementException e) { - String errorMessage = "Issue in retrieving deivce management service instance"; - log.error(errorMessage, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); - } - } - - @GET - @Path("/{type}/{id}/last-pending/operation") - public Response getNextPendingOperation(@PathParam("type") String type, @PathParam("id") String deviceId) { - try { - if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { - String errorMessage = "Device identifier list is empty"; - log.error(errorMessage); - return Response.status(Response.Status.BAD_REQUEST).build(); - } - Operation operation = DeviceMgtAPIUtils.getDeviceManagementService().getNextPendingOperation( - new DeviceIdentifier(deviceId, type)); - return Response.status(Response.Status.OK).entity(operation).build(); - } catch (OperationManagementException e) { - String errorMessage = "Issue in retrieving operation management service instance"; - log.error(errorMessage, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); - } catch (DeviceManagementException e) { - String errorMessage = "Issue in retrieving deivce management service instance"; - log.error(errorMessage, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); - } - } - - @PUT - @Path("/{type}/{id}/operations") - public Response updateOperation(@PathParam("type") String type, @PathParam("id") String deviceId, @Valid Operation operation) { - try { - if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { - String errorMessage = "Device identifier list is empty"; - log.error(errorMessage); - return Response.status(Response.Status.BAD_REQUEST).build(); - } - if (operation == null) { - String errorMessage = "Device identifier list is empty"; - log.error(errorMessage); - return Response.status(Response.Status.BAD_REQUEST).build(); - } - DeviceMgtAPIUtils.getDeviceManagementService().updateOperation - (new DeviceIdentifier(deviceId, type), operation); - return Response.status(Response.Status.ACCEPTED).build(); - } catch (OperationManagementException e) { - String errorMessage = "Issue in retrieving operation management service instance"; - log.error(errorMessage, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); - } catch (DeviceManagementException e) { - String errorMessage = "Issue in retrieving deivce management service instance"; - log.error(errorMessage, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); - } - } - - @GET - @Path("/{type}/{id}/status/operations") - public Response getOperationsByDeviceAndStatus(@PathParam("type") String type, @PathParam("id") String deviceId, - @QueryParam("status")Operation.Status status) { - if (status == null) { - String errorMessage = "status is empty"; - log.error(errorMessage); - return Response.status(Response.Status.BAD_REQUEST).build(); - } - - try { - if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { - String errorMessage = "Device identifier list is empty"; - log.error(errorMessage); - return Response.status(Response.Status.BAD_REQUEST).build(); - } - List operations = DeviceMgtAPIUtils.getDeviceManagementService() - .getOperationsByDeviceAndStatus(new DeviceIdentifier(deviceId, type), status); - OperationList operationsList = new OperationList(); - operationsList.setList(operations); - operationsList.setCount(operations.size()); - return Response.status(Response.Status.OK).entity(operationsList).build(); - } catch (OperationManagementException e) { - String errorMessage = "Issue in retrieving operation management service instance"; - log.error(errorMessage, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); - } catch (DeviceManagementException e) { - String errorMessage = "Issue in retrieving device management service"; - log.error(errorMessage, e); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); - } - } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/Constants.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/Constants.java index c5fa21ae89..952f55fceb 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/Constants.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/Constants.java @@ -27,8 +27,10 @@ public class Constants { public static final String USER_CLAIM_FIRST_NAME = "http://wso2.org/claims/givenname"; public static final String USER_CLAIM_LAST_NAME = "http://wso2.org/claims/lastname"; public static final String PRIMARY_USER_STORE = "PRIMARY"; + public static final String DEFAULT_STREAM_VERSION = "1.0.0"; public static final String SCOPE = "scope"; + public final class ErrorMessages { private ErrorMessages () { throw new AssertionError(); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java index 888b1c42ee..90814865da 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java @@ -18,12 +18,27 @@ package org.wso2.carbon.device.mgt.jaxrs.util; +import org.apache.axis2.AxisFault; +import org.apache.axis2.client.Options; +import org.apache.axis2.java.security.SSLProtocolSocketFactory; +import org.apache.axis2.transport.http.HTTPConstants; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.analytics.stream.persistence.stub.EventStreamPersistenceAdminServiceStub; +import org.wso2.carbon.base.ServerConfiguration; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.core.util.Utils; import org.wso2.carbon.device.mgt.analytics.dashboard.GadgetDataService; +import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; @@ -35,7 +50,13 @@ import org.wso2.carbon.device.mgt.core.search.mgt.SearchManagerService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService; import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.EventAttributeList; import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.InputValidationException; +import org.wso2.carbon.event.publisher.stub.EventPublisherAdminServiceStub; +import org.wso2.carbon.event.receiver.stub.EventReceiverAdminServiceStub; +import org.wso2.carbon.event.stream.stub.EventStreamAdminServiceStub; +import org.wso2.carbon.identity.jwt.client.extension.JWTClient; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; import org.wso2.carbon.identity.user.store.count.AbstractCountRetrieverFactory; import org.wso2.carbon.identity.user.store.count.UserStoreCountRetriever; @@ -54,7 +75,22 @@ import org.wso2.carbon.user.api.UserStoreManager; import org.wso2.carbon.user.core.jdbc.JDBCUserStoreManager; import org.wso2.carbon.user.core.service.RealmService; +import javax.cache.Cache; +import javax.cache.Caching; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; import javax.ws.rs.core.MediaType; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.util.ArrayList; import java.util.List; /** @@ -64,7 +100,51 @@ public class DeviceMgtAPIUtils { public static final MediaType DEFAULT_CONTENT_TYPE = MediaType.APPLICATION_JSON_TYPE; private static final String NOTIFIER_FREQUENCY = "notifierFrequency"; + private static final String STREAM_DEFINITION_PREFIX = "iot.per.device.stream."; + private static final String DEFAULT_HTTP_PROTOCOL = "https"; + private static final String EVENT_RECIEVER_CONTEXT = "EventReceiverAdminService/"; + private static final String EVENT_PUBLISHER_CONTEXT = "EventPublisherAdminService/"; + private static final String EVENT_STREAM_CONTEXT = "EventStreamAdminService/"; + private static final String EVENT_PERSISTENCE_CONTEXT = "EventStreamPersistenceAdminService/"; + private static final String AUTHORIZATION_HEADER = "Authorization"; + private static final String AUTHORIZATION_HEADER_VALUE = "Bearer"; + public static final String DAS_PORT = "${iot.analytics.https.port}"; + public static final String DAS_HOST_NAME = "${iot.analytics.host}"; + private static final String KEY_STORE_TYPE = "JKS"; + private static final String TRUST_STORE_TYPE = "JKS"; + private static final String KEY_MANAGER_TYPE = "SunX509"; //Default Key Manager Type + private static final String TRUST_MANAGER_TYPE = "SunX509"; //Default Trust Manager Type + private static final String SSLV3 = "SSLv3"; + private static final String EVENT_CACHE_MANAGER_NAME = "mqttAuthorizationCacheManager"; + private static final String EVENT_CACHE_NAME = "mqttAuthorizationCache"; + public static final String DAS_ADMIN_SERVICE_EP = "https://" + DAS_HOST_NAME + ":" + DAS_PORT + "/services/"; + private static SSLContext sslContext; + private static Log log = LogFactory.getLog(DeviceMgtAPIUtils.class); + private static KeyStore keyStore; + private static KeyStore trustStore; + private static char[] keyStorePassword; + + static { + String keyStorePassword = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Password"); + String trustStorePassword = ServerConfiguration.getInstance().getFirstProperty( + "Security.TrustStore.Password"); + String keyStoreLocation = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Location"); + String trustStoreLocation = ServerConfiguration.getInstance().getFirstProperty( + "Security.TrustStore.Location"); + + //Call to load the keystore. + try { + loadKeyStore(keyStoreLocation, keyStorePassword); + //Call to load the TrustStore. + loadTrustStore(trustStoreLocation, trustStorePassword); + //Create the SSL context with the loaded TrustStore/keystore. + initSSLConnection(); + } catch (KeyStoreException | IOException | CertificateException | NoSuchAlgorithmException + | UnrecoverableKeyException | KeyManagementException e) { + log.error("publishing dynamic event receiver is failed due to " + e.getMessage(), e); + } + } public static int getNotifierFrequency(PlatformConfiguration tenantConfiguration) { List configEntryList = tenantConfiguration.getConfiguration(); @@ -113,6 +193,18 @@ public class DeviceMgtAPIUtils { return deviceManagementProviderService; } + public static boolean isValidDeviceIdentifier(DeviceIdentifier deviceIdentifier) throws DeviceManagementException { + Device device = getDeviceManagementService().getDevice(deviceIdentifier); + if (device == null || device.getDeviceIdentifier() == null || + device.getDeviceIdentifier().isEmpty() || device.getEnrolmentInfo() == null) { + return false; + } else if (EnrolmentInfo.Status.REMOVED.equals(device.getEnrolmentInfo().getStatus())) { + return false; + } + return true; + } + + public static UserStoreCountRetriever getUserStoreCountRetrieverService() throws UserStoreCounterException { PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); @@ -344,4 +436,212 @@ public class DeviceMgtAPIUtils { return username; } + public static EventsPublisherService getEventPublisherService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + EventsPublisherService eventsPublisherService = + (EventsPublisherService) ctx.getOSGiService(EventsPublisherService.class, null); + if (eventsPublisherService == null) { + String msg = "Event Publisher service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return eventsPublisherService; + } + + public static String getStreamDefinition(String deviceType, String tenantDomain) { + return STREAM_DEFINITION_PREFIX + tenantDomain + "." + deviceType.replace(" ", "."); + } + + public static EventStreamAdminServiceStub getEventStreamAdminServiceStub() + throws AxisFault, UserStoreException, JWTClientException { + EventStreamAdminServiceStub eventStreamAdminServiceStub = new EventStreamAdminServiceStub( + Utils.replaceSystemProperty(DAS_ADMIN_SERVICE_EP + EVENT_STREAM_CONTEXT)); + Options streamOptions = eventStreamAdminServiceStub._getServiceClient().getOptions(); + if (streamOptions == null) { + streamOptions = new Options(); + } + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminUserName() + "@" + tenantDomain; + JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient(); + + String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64( + jwtClient.getJwtToken(username).getBytes())); + + List
list = new ArrayList<>(); + Header httpHeader = new Header(); + httpHeader.setName(AUTHORIZATION_HEADER); + httpHeader.setValue(authValue); + list.add(httpHeader);//"https" + streamOptions.setProperty(HTTPConstants.HTTP_HEADERS, list); + streamOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER + , new Protocol(DEFAULT_HTTP_PROTOCOL + , (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext) + , Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT)))); + eventStreamAdminServiceStub._getServiceClient().setOptions(streamOptions); + return eventStreamAdminServiceStub; + } + + public static EventReceiverAdminServiceStub getEventReceiverAdminServiceStub() + throws AxisFault, UserStoreException, JWTClientException { + EventReceiverAdminServiceStub receiverAdminServiceStub = new EventReceiverAdminServiceStub( + Utils.replaceSystemProperty(DAS_ADMIN_SERVICE_EP + EVENT_RECIEVER_CONTEXT)); + Options eventReciverOptions = receiverAdminServiceStub._getServiceClient().getOptions(); + if (eventReciverOptions == null) { + eventReciverOptions = new Options(); + } + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminUserName() + "@" + tenantDomain; + JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient(); + + String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64( + jwtClient.getJwtToken(username).getBytes())); + + List
list = new ArrayList<>(); + Header httpHeader = new Header(); + httpHeader.setName(AUTHORIZATION_HEADER); + httpHeader.setValue(authValue); + list.add(httpHeader);//"https" + + eventReciverOptions.setProperty(HTTPConstants.HTTP_HEADERS, list); + eventReciverOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER + , new Protocol(DEFAULT_HTTP_PROTOCOL + , (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext) + , Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT)))); + + receiverAdminServiceStub._getServiceClient().setOptions(eventReciverOptions); + return receiverAdminServiceStub; + } + + public static EventPublisherAdminServiceStub getEventPublisherAdminServiceStub() + throws AxisFault, UserStoreException, JWTClientException { + EventPublisherAdminServiceStub eventPublisherAdminServiceStub = new EventPublisherAdminServiceStub( + Utils.replaceSystemProperty(DAS_ADMIN_SERVICE_EP + EVENT_PUBLISHER_CONTEXT)); + Options eventReciverOptions = eventPublisherAdminServiceStub._getServiceClient().getOptions(); + if (eventReciverOptions == null) { + eventReciverOptions = new Options(); + } + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminUserName() + "@" + tenantDomain; + JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient(); + + String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64( + jwtClient.getJwtToken(username).getBytes())); + + List
list = new ArrayList<>(); + Header httpHeader = new Header(); + httpHeader.setName(AUTHORIZATION_HEADER); + httpHeader.setValue(authValue); + list.add(httpHeader);//"https" + + eventReciverOptions.setProperty(HTTPConstants.HTTP_HEADERS, list); + eventReciverOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER + , new Protocol(DEFAULT_HTTP_PROTOCOL + , (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext) + , Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT)))); + eventPublisherAdminServiceStub._getServiceClient().setOptions(eventReciverOptions); + return eventPublisherAdminServiceStub; + } + + public static EventStreamPersistenceAdminServiceStub getEventStreamPersistenceAdminServiceStub() + throws AxisFault, UserStoreException, JWTClientException { + EventStreamPersistenceAdminServiceStub eventStreamPersistenceAdminServiceStub + = new EventStreamPersistenceAdminServiceStub( + Utils.replaceSystemProperty(DAS_ADMIN_SERVICE_EP + EVENT_PERSISTENCE_CONTEXT)); + Options eventReciverOptions = eventStreamPersistenceAdminServiceStub._getServiceClient().getOptions(); + if (eventReciverOptions == null) { + eventReciverOptions = new Options(); + } + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminUserName() + "@" + tenantDomain; + JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient(); + + String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64( + jwtClient.getJwtToken(username).getBytes())); + + List
list = new ArrayList<>(); + Header httpHeader = new Header(); + httpHeader.setName(AUTHORIZATION_HEADER); + httpHeader.setValue(authValue); + list.add(httpHeader);//"https" + + eventReciverOptions.setProperty(HTTPConstants.HTTP_HEADERS, list); + eventReciverOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER + , new Protocol(DEFAULT_HTTP_PROTOCOL + , (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext) + , Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT)))); + + eventStreamPersistenceAdminServiceStub._getServiceClient().setOptions(eventReciverOptions); + return eventStreamPersistenceAdminServiceStub; + } + + /** + * This method is used to create the Cache that holds the event definition of the device type.. + * @return Cachemanager + */ + public static synchronized Cache getDynamicEventCache() { + return Caching.getCacheManagerFactory().getCacheManager(EVENT_CACHE_MANAGER_NAME).getCache(EVENT_CACHE_NAME); + } + + /** + * Loads the keystore. + * + * @param keyStorePath - the path of the keystore + * @param ksPassword - the keystore password + */ + private static void loadKeyStore(String keyStorePath, String ksPassword) + throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException { + InputStream fis = null; + try { + keyStorePassword = ksPassword.toCharArray(); + keyStore = KeyStore.getInstance(KEY_STORE_TYPE); + fis = new FileInputStream(keyStorePath); + keyStore.load(fis, keyStorePassword); + } finally { + if (fis != null) { + fis.close(); + } + } + } + + /** + * Loads the trustore + * + * @param trustStorePath - the trustore path in the filesystem. + * @param tsPassword - the truststore password + */ + private static void loadTrustStore(String trustStorePath, String tsPassword) + throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException { + + InputStream fis = null; + try { + trustStore = KeyStore.getInstance(TRUST_STORE_TYPE); + fis = new FileInputStream(trustStorePath); + trustStore.load(fis, tsPassword.toCharArray()); + } finally { + if (fis != null) { + fis.close(); + } + } + } + + /** + * Initializes the SSL Context + */ + private static void initSSLConnection() throws NoSuchAlgorithmException, UnrecoverableKeyException, + KeyStoreException, KeyManagementException { + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KEY_MANAGER_TYPE); + keyManagerFactory.init(keyStore, keyStorePassword); + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TRUST_MANAGER_TYPE); + trustManagerFactory.init(trustStore); + + // Create and initialize SSLContext for HTTPS communication + sslContext = SSLContext.getInstance(SSLV3); + sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); + SSLContext.setDefault(sslContext); + } + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml index 6fa36bfb92..8a6e6c2bd9 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -42,6 +42,7 @@ + @@ -86,6 +87,7 @@ + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypePluginDAOManager.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypePluginDAOManager.java index 563be5ce0b..6a4f0e0126 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypePluginDAOManager.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypePluginDAOManager.java @@ -19,13 +19,15 @@ package org.wso2.carbon.device.mgt.extensions.device.type.template.dao; +import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.extensions.device.type.template.config.DeviceDetails; +import org.wso2.carbon.utils.multitenancy.MultitenantConstants; public class DeviceTypePluginDAOManager { private PluginDAO deviceTypePluginDAO; private DeviceTypeDAOHandler deviceTypeDAOHandler; - private static String DEFAULT_DATASOURCE_NAME = "jdbc/DM_DS"; + private static final String DEFAULT_DATASOURCE_NAME = "jdbc/DM_DS"; public DeviceTypePluginDAOManager(String datasourceName, DeviceDAODefinition deviceDAODefinition) { deviceTypeDAOHandler = new DeviceTypeDAOHandler(datasourceName); @@ -33,7 +35,14 @@ public class DeviceTypePluginDAOManager { } public DeviceTypePluginDAOManager(String deviceType, DeviceDetails deviceDetails) { - deviceTypeDAOHandler = new DeviceTypeDAOHandler(DEFAULT_DATASOURCE_NAME); + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext() + .setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true); + try { + deviceTypeDAOHandler = new DeviceTypeDAOHandler(DEFAULT_DATASOURCE_NAME); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } deviceTypePluginDAO = new PropertyBasedPluginDAOImpl(deviceDetails, deviceTypeDAOHandler, deviceType); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/api/device-api.jag b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/api/device-api.jag index d59af12fe8..df5d11d01b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/api/device-api.jag +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/api/device-api.jag @@ -168,7 +168,6 @@ if (!user) { response.sendError(403); } } else if (uriMatcher.match("/{context}/api/devices/agent/{type}/{deviceId}/config")) { - log.error("matching"); elements = uriMatcher.elements(); deviceId = elements.deviceId; type = elements.type; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/conf/config.json b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/conf/config.json index 61dda23a3a..536724a040 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/conf/config.json +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/conf/config.json @@ -142,45 +142,12 @@ "perm:admin:certificates:view", "perm:admin:certificates:add", "perm:admin:certificates:verify", - "perm:ios:enroll", - "perm:ios:view-device", - "perm:ios:apn", - "perm:ios:ldap", - "perm:ios:enterprise-app", - "perm:ios:store-application", - "perm:ios:remove-application", - "perm:ios:app-list", - "perm:ios:profile-list", - "perm:ios:lock", - "perm:ios:enterprise-wipe", - "perm:ios:device-info", - "perm:ios:restriction", - "perm:ios:email", - "perm:ios:cellular", - "perm:ios:applications", - "perm:ios:wifi", - "perm:ios:ring", - "perm:ios:location", - "perm:ios:notification", - "perm:ios:airplay", - "perm:ios:caldav", - "perm:ios:cal-subscription", - "perm:ios:passcode-policy", - "perm:ios:webclip", - "perm:ios:vpn", - "perm:ios:per-app-vpn", - "perm:ios:app-to-per-app-vpn", - "perm:ios:app-lock", - "perm:ios:clear-passcode", - "perm:ios:remove-profile", - "perm:ios:get-restrictions", - "perm:ios:wipe-data", "perm:admin", "perm:devicetype:deployment", "perm:device-types:events", "perm:device-types:events:view", "perm:admin:device-type", - "perm:devices:add" + "perm:device:enroll" ], "isOAuthEnabled": true, "backendRestEndpoints": { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js index 7a792e2041..4067d09e94 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js @@ -369,7 +369,7 @@ deviceModule = function () { var applicationName = type.replace(" ", "") + "_" + carbonUser.domain; var requestURL = (devicemgtProps["oauthProvider"]["appRegistration"] ["apiManagerClientAppRegistrationServiceURL"]).replace("/tenants",""); - var payload = {applicationName:applicationName, tags:["device_management"], + var payload = {applicationName:applicationName, tags:["device_agent"], isAllowedToAllDomains:false, validityPeriod: 3600}; serviceInvokers.XMLHttp.post( @@ -386,7 +386,8 @@ deviceModule = function () { //noinspection JSUnresolvedFunction var jwtClient = JWTClientManagerService.getJWTClient(); // returning access token by JWT grant type - var deviceScope = "device_" + type.replace(" ", "") + "_" + deviceId; + var deviceScope = "device_" + type.replace(" ", "") + "_" + deviceId + " perm:device:enroll " + + "perm:device:disenroll perm:device:modify perm:devices:operations"; var tokenInfo = jwtClient.getAccessToken(config.clientId, config.clientSecret, userName, deviceScope); config.accessToken = tokenInfo.getAccessToken(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetypes/public/js/devicetype-listing.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetypes/public/js/devicetype-listing.js index 6d990d9a85..9cfe22481a 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetypes/public/js/devicetype-listing.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetypes/public/js/devicetype-listing.js @@ -135,7 +135,7 @@ function loadDeviceTypes() { class: "", data: "name", render: function (name, type, row, meta) { - return '

' + name.replace("devicemgt", ""); + '

'; + return '

' + name.replace("devicemgt", "") + '

'; } }, { @@ -189,7 +189,8 @@ function loadDeviceTypes() { var options = { "placeholder": "Search By Device Type Name", - "searchKey": "filter" + "searchKey": "filter", + "searching": false }; var settings = { "sorting": false diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.data-tables-extended/public/js/dataTables.extended.serversidepaging.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.data-tables-extended/public/js/dataTables.extended.serversidepaging.js index c3e8fd5d00..d793e6414b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.data-tables-extended/public/js/dataTables.extended.serversidepaging.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.data-tables-extended/public/js/dataTables.extended.serversidepaging.js @@ -50,6 +50,12 @@ $.fn.datatables_extended_serverside_paging = function (settings, url, dataFilter var deviceType; var ownership; + var searching = true; + if (options) { + if (typeof options.searching !== 'undefined') { + searching = options.searching; + } + } //--- End of EMM related codes @@ -57,7 +63,7 @@ $.fn.datatables_extended_serverside_paging = function (settings, url, dataFilter $.extend({}, { serverSide: true, processing: false, - searching: true, + searching: searching, ordering: false, filter: false, bSortCellsTop: true, diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.realtime.analytics-view/analytics-view.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.realtime.analytics-view/analytics-view.hbs index 485c91dcf7..6911c698fc 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.realtime.analytics-view/analytics-view.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.realtime.analytics-view/analytics-view.hbs @@ -24,7 +24,7 @@ {{#each events}} {{this.key}} - {{#if this.value}}{{this.value}}{{else}}-{{/if}} + {{this.value}} {{/each}} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.realtime.analytics-view/analytics-view.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.realtime.analytics-view/analytics-view.js index e11d700c79..6569d62711 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.realtime.analytics-view/analytics-view.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.realtime.analytics-view/analytics-view.js @@ -38,15 +38,19 @@ function onRequest(context) { if (encodedClientKeys) { var tokenUtil = require("/app/modules/oauth/token-handler-utils.js")["utils"]; var resp = tokenUtil.decode(encodedClientKeys).split(":"); - var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username,"default", {}); - if (tokenPair) { - token = tokenPair.accessToken; - } if (tenantDomain == "carbon.super") { + var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username,"default", {}); + if (tokenPair) { + token = tokenPair.accessToken; + } websocketEndpoint = websocketEndpoint + "/secured-websocket/iot.per.device.stream." + tenantDomain + "." + device.type + "/1.0.0?" + "deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type + "&websocketToken=" + token; } else { - websocketEndpoint = websocketEndpoint + "/t/" + tenantDomain + "/secured-websocket/iot.per.device.stream." + tenantDomain + var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username + "@" + tenantDomain,"default", {}); + if (tokenPair) { + token = tokenPair.accessToken; + } + websocketEndpoint = websocketEndpoint + "/secured-websocket" + "/t/" + tenantDomain + "/iot.per.device.stream." + tenantDomain + "." + device.type + "/1.0.0?" + "deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type + "&websocketToken=" + token; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/public/js/type-view.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/public/js/type-view.js index f5b93adcdc..e75441bc0f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/public/js/type-view.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/public/js/type-view.js @@ -427,7 +427,7 @@ $(document).ready(function () { device.properties.push(property); } }); - var addDeviceAPI = apiBasePath + "/devices"; + var addDeviceAPI = apiBasePath + "/device/agent/enroll"; invokerUtil.post( addDeviceAPI, @@ -438,7 +438,7 @@ $(document).ready(function () { type: "GET", url: "/devicemgt/api/devices/agent/" + deviceType + "/" + deviceId + "/config", success: function(data, status, xhr) { - var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(data)); + var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(data, null, 4)); var dlAnchorElem = document.getElementById('downloadAnchorElem'); dlAnchorElem.setAttribute("href", dataStr ); dlAnchorElem.setAttribute("download", deviceId + ".json"); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.hbs index b26f7c72f7..a152f16427 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.hbs @@ -18,7 +18,7 @@


- View API @@ -112,17 +112,17 @@
  • Generate Application

    - curl -k -X POST https://localhost:8243/api-application-registration/register -H + curl -k -X POST {{httpsGateway}}/api-application-registration/register -H 'authorization: Basic Base64(username:password)' -H 'content-type: application/json' - -d '{ "applicationName":"testme", "isAllowedToAllDomains":false, "tags":["device_management"]}' + -d '{ "applicationName":"testme", "isAllowedToAllDomains":false, "tags":["device_agent"]}'
  • Generate Token

    - curl -k -d "grant_type=password&username=%username%&password=%password%&scope=perm:devices:add" + curl -k -d "grant_type=password&username=%username%&password=%password%&scope=perm:device:enroll perm:device:disenroll perm:device:modify perm:devices:operations" -H "Authorization: Basic Base64(client_id:client_secret)" - -H "Content-Type: application/x-www-form-urlencoded" https://localhost:8243/token + -H "Content-Type: application/x-www-form-urlencoded" {{httpsGateway}}/token
  • Create Device

    - curl -X POST http://localhost:8280/api/device-mgt/v1.0/devices -H 'accept: application/json' + curl -X POST {{httpsGateway}}/api/device-mgt/v1.0/device/agent/enroll -H 'accept: application/json' -H 'authorization: Bearer %accessToken%' -H 'content-type: application/json' -d '{ "name": "devicename", "type": "{{deviceType}}", "description": "descritption", "deviceIdentifier": "1234", "enrolmentInfo": @@ -214,26 +214,32 @@

    Device Communication


    {{#if event}} -

    publish data for analytics :

    +

    publish device events :

    {{#if_eq event.transport "MQTT"}} MQTT Topic : {{tenantDomain}}/{{deviceType}}/<device_id>/events + {{#if eventSample}} +
    + Device Event Payload + {{eventSample}} +
    +
    +
    + {{/if}} {{/if_eq}} {{#if_eq event.transport "HTTP"}} - HTTP API : POST: + curl -k -X POST {{httpsGateway}}/api/device-mgt/v1.0/device/agent/events/publish/{{deviceType}}/%deviceId% + -H 'authorization: Bearer %accessToken%' + -H 'content-type: application/json' + -d '{"payloadData": [{{sampleValue}}]}' + + {{/if_eq}} - {{#if eventSample}} -
    - Device Event Payload - {{eventSample}} -
    -
    -
    - {{/if}} {{/if}}

    Retrieve operations

    {{#if type.deviceTypeMetaDefinition.pushNotificationConfig}} {{#if_eq type.deviceTypeMetaDefinition.pushNotificationConfig.type "MQTT"}} + MQTT - {{mqttGateway}} MQTT Topic : {{tenantDomain}}/{{deviceType}}/<device_id>/operation/#
    Topic Structure: @@ -256,10 +262,19 @@
{{/if_eq}} {{else}} - View Operation API - + Retrieve pending operation: + curl -k -X GET {{httpsGateway}}/api/device-mgt/v1.0/device/agent/pending/operations/{{deviceType}}/deviceId + -H 'authorization: Bearer %accessToken%' -H 'content-type: application/json' +
+ Retrieve last pending operation: + curl -k -X GET {{httpsGateway}}/api/device-mgt/v1.0/device/agent/last-pending/operation/{{deviceType}}/deviceId + -H 'authorization: Bearer %accessToken%' -H 'content-type: application/json' +
+ Update operation: + curl -k -X PUT {{httpsGateway}}/api/device-mgt/v1.0/device/agent/operations/{{deviceType}}/deviceId + -H 'authorization: Bearer %accessToken%' -H 'content-type: application/json' -d '{"enabled": true,"code": "alarm","type": "COMMAND","id": 1,"status": "COMPLETED", + "isEnabled": false,"activityId": "ACTIVITY_1"}' + {{/if}}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.js index 81b39fa204..92a85e1cca 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.js @@ -24,6 +24,7 @@ function onRequest(context) { var tenantDomain = user.domain; var deviceMgtProps = require("/app/modules/conf-reader/main.js")["conf"]; var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"]; + var process = require("process"); context.handlebars.registerHelper('if_eq', function(a, b, opts) { if(a == b) // Or === depending on your needs return opts.fn(this); @@ -53,6 +54,7 @@ function onRequest(context) { if (restAPIResponse["status"] == 200 && restAPIResponse["responseText"]) { var typeData = parse(restAPIResponse["responseText"]); displayData.event = typeData; + var sampleValue = ""; if (typeData.eventAttributes && typeData.eventAttributes.attributes) { var sample = {}; sample.event = {}; @@ -62,21 +64,27 @@ function onRequest(context) { switch (attribute.type) { case "STRING": eventExample[attribute.name] = "string"; + sampleValue = sampleValue + "\"string\", "; break; case "LONG": eventExample[attribute.name] = 0; + sampleValue = sampleValue + 0 +", "; break; case "INT": eventExample[attribute.name] = 0; + sampleValue = sampleValue + 0 +", "; break; case "FLOAT": eventExample[attribute.name] = 0.0; + sampleValue = sampleValue + 0.0 +", "; break; case "DOUBLE": eventExample[attribute.name] = 0.0; + sampleValue = sampleValue + 0.0 +", "; break; case "BOOL": eventExample[attribute.name] = false; + sampleValue = sampleValue + false + ", "; break; } @@ -86,7 +94,13 @@ function onRequest(context) { metaEventExample.deviceId = "deviceIdentifier"; sample.event.payloadData = eventExample; sample.event.metaData = metaEventExample; + if (sampleValue && sampleValue.length > 2) { + displayData.sampleValue = sampleValue.substring(0, sampleValue.length - 2); + } displayData.eventSample = JSON.stringify(sample); + displayData.mqttGateway = "tcp://" + process.getProperty("mqtt.broker.host") + ":" + process.getProperty("mqtt.broker.port"); + displayData.httpsGateway = "https://" + process.getProperty("iot.gateway.host") + ":" + process.getProperty("iot.gateway.https.port"); + } } }