From c28f820455edbbdf88ab7fb21baeffd776a5ccd1 Mon Sep 17 00:00:00 2001 From: ayyoob Date: Wed, 19 Apr 2017 16:32:06 +0530 Subject: [PATCH] added missing apis - operation and device management --- .../mgt/jaxrs/beans/OperationRequest.java | 45 ++ .../service/api/DeviceManagementService.java | 463 ++++++++++++++++++ .../impl/DeviceManagementServiceImpl.java | 242 ++++++++- .../wso2/carbon/device/mgt/common/Device.java | 2 +- 4 files changed, 750 insertions(+), 2 deletions(-) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/OperationRequest.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/OperationRequest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/OperationRequest.java new file mode 100644 index 00000000000..6d980cbee01 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/OperationRequest.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed 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 org.wso2.carbon.device.mgt.common.operation.mgt.Operation; + +import java.util.List; + +@ApiModel(value = "OperationRequest", description = "Operation details together with deviceIdentifier") +public class OperationRequest { + + @ApiModelProperty(name = "deviceIdentifiers", value = "list of devices that needs to be verified against the user", required = true) + List deviceIdentifiers; + @ApiModelProperty(name = "permission", value = "if null then checks against the owner else it could be grouping permission", required = false) + Operation operation; + + public List getDeviceIdentifiers() { + return deviceIdentifiers; + } + + public void setDeviceIdentifiers(List deviceIdentifiers) { + this.deviceIdentifiers = deviceIdentifiers; + } + + public Operation getOperation() { + return operation; + } + + public void setOperation(Operation operation) { + this.operation = operation; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java index ddbdfcdc08b..06d24510445 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java @@ -32,17 +32,22 @@ 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.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.Feature; import org.wso2.carbon.device.mgt.common.app.mgt.Application; +import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; import org.wso2.carbon.device.mgt.common.policy.mgt.Policy; import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData; import org.wso2.carbon.device.mgt.common.search.SearchContext; import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList; import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.OperationList; +import org.wso2.carbon.device.mgt.jaxrs.beans.OperationRequest; import org.wso2.carbon.device.mgt.jaxrs.util.Constants; +import javax.validation.Valid; import javax.validation.constraints.Size; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -56,6 +61,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.util.List; /** * Device related REST-API. This can be used to manipulated device related details. @@ -137,6 +143,12 @@ import javax.ws.rs.core.Response; 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.", @@ -423,6 +435,169 @@ 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 addDevice(@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( + 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 isEnrolled(@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}/location") @@ -1233,4 +1408,292 @@ public interface DeviceManagementService { @QueryParam("newStatus") EnrolmentInfo.Status newStatus); + @POST + @Path("/{type}/operations") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Add operation to set of devices for a given device type", + notes = "Returns the Activity Related to the operation.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully added the operation.", + response = Activity.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 addOperation(@ApiParam(name = "type", value = "The device type, such as ios, android or windows... etc.", required = true) + @PathParam("type") String type, + @ApiParam(name = "deviceOperation", value = "Operation object with device ids.", required = true) + @Valid OperationRequest operationRequest); + + @GET + @Path("/{type}/{id}/pending/operations") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Get pending operation of the given device", + notes = "Returns the Operations.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved the operations.", + response = OperationList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response getPendingOperations(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) + @PathParam("type") String type, + @ApiParam(name = "id", value = "The device id.", required = true) + @PathParam("id") String deviceId); + + @GET + @Path("/{type}/{id}/last-pending/operation") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Get pending operation of the given device", + notes = "Returns the Operation.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved the operation.", + response = Operation.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response getNextPendingOperation(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) + @PathParam("type") String type, + @ApiParam(name = "id", value = "The device id.", required = true) + @PathParam("id") String deviceId); + + @PUT + @Path("/{type}/{id}/operations") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Update Operation", + notes = "Update the Operations.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully updated the operations.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response updateOperation(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) + @PathParam("type") String type, + @ApiParam(name = "id", value = "The device id.", required = true) + @PathParam("id") String deviceId, + @ApiParam(name = "operation", value = "Operation object with data.", required = true) + @Valid Operation operation); + + @GET + @Path("/{type}/{id}/status/operations") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Get pending operation of the given device", + notes = "Returns the Operations.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved the operations.", + response = OperationList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response getOperationsByDeviceAndStatus(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) + @PathParam("type") String type, + @ApiParam(name = "id", value = "The device id.", required = true) + @PathParam("id") String deviceId, + @ApiParam(name = "status", value = "status of the operation.", required = true) + @QueryParam("status")Operation.Status status); + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java index 3f3185a30d1..4bbbfdb1302 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -18,17 +18,18 @@ */ package org.wso2.carbon.device.mgt.jaxrs.service.impl; -import io.swagger.annotations.ApiParam; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.Feature; import org.wso2.carbon.device.mgt.common.FeatureManager; +import org.wso2.carbon.device.mgt.common.InvalidDeviceException; import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.PaginationResult; import org.wso2.carbon.device.mgt.common.app.mgt.Application; @@ -36,6 +37,7 @@ import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException; 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.device.details.DeviceLocation; +import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; 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.common.policy.mgt.Policy; @@ -52,6 +54,7 @@ import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceCompliance; import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList; import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; import org.wso2.carbon.device.mgt.jaxrs.beans.OperationList; +import org.wso2.carbon.device.mgt.jaxrs.beans.OperationRequest; import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceManagementService; import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; @@ -59,6 +62,7 @@ import org.wso2.carbon.policy.mgt.common.PolicyManagementException; import org.wso2.carbon.policy.mgt.core.PolicyManagerService; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; +import javax.validation.Valid; import javax.validation.constraints.Size; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -85,6 +89,126 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { private static final Log log = LogFactory.getLog(DeviceManagementServiceImpl.class); + @POST + @Override + public Response addDevice(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(); + device.getEnrolmentInfo().setOwner(DeviceMgtAPIUtils.getAuthenticatedUser()); + 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 + public Response isEnrolled(@PathParam("type") String type, @PathParam("id") String id) { + boolean result; + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(id, type); + try { + result = DeviceMgtAPIUtils.getDeviceManagementService().isEnrolled(deviceIdentifier); + if (result) { + return Response.status(Response.Status.OK).build(); + } else { + return Response.status(Response.Status.NOT_FOUND).build(); + } + } catch (DeviceManagementException e) { + String msg = "Error occurred while checking enrollment status of the device."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @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.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( @@ -601,4 +725,120 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); } } + + @POST + @Path("/{type}/operations") + public Response addOperation(@PathParam("type") String type, OperationRequest operationRequest) { + try { + if (operationRequest == null || operationRequest.getDeviceIdentifiers() == null) { + String errorMessage = "Device identifier list is empty"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + DeviceIdentifier deviceIdentifier; + List deviceIdentifiers = new ArrayList<>(); + for (String deviceId : operationRequest.getDeviceIdentifiers()) { + deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(deviceId); + deviceIdentifier.setType(type); + deviceIdentifiers.add(deviceIdentifier); + } + Activity activity = DeviceMgtAPIUtils.getDeviceManagementService().addOperation(type + , operationRequest.getOperation(), deviceIdentifiers); + return Response.status(Response.Status.CREATED).entity(activity).build(); + } catch (InvalidDeviceException e) { + String errorMessage = "Invalid Device Identifiers found."; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).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(); + } + } + + @GET + @Path("/{type}/{id}/pending/operations") + public Response getPendingOperations(@PathParam("type") String type, @PathParam("id") String deviceId) { + try { + List operations = DeviceMgtAPIUtils.getDeviceManagementService().getPendingOperations( + new DeviceIdentifier(deviceId, type)); + OperationList operationsList = new OperationList(); + operationsList.setList(operations); + operationsList.setCount(operations.size()); + return Response.status(Response.Status.OK).entity(operationsList).build(); + } catch (OperationManagementException e) { + String errorMessage = "Issue in retrieving operation management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); + } + } + + @GET + @Path("/{type}/{id}/last-pending/operation") + public Response getNextPendingOperation(@PathParam("type") String type, @PathParam("id") String deviceId) { + try { + 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(); + } + } + + @PUT + @Path("/{type}/{id}/operations") + public Response updateOperation(@PathParam("type") String type, @PathParam("id") String deviceId, Operation operation) { + try { + 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(); + } + } + + @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 { + List operations = DeviceMgtAPIUtils.getDeviceManagementService() + .getOperationsByDeviceAndStatus(new DeviceIdentifier(deviceId, type), status); + OperationList operationsList = new OperationList(); + operationsList.setList(operations); + operationsList.setCount(operations.size()); + return Response.status(Response.Status.OK).entity(operationsList).build(); + } catch (OperationManagementException e) { + String errorMessage = "Issue in retrieving operation management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); + } catch (DeviceManagementException e) { + String errorMessage = "Issue in retrieving device management service"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); + } + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/Device.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/Device.java index 04df8c7dcdc..d492ce22e1f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/Device.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/Device.java @@ -30,7 +30,7 @@ public class Device implements Serializable { private static final long serialVersionUID = 1998101711L; - @ApiModelProperty(name = "id", value = "ID of the device in the WSO2 EMM device information database.", + @ApiModelProperty(name = "id", value = "ID of the device in the device information database.", required = true) private int id;