fixed multi tenant issues after testing custom device type impl

revert-70aa11f8
ayyoob 8 years ago
parent 56faa75861
commit c3f23fa564

@ -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<String> allowedApisTags = getDeviceManagementProviderService().getAvailableDeviceTypes();
allowedApisTags.add(DEFAULT_CDMF_API_TAG);
allowedApisTags.add(DEFAULT_CERT_API_TAG);
allowedApisTags.add(DEFAULT_AGENT_API_TAG);
return allowedApisTags;
}

@ -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);
}

@ -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,14 +48,31 @@ public class EventsPublisherServiceImpl implements EventsPublisherService {
public boolean publishEvent(String streamName, String version, Object[] metaDataArray,
Object[] correlationDataArray,
Object[] payloadDataArray) throws DataPublisherConfigurationException {
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,
return dataPublisher.tryPublish(streamId, System.currentTimeMillis(), metaDataArray,
correlationDataArray,
payloadDataArray);
} else {
return false;
}
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}

@ -166,6 +166,11 @@
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.analytics.data.publisher</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>

@ -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;
}
}

@ -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);
}

@ -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);
}

@ -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<Attribute> 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<? extends Operation> 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<? extends Operation> 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();
}
}
}

@ -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<Attribute> 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);
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) {
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<Header> 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<Header> 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<Header> 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<Header> 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('.', '_');
}

@ -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<? extends Operation> 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<? extends Operation> 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();
}
}
}

@ -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(); }

@ -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<ConfigurationEntry> 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<Header> 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<Header> 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<Header> 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<Header> 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<String, EventAttributeList> 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);
}
}

@ -42,6 +42,7 @@
<ref bean="deviceTypeManagementAdminService"/>
<ref bean="deviceAnalyticsArtifactUploaderAdminService"/>
<ref bean="deviceEventManagementService"/>
<ref bean="deviceAgentService"/>
<ref bean="swaggerResource"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
@ -86,6 +87,7 @@
<bean id="deviceAccessAuthorizationAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.DeviceAccessAuthorizationAdminServiceImpl"/>
<bean id="deviceAnalyticsArtifactUploaderAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.DeviceAnalyticsArtifactUploaderAdminServiceImpl"/>
<bean id="deviceEventManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.DeviceEventManagementServiceImpl"/>
<bean id="deviceAgentService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.DeviceAgentServiceImpl"/>
<bean id="jsonProvider" class="org.wso2.carbon.device.mgt.jaxrs.common.GsonMessageBodyHandler"/>
<!--<bean id="errorHandler" class="org.wso2.carbon.device.mgt.jaxrs.common.ErrorHandler"/>-->

@ -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) {
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);
}

@ -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;

@ -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": {

@ -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();

@ -135,7 +135,7 @@ function loadDeviceTypes() {
class: "",
data: "name",
render: function (name, type, row, meta) {
return '<h4>' + name.replace("devicemgt", ""); + '</h4>';
return '<h4>' + name.replace("devicemgt", "") + '</h4>';
}
},
{
@ -189,7 +189,8 @@ function loadDeviceTypes() {
var options = {
"placeholder": "Search By Device Type Name",
"searchKey": "filter"
"searchKey": "filter",
"searching": false
};
var settings = {
"sorting": false

@ -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,

@ -24,7 +24,7 @@
{{#each events}}
<tr role="row" class="odd">
<td class="sorting_1" style="padding:10px 15px;">{{this.key}}</td>
<td id="{{this.key}}-value" style="padding:10px 15px;">{{#if this.value}}{{this.value}}{{else}}-{{/if}}</td>
<td id="{{this.key}}-value" style="padding:10px 15px;">{{this.value}}</td>
</tr>
{{/each}}
</tbody>

@ -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(":");
if (tenantDomain == "carbon.super") {
var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username,"default", {});
if (tokenPair) {
token = tokenPair.accessToken;
}
if (tenantDomain == "carbon.super") {
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;
}

@ -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");

@ -18,7 +18,7 @@
<br>
<hr>
<br>
<a href="/api-store/apis/info?name=DeviceManagement&version=1.0.0&provider=admin"
<a href="/api-store/apis/info?name=DeviceAgent Service&version=1.0.0&provider=admin"
class="btn-operations"
target="_blank"><i class="fw fw-api add-margin-1x"></i> View API</i>
</a>
@ -112,17 +112,17 @@
<hr>
<ul class="list-unstyled">
<li class="padding-top-double"><span><h3 class="uppercase">Generate Application</h3></span>
<code>curl -k -X POST https://localhost:8243/api-application-registration/register -H
<code>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"]}'</code>
-d '{ "applicationName":"testme", "isAllowedToAllDomains":false, "tags":["device_agent"]}'</code>
</li>
<li class="padding-top-double"><span><h3 class="uppercase">Generate Token</h3></span>
<code>curl -k -d "grant_type=password&username=%username%&password=%password%&scope=perm:devices:add"
<code>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</code>
-H "Content-Type: application/x-www-form-urlencoded" {{httpsGateway}}/token</code>
</li>
<li class="padding-top-double"><span><h3 class="uppercase">Create Device</h3></span>
<code>curl -X POST http://localhost:8280/api/device-mgt/v1.0/devices -H 'accept: application/json'
<code>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,13 +214,9 @@
<h2 class="uppercase">Device Communication</h2>
<hr>
{{#if event}}
<h3 class="uppercase">publish data for analytics :</h3>
<h3 class="uppercase">publish device events :</h3>
{{#if_eq event.transport "MQTT"}}
MQTT Topic : <code>{{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/events</code>
{{/if_eq}}
{{#if_eq event.transport "HTTP"}}
HTTP API : <code>POST: </code>
{{/if_eq}}
{{#if eventSample}}
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 padding-double grey-bg">
Device Event Payload
@ -229,11 +225,21 @@
<br>
</div>
{{/if}}
{{/if_eq}}
{{#if_eq event.transport "HTTP"}}
<code> 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}}]}'
</code>
{{/if_eq}}
{{/if}}
</br>
<h3 class="uppercase">Retrieve operations</h3>
{{#if type.deviceTypeMetaDefinition.pushNotificationConfig}}
{{#if_eq type.deviceTypeMetaDefinition.pushNotificationConfig.type "MQTT"}}
MQTT - {{mqttGateway}}
MQTT Topic : <code>{{tenantDomain}}/{{deviceType}}/&lt;device_id&gt;/operation/#</code>
<br/>
Topic Structure:
@ -256,10 +262,19 @@
</ul>
{{/if_eq}}
{{else}}
<a href="/api-store/apis/info?name=DeviceManagement&version=1.0.0&provider=admin"
class="btn-operations"
target="_blank"><i class="fw fw-api add-margin-1x"></i> View Operation API</i>
</a>
Retrieve pending operation:
<code>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'</code>
</br>
Retrieve last pending operation:
<code>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'</code>
</br>
Update operation:
<code>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"}'</code>
{{/if}}
<br>

@ -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");
}
}
}

Loading…
Cancel
Save