diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/DeviceManagementConfigService.java b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/DeviceManagementConfigService.java index 4742548f66d..14e0e1ded1f 100644 --- a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/DeviceManagementConfigService.java +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/DeviceManagementConfigService.java @@ -18,6 +18,7 @@ package io.entgra.carbon.device.mgt.config.jaxrs.service; +import org.wso2.carbon.device.mgt.common.DeviceTransferRequest; import io.entgra.carbon.device.mgt.config.jaxrs.beans.ErrorResponse; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -33,12 +34,11 @@ 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.configuration.mgt.DeviceConfiguration; -import org.wso2.carbon.device.mgt.common.search.PropertyMap; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; +import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; @@ -63,7 +63,6 @@ import javax.ws.rs.core.Response; ) @Path("/configurations") @Api(value = "Device Management Configuration") -@Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @Scopes(scopes = { @Scope( @@ -71,6 +70,12 @@ import javax.ws.rs.core.Response; description = "", key = "perm:view-configuration", permissions = {"/device-mgt/platform-configurations/view"} + ), + @Scope( + name = "Manage configurations", + description = "", + key = "perm:manage-configuration", + permissions = {"/device-mgt/platform-configurations/manage"} ) } ) @@ -119,16 +124,74 @@ public interface DeviceManagementConfigService { "fetching device configurations.", response = ErrorResponse.class) }) - Response getConfiguration(@ApiParam( - name = "token", - value = "value for identify an already enrolled and authorized device", - required = true) - @HeaderParam("token") - String token, - @ApiParam( - name = "properties", - value = "The properties list using for query a device", - required = true) - @QueryParam("properties") - String properties); + @Produces(MediaType.APPLICATION_JSON) + Response getConfiguration( + @ApiParam( + name = "token", + value = "value for identify an already enrolled and authorized device", + required = true) + @HeaderParam("token") + String token, + @ApiParam( + name = "properties", + value = "The properties list using for query a device", + required = true) + @QueryParam("properties") + String properties); + + @PUT + @Path("/transfer") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Transfer device to another tenant from super tenant", + notes = "This API is responsible for transfer device from super tenant to another tenant", + tags = "Device Management Configuration", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "scope", value = "perm:manage-configuration") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully transferred the device.", + response = DeviceConfiguration.class, + responseContainer = "List", + 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.Used by caches, or in " + + "conditional requests."), + } + ), + @ApiResponse( + code = 400, + message = "Bad request.\n The request contains invalid parameters"), + @ApiResponse( + code = 401, + message = "Unauthorized.\n The requested is not authorized"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while " + + "fetching device configurations.", + response = ErrorResponse.class) + }) + @Produces(MediaType.APPLICATION_JSON) + Response transferDevices( + @ApiParam( + name = "Device Transfer Request", + value = "The device transfer request", + required = true) + DeviceTransferRequest deviceTransferRequest); } diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java index b34f964b177..93aba13627a 100644 --- a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java @@ -26,8 +26,10 @@ import io.entgra.carbon.device.mgt.config.jaxrs.service.DeviceManagementConfigSe import io.entgra.carbon.device.mgt.config.jaxrs.util.DeviceMgtAPIUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.AppRegistrationCredentials; import org.wso2.carbon.device.mgt.common.ApplicationRegistrationException; +import org.wso2.carbon.device.mgt.common.DeviceTransferRequest; import org.wso2.carbon.device.mgt.common.configuration.mgt.AmbiguousConfigurationException; import org.wso2.carbon.device.mgt.common.configuration.mgt.DeviceConfiguration; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; @@ -41,16 +43,17 @@ import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientExceptio import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; +import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.IOException; +import java.util.List; import java.util.Map; @Path("/configurations") -@Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class DeviceManagementConfigServiceImpl implements DeviceManagementConfigService { @@ -58,6 +61,7 @@ public class DeviceManagementConfigServiceImpl implements DeviceManagementConfig @Override @GET + @Produces(MediaType.APPLICATION_JSON) public Response getConfiguration(@HeaderParam("token") String token, @QueryParam("properties") String properties) { DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); @@ -115,6 +119,41 @@ public class DeviceManagementConfigServiceImpl implements DeviceManagementConfig } } + @PUT + @Path("/transfer") + @Override + @Produces(MediaType.APPLICATION_JSON) + public Response transferDevices(DeviceTransferRequest deviceTransferRequest) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + int tenantId = ctx.getTenantId(false); + if (tenantId != -1234) { + return Response.status(Response.Status.FORBIDDEN).entity("Tenant '" + ctx.getTenantDomain(true) + + "' does not have privilege to transfer device").build(); + } + DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); + try { + List devicesTransferred = dms.transferDeviceToTenant(deviceTransferRequest); + if (devicesTransferred.isEmpty()) { + String msg = "Devices are not enrolled to super tenant"; + log.warn(msg); + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } else { + return Response.status(Response.Status.OK).entity(devicesTransferred).build(); + } + } catch (DeviceManagementException e) { + String msg = "Error occurred while transferring device to tenant " + + deviceTransferRequest.getDestinationTenant(); + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (DeviceNotFoundException e) { + log.error(e.getMessage(), e); + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(e.getMessage()).build()).build(); + } + } + private String parseUriParamsToJSON(String uriParams) { uriParams = uriParams.replaceAll("=", "\":\""); uriParams = uriParams.replaceAll("&", "\",\""); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GroupManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GroupManagementService.java index d060f3a3df9..0e5673dd299 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GroupManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GroupManagementService.java @@ -681,7 +681,15 @@ public interface GroupManagementService { "pagination index/offset.", defaultValue = "5") @QueryParam("limit") - int limit); + int limit, + + @ApiParam( + name = "requireDeviceProps", + value = "Boolean flag indicating whether to include device properties \n" + + " to the device object.", + required = false) + @QueryParam("requireDeviceProps") + boolean requireDeviceProps); @Path("/id/{groupId}/devices/count") @GET diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java index 4377c9d1855..ca8bdcf5f69 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java @@ -249,7 +249,7 @@ public interface DeviceManagementAdminService { List deviceIdentifiers); @DELETE - @Path("/type/{device-type}/id/{device-id}") + @Path("/permanent-delete") @ApiOperation( produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON, @@ -282,37 +282,20 @@ public interface DeviceManagementAdminService { 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 deleteDevicePermanently( - @ApiParam( - name = "device-type", - value = "The device type, such as ios, android, or windows.", - required = true) - @PathParam("device-type") - @Size(max = 45) - String deviceType, + Response deleteDevicesPermanently( @ApiParam( - name = "device-id", - value = "The device identifier of the device.", + name = "Device Identifiers", + value = "List of device identifiers.", required = true) - @PathParam("device-id") - @Size(max = 45) - String deviceId); + List deviceIdentifiers); } 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 9febec7ec36..ee4bf95b08e 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 @@ -652,10 +652,19 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { List devices; DeviceList deviceList = new DeviceList(); try { + if(map.getProperties().isEmpty()){ + if (log.isDebugEnabled()) { + log.debug("No search criteria defined when querying devices."); + } + return Response.status(Response.Status.BAD_REQUEST).entity("No search criteria defined.").build(); + } DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); devices = dms.getDevicesBasedOnProperties(map.getProperties()); if(devices == null || devices.isEmpty()){ - return Response.status(Response.Status.OK).entity("No device found matching query criteria.").build(); + if (log.isDebugEnabled()) { + log.debug("No Devices Found for criteria : " + map); + } + return Response.status(Response.Status.NOT_FOUND).entity("No device found matching query criteria.").build(); } } catch (DeviceManagementException e) { String msg = "Error occurred while searching for devices that matches the provided device properties"; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java index 3d4d8fe29bf..e2cda27c0ca 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java @@ -204,10 +204,10 @@ public class GroupManagementServiceImpl implements GroupManagementService { } @Override - public Response getDevicesOfGroup(int groupId, int offset, int limit) { + public Response getDevicesOfGroup(int groupId, int offset, int limit, boolean requireDeviceProps) { try { GroupManagementProviderService service = DeviceMgtAPIUtils.getGroupManagementProviderService(); - List deviceList = service.getDevices(groupId, offset, limit); + List deviceList = service.getDevices(groupId, offset, limit, requireDeviceProps); int deviceCount = service.getDeviceCount(groupId); DeviceList deviceListWrapper = new DeviceList(); if (deviceList != null) { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java index 031fd1c56a7..301a5d0dfc7 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java @@ -138,26 +138,26 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe @DELETE @Override - @Path("/type/{device-type}/id/{device-id}") - public Response deleteDevicePermanently(@PathParam("device-type") String deviceType, - @PathParam("device-id") String deviceId) { + @Path("/permanent-delete") + public Response deleteDevicesPermanently(List deviceIdentifiers) { DeviceManagementProviderService deviceManagementProviderService = DeviceMgtAPIUtils.getDeviceManagementService(); try { - DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, deviceType); - Device persistedDevice = deviceManagementProviderService.getDevice(deviceIdentifier, true); - if (persistedDevice == null) { - String msg = "No device found with the device type: " + deviceType + - " having the device ID: " + deviceId + " to permanently delete."; + if (!deviceManagementProviderService.deleteDevices(deviceIdentifiers)) { + String msg = "Found un-deployed device type."; log.error(msg); - return Response.status(Response.Status.NOT_FOUND).entity( + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); } - boolean response = deviceManagementProviderService.deleteDevice(deviceIdentifier); - return Response.status(Response.Status.OK).entity(response).build(); + return Response.status(Response.Status.OK).entity(true).build(); } catch (DeviceManagementException e) { - String msg = "Error encountered while permanently deleting device of type : " + deviceType + " and " + - "ID : " + deviceId; + String msg = "Error encountered while permanently deleting devices"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + catch (InvalidDeviceException e) { + String msg = "Found Invalid devices"; log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity( new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java index 559a8cabee2..35f36502738 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java @@ -266,16 +266,16 @@ public class GroupManagementServiceImplTest { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) .toReturn(groupManagementProviderService); Mockito.doReturn(1).when(groupManagementProviderService).getDeviceCount(Mockito.anyInt()); - Mockito.doReturn(new ArrayList()).when(groupManagementProviderService).getDevices(1, 0, 10); - Mockito.doReturn(null).when(groupManagementProviderService).getDevices(2, 0, 10); - Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService).getDevices(3, 0, 10); - Response response = groupManagementService.getDevicesOfGroup(1, 0, 10); + Mockito.doReturn(new ArrayList()).when(groupManagementProviderService).getDevices(1, 0, 10, false); + Mockito.doReturn(null).when(groupManagementProviderService).getDevices(2, 0, 10, false); + Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService).getDevices(3, 0, 10, false); + Response response = groupManagementService.getDevicesOfGroup(1, 0, 10, false); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), "getDevicesOfGroup request failed for a request with valid parameters"); - response = groupManagementService.getDevicesOfGroup(2, 0, 10); + response = groupManagementService.getDevicesOfGroup(2, 0, 10, false); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), "getDevicesOfGroup request failed for a request with valid parameters"); - response = groupManagementService.getDevicesOfGroup(3, 0, 10); + response = groupManagementService.getDevicesOfGroup(3, 0, 10, false); Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), "getDevicesOfGroup request succeded for a request with in-valid parameters"); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceManager.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceManager.java index 09e84c26b98..2c7336144f6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceManager.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceManager.java @@ -98,13 +98,11 @@ public interface DeviceManager { boolean disenrollDevice(DeviceIdentifier deviceId) throws DeviceManagementException; /** - * Method to delete a particular device from CDM. - * - * @param deviceId Fully qualified device identifier - * @return A boolean indicating the status of the operation. + * Method to delete multiple devices from CDM. + * @param deviceIdentifiers Fully qualified device identifier list * @throws DeviceManagementException If some unusual behaviour is observed while deleting a device */ - boolean deleteDevice(DeviceIdentifier deviceId, Device device) throws DeviceManagementException; + void deleteDevices(List deviceIdentifiers) throws DeviceManagementException; /** * Method to retrieve the status of the registration process of a particular device. diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceTransferRequest.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceTransferRequest.java new file mode 100644 index 00000000000..2a73c4dccf5 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceTransferRequest.java @@ -0,0 +1,48 @@ +package org.wso2.carbon.device.mgt.common; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +/** + * Represents an individual configuration entry. + */ +@ApiModel(value = "DeviceTransferRequest", description = "This class carries all information related to device " + + "transfer from super tenant to another tenant.") +public class DeviceTransferRequest { + + @ApiModelProperty(name = "deviceType", value = "Type of the device", required = true) + private String deviceType; + + @ApiModelProperty(name = "deviceIds", value = "Ids of devices to transfer", required = true) + private List deviceIds; + + @ApiModelProperty(name = "destinationTenant", value = "Destination Tenant ID", required = true) + private String destinationTenant; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public List getDeviceIds() { + return deviceIds; + } + + public void setDeviceId(List deviceIds) { + this.deviceIds = deviceIds; + } + + public String getDestinationTenant() { + return destinationTenant; + } + + public void setDestinationTenant(String destinationTenant) { + this.destinationTenant = destinationTenant; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/pom.xml b/components/device-mgt/org.wso2.carbon.device.mgt.core/pom.xml index 5a4eafe577d..560b693618d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/pom.xml +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/pom.xml @@ -356,6 +356,10 @@ org.powermock powermock-api-mockito + + org.wso2.carbon.multitenancy + org.wso2.carbon.tenant.mgt + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java index f824a2255b9..f6bff717b15 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java @@ -45,6 +45,7 @@ import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.geo.GeoCluster; import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; +import java.sql.SQLException; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -522,11 +523,15 @@ public interface DeviceDAO { List getDevicesByIdentifiers(List deviceIdentifiers, int tenantId) throws DeviceManagementDAOException; - /** - * This method is used to permanently delete the device and its related details - * @param deviceIdentifier device id - * @param tenantId tenant id - * @throws DeviceManagementDAOException + /*** + * This method is used to permanently delete devices and their related details + * @param deviceIdentifiers List of device identifiers. + * @param deviceIds list of device ids (primary keys). + * @param enrollmentIds list of enrollment ids. + * @throws DeviceManagementDAOException when no enrolments are found for the given device. */ - void deleteDevice(DeviceIdentifier deviceIdentifier, int tenantId) throws DeviceManagementDAOException; + void deleteDevices(List deviceIdentifiers, List deviceIds, List enrollmentIds) throws DeviceManagementDAOException; + + boolean transferDevice(String deviceType, String deviceId, String owner, int destinationTenantId) + throws DeviceManagementDAOException, SQLException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java index 6e5ef3a5861..2a69ef188d4 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java @@ -56,6 +56,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; +import java.sql.Statement; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -1560,9 +1561,8 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { ps.setInt(index++, tenantId); ps.setInt(index, tenantId); try (ResultSet rs = ps.executeQuery()) { - if (rs.next()) { - Device device = DeviceManagementDAOUtil.loadDevice(rs); - devices.add(device); + while (rs.next()) { + devices.add(DeviceManagementDAOUtil.loadDevice(rs)); } } } @@ -1572,369 +1572,461 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { + " given device identifiers.", e); } } - - public void deleteDevice(DeviceIdentifier deviceIdentifier, int tenantId) throws DeviceManagementDAOException { - String deviceIdentifierId = deviceIdentifier.getId(); - String deviceType = deviceIdentifier.getType(); + + @Override + public void deleteDevices(List deviceIdentifiers, List deviceIds, List enrollmentIds) + throws DeviceManagementDAOException { Connection conn; try { conn = this.getConnection(); - int deviceId = getDeviceId(conn, deviceIdentifier, tenantId); - if (deviceId == -1) { - String msg = "Device " + deviceIdentifierId + " of type " + deviceType + " is not found"; + if (enrollmentIds.isEmpty()) { + String msg = "Enrollments not found for the devices: " + deviceIdentifiers; log.error(msg); throw new DeviceManagementDAOException(msg); } else { - List enrollmentIds = getEnrollmentIds(conn, deviceId, tenantId); - if (enrollmentIds == null || enrollmentIds.isEmpty()) { - String msg = "Enrollments not found for the device " + deviceIdentifierId + " of type " - + deviceType; - log.error(msg); - throw new DeviceManagementDAOException(msg); - } else { - removeDeviceDetail(conn, deviceId); - if (log.isDebugEnabled()) { - log.debug("Successfully removed device detail data of device " + deviceIdentifierId - + " of type " + deviceType); - } - removeDeviceLocation(conn, deviceId); - if (log.isDebugEnabled()) { - log.debug("Successfully removed device location data of device " + deviceIdentifierId - + " of type " + deviceType); - } - removeDeviceInfo(conn, deviceId); - if (log.isDebugEnabled()) { - log.debug("Successfully removed device info data of device " + deviceIdentifierId - + " of type " + deviceType); - } - removeDeviceNotification(conn, deviceId); - if (log.isDebugEnabled()) { - log.debug("Successfully removed device notification data of device " + deviceIdentifierId - + " of type " + deviceType); - } - removeDeviceApplicationMapping(conn, deviceId); - if (log.isDebugEnabled()) { - log.debug("Successfully removed device application mapping data of device " - + deviceIdentifierId + " of type " + deviceType); - } - removeDevicePolicyApplied(conn, deviceId); - if (log.isDebugEnabled()) { - log.debug("Successfully removed device applied policy data of device " + deviceIdentifierId - + " of type " + deviceType); - } - removeDevicePolicy(conn, deviceId); - if (log.isDebugEnabled()) { - log.debug("Successfully removed device policy data of device " + deviceIdentifierId - + " of type " + deviceType); - } - if (log.isDebugEnabled()) { - log.debug("Starting to remove " + enrollmentIds.size() + " enrollment data of device " - + deviceIdentifierId + " of type " + deviceType); - } - for (Integer enrollmentId : enrollmentIds) { - removeEnrollmentDeviceDetail(conn, enrollmentId); - removeEnrollmentDeviceLocation(conn, enrollmentId); - removeEnrollmentDeviceInfo(conn, enrollmentId); - removeEnrollmentDeviceApplicationMapping(conn, enrollmentId); - removeDeviceOperationResponse(conn, enrollmentId); - removeEnrollmentOperationMapping(conn, enrollmentId); - } - if (log.isDebugEnabled()) { - log.debug("Successfully removed enrollment device details, enrollment device location, " + - "enrollment device info, enrollment device application mapping, " + - "enrollment device operation response, enrollment operation mapping data of device " - + deviceIdentifierId + " of type " + deviceType); - } - removeDeviceEnrollment(conn, deviceId); - if (log.isDebugEnabled()) { - log.debug("Successfully removed device enrollment data of device " + deviceIdentifierId - + " of type " + deviceType); - } - removeDeviceGroupMapping(conn, deviceId); - if (log.isDebugEnabled()) { - log.debug("Successfully removed device group mapping data of device " + deviceIdentifierId - + " of type " + deviceType); - } - removeDevice(conn, deviceId); - if (log.isDebugEnabled()) { - log.debug("Successfully permanently deleted the device of device " + deviceIdentifierId - + " of type " + deviceType); - } + removeDeviceDetail(conn, deviceIds); + if (log.isDebugEnabled()) { + log.debug("Successfully removed device detail data of devices: " + deviceIdentifiers); + } + removeDeviceLocation(conn, deviceIds); + if (log.isDebugEnabled()) { + log.debug("Successfully removed device location data of devices: " + deviceIdentifiers); + } + removeDeviceInfo(conn, deviceIds); + if (log.isDebugEnabled()) { + log.debug("Successfully removed device info data of devices: " + deviceIdentifiers); + } + removeDeviceNotification(conn, deviceIds); + if (log.isDebugEnabled()) { + log.debug("Successfully removed device notification data of devices: " + deviceIdentifiers); + } + removeDeviceApplicationMapping(conn, deviceIds); + if (log.isDebugEnabled()) { + log.debug("Successfully removed device application mapping data of devices: " + + deviceIdentifiers); + } + removeDevicePolicyApplied(conn, deviceIds); + if (log.isDebugEnabled()) { + log.debug("Successfully removed device applied policy data of devices: " + deviceIdentifiers); + } + removeDevicePolicy(conn, deviceIds); + if (log.isDebugEnabled()) { + log.debug("Successfully removed device policy data of devices: " + deviceIdentifiers); + } + if (log.isDebugEnabled()) { + log.debug("Starting to remove " + enrollmentIds.size() + " enrollment data of devices with " + + "identifiers: " + deviceIdentifiers); + } + removeEnrollmentDeviceDetail(conn, enrollmentIds); + removeEnrollmentDeviceLocation(conn, enrollmentIds); + removeEnrollmentDeviceInfo(conn, enrollmentIds); + removeEnrollmentDeviceApplicationMapping(conn, enrollmentIds); + removeDeviceOperationResponse(conn, enrollmentIds); + removeEnrollmentOperationMapping(conn, enrollmentIds); + if (log.isDebugEnabled()) { + log.debug("Successfully removed enrollment device details, enrollment device location," + + "enrollment device info, enrollment device application mapping, " + + "enrollment device operation response, enrollment operation mapping data of " + + "devices with identifiers: " + deviceIdentifiers); + } + removeDeviceEnrollment(conn, deviceIds); + if (log.isDebugEnabled()) { + log.debug("Successfully removed device enrollment data of devices: " + deviceIdentifiers); + } + removeDeviceGroupMapping(conn, deviceIds); + if (log.isDebugEnabled()) { + log.debug("Successfully removed device group mapping data of devices: " + deviceIdentifiers); + } + removeDevice(conn, deviceIds); + if (log.isDebugEnabled()) { + log.debug("Successfully permanently deleted the device of devices: " + deviceIdentifiers); } } } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while deleting the device " + deviceIdentifierId - + " of type " + deviceType, e); + String msg ="Error occurred while deleting the devices: " + deviceIdentifiers; + log.error(msg,e); + throw new DeviceManagementDAOException(msg, e); } } - private int getDeviceId(Connection conn, DeviceIdentifier deviceIdentifier, int tenantId) - throws DeviceManagementDAOException { - PreparedStatement stmt = null; - ResultSet rs = null; - int deviceId = -1; + /*** + * This method removes records of a given list of devices from the DM_DEVICE_DETAIL table + * @param conn Connection object + * @param deviceIds list of device ids (primary keys) + * @throws DeviceManagementDAOException if deletion fails + */ + private void removeDeviceDetail(Connection conn, List deviceIds) throws DeviceManagementDAOException { + String sql = "DELETE FROM DM_DEVICE_DETAIL WHERE DEVICE_ID = ?"; try { - String sql = "SELECT ID FROM DM_DEVICE WHERE DEVICE_IDENTIFICATION = ? AND TENANT_ID = ?"; - stmt = conn.prepareStatement(sql); - stmt.setString(1, deviceIdentifier.getId()); - stmt.setInt(2, tenantId); - rs = stmt.executeQuery(); - if (rs.next()) { - deviceId = rs.getInt("ID"); - } + executeBatchOperation(conn, sql, deviceIds); } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while retrieving device id of the device", e); - } finally { - DeviceManagementDAOUtil.cleanupResources(stmt, rs); + String msg = "Error occurred while removing device details."; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); } - return deviceId; } - private List getEnrollmentIds(Connection conn, int deviceId, int tenantId) throws DeviceManagementDAOException { - PreparedStatement stmt = null; - ResultSet rs = null; - List enrollmentIds = new ArrayList<>(); + /*** + * This method removes records of a given list of devices from the DM_DEVICE_LOCATION table + * @param conn Connection object + * @param deviceIds list of device ids (primary keys) + * @throws DeviceManagementDAOException if deletion fails + */ + private void removeDeviceLocation(Connection conn, List deviceIds) throws DeviceManagementDAOException { + String sql = "DELETE FROM DM_DEVICE_LOCATION WHERE DEVICE_ID = ?"; try { - String sql = "SELECT ID FROM DM_ENROLMENT WHERE DEVICE_ID = ? AND TENANT_ID = ?"; - stmt = conn.prepareStatement(sql); - stmt.setInt(1, deviceId); - stmt.setInt(2, tenantId); - rs = stmt.executeQuery(); - while (rs.next()) { - enrollmentIds.add(rs.getInt("ID")); - } + executeBatchOperation(conn, sql, deviceIds); } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while retrieving enrollment id of the device", e); - } finally { - DeviceManagementDAOUtil.cleanupResources(stmt, rs); + String msg = "Error occurred while obtaining locations of devices."; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); } - return enrollmentIds; } - private void removeDeviceDetail(Connection conn, int deviceId) throws DeviceManagementDAOException { - PreparedStatement stmt = null; + /*** + * This method removes records of a given list of devices from the DM_DEVICE_INFO table + * @param conn Connection object + * @param deviceIds list of device ids (primary keys) + * @throws DeviceManagementDAOException if deletion fails + */ + private void removeDeviceInfo(Connection conn, List deviceIds) throws DeviceManagementDAOException { + String sql = "DELETE FROM DM_DEVICE_INFO WHERE DEVICE_ID = ?"; try { - String sql = "DELETE FROM DM_DEVICE_DETAIL WHERE DEVICE_ID = ?"; - stmt = conn.prepareStatement(sql); - stmt.setInt(1, deviceId); - stmt.executeUpdate(); + executeBatchOperation(conn, sql, deviceIds); } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while removing device detail", e); - } finally { - DeviceManagementDAOUtil.cleanupResources(stmt, null); + String msg = "Error occurred while removing device info."; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); } } - private void removeDeviceLocation(Connection conn, int deviceId) throws DeviceManagementDAOException { - PreparedStatement stmt = null; + /*** + * This method removes records of a given list of devices from the DM_NOTIFICATION table + * @param conn Connection object + * @param deviceIds list of device ids (primary keys) + * @throws DeviceManagementDAOException if deletion fails + */ + private void removeDeviceNotification(Connection conn, List deviceIds) throws DeviceManagementDAOException { + String sql = "DELETE FROM DM_NOTIFICATION WHERE DEVICE_ID = ?"; try { - String sql = "DELETE FROM DM_DEVICE_LOCATION WHERE DEVICE_ID = ?"; - stmt = conn.prepareStatement(sql); - stmt.setInt(1, deviceId); - stmt.executeUpdate(); + executeBatchOperation(conn, sql, deviceIds); } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while removing device location", e); - } finally { - DeviceManagementDAOUtil.cleanupResources(stmt, null); + String msg = "Error occurred while removing device notifications."; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); } + } - private void removeDeviceInfo(Connection conn, int deviceId) throws DeviceManagementDAOException { - PreparedStatement stmt = null; + /*** + * This method removes records of a given list of devices from the DM_DEVICE_APPLICATION_MAPPING table + * @param conn Connection object + * @param deviceIds list of device ids (primary keys) + * @throws DeviceManagementDAOException if deletion fails + */ + private void removeDeviceApplicationMapping(Connection conn, List deviceIds) + throws DeviceManagementDAOException { + String sql = "DELETE FROM DM_DEVICE_APPLICATION_MAPPING WHERE DEVICE_ID = ?"; try { - String sql = "DELETE FROM DM_DEVICE_INFO WHERE DEVICE_ID = ?"; - stmt = conn.prepareStatement(sql); - stmt.setInt(1, deviceId); - stmt.executeUpdate(); + executeBatchOperation(conn, sql, deviceIds); } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while removing device info", e); - } finally { - DeviceManagementDAOUtil.cleanupResources(stmt, null); + String msg = "Error occurred while removing device application mapping"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); } } - private void removeDeviceNotification(Connection conn, int deviceId) throws DeviceManagementDAOException { - PreparedStatement stmt = null; + /*** + * This method removes records of a given list of devices from the DM_DEVICE_POLICY_APPLIED table + * @param conn Connection object + * @param deviceIds list of device ids (primary keys) + * @throws DeviceManagementDAOException if deletion fails + */ + private void removeDevicePolicyApplied(Connection conn, List deviceIds) + throws DeviceManagementDAOException { + String sql = "DELETE FROM DM_DEVICE_POLICY_APPLIED WHERE DEVICE_ID = ?"; try { - String sql = "DELETE FROM DM_NOTIFICATION WHERE DEVICE_ID = ?"; - stmt = conn.prepareStatement(sql); - stmt.setInt(1, deviceId); - stmt.executeUpdate(); + executeBatchOperation(conn, sql, deviceIds); } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while removing device notification", e); - } finally { - DeviceManagementDAOUtil.cleanupResources(stmt, null); + String msg = "Error occurred while removing policies applied on devices"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); } } - private void removeDeviceApplicationMapping(Connection conn, int deviceId) throws DeviceManagementDAOException { - PreparedStatement stmt = null; + /*** + * This method removes records of a given list of devices from the DM_DEVICE_POLICY table + * @param conn Connection object + * @param deviceIds list of device ids (primary keys) + * @throws DeviceManagementDAOException if deletion fails + */ + private void removeDevicePolicy(Connection conn, List deviceIds) throws DeviceManagementDAOException { + String sql = "DELETE FROM DM_DEVICE_POLICY WHERE DEVICE_ID = ?"; try { - String sql = "DELETE FROM DM_DEVICE_APPLICATION_MAPPING WHERE DEVICE_ID = ?"; - stmt = conn.prepareStatement(sql); - stmt.setInt(1, deviceId); - stmt.executeUpdate(); + executeBatchOperation(conn, sql, deviceIds); } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while removing device application mapping", e); - } finally { - DeviceManagementDAOUtil.cleanupResources(stmt, null); + String msg = "Error occurred while removing policies of devices"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); } } - private void removeDevicePolicyApplied(Connection conn, int deviceId) throws DeviceManagementDAOException { - PreparedStatement stmt = null; + /*** + * This method removes records of a given list of enrollments from the DM_DEVICE_DETAIL table + * @param conn Connection object + * @param enrollmentIds list of enrollment ids (primary keys) + * @throws DeviceManagementDAOException if deletion fails + */ + private void removeEnrollmentDeviceDetail(Connection conn, List enrollmentIds) + throws DeviceManagementDAOException { + String sql = "DELETE FROM DM_DEVICE_DETAIL WHERE ENROLMENT_ID = ?"; try { - String sql = "DELETE FROM DM_DEVICE_POLICY_APPLIED WHERE DEVICE_ID = ?"; - stmt = conn.prepareStatement(sql); - stmt.setInt(1, deviceId); - stmt.executeUpdate(); + executeBatchOperation(conn, sql, enrollmentIds); } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while removing device policy applied", e); - } finally { - DeviceManagementDAOUtil.cleanupResources(stmt, null); + String msg = "Error occurred while removing enrollment details of devices"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); } } - private void removeDevicePolicy(Connection conn, int deviceId) throws DeviceManagementDAOException { - PreparedStatement stmt = null; + /*** + * This method removes records of a given list of enrollments from the DM_DEVICE_LOCATION table + * @param conn Connection object + * @param enrollmentIds list of enrollment ids (primary keys) + * @throws DeviceManagementDAOException if deletion fails + */ + private void removeEnrollmentDeviceLocation(Connection conn, List enrollmentIds) + throws DeviceManagementDAOException { + String sql = "DELETE FROM DM_DEVICE_LOCATION WHERE ENROLMENT_ID = ?"; try { - String sql = "DELETE FROM DM_DEVICE_POLICY WHERE DEVICE_ID = ?"; - stmt = conn.prepareStatement(sql); - stmt.setInt(1, deviceId); - stmt.executeUpdate(); + executeBatchOperation(conn, sql, enrollmentIds); } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while removing device policy", e); - } finally { - DeviceManagementDAOUtil.cleanupResources(stmt, null); + String msg = "Error occurred while removing enrollment locations of devices"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); } } - private void removeEnrollmentDeviceDetail(Connection conn, int enrollmentId) throws DeviceManagementDAOException { - PreparedStatement stmt = null; + /*** + * This method removes records of a given list of enrollments from the DM_DEVICE_INFO table + * @param conn Connection object + * @param enrollmentIds list of enrollment ids (primary keys) + * @throws DeviceManagementDAOException if deletion fails + */ + private void removeEnrollmentDeviceInfo(Connection conn, List enrollmentIds) + throws DeviceManagementDAOException { + String sql = "DELETE FROM DM_DEVICE_INFO WHERE ENROLMENT_ID = ?"; try { - String sql = "DELETE FROM DM_DEVICE_DETAIL WHERE ENROLMENT_ID = ?"; - stmt = conn.prepareStatement(sql); - stmt.setInt(1, enrollmentId); - stmt.executeUpdate(); + executeBatchOperation(conn, sql, enrollmentIds); } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while removing enrollment device detail", e); - } finally { - DeviceManagementDAOUtil.cleanupResources(stmt, null); + String msg = "Error occurred while removing enrollment info of devices"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); } } - private void removeEnrollmentDeviceLocation(Connection conn, int enrollmentId) throws DeviceManagementDAOException { - PreparedStatement stmt = null; + /*** + * This method removes records of a given list of enrollments from the DM_DEVICE_APPLICATION_MAPPING table + * @param conn Connection object + * @param enrollmentIds list of enrollment ids (primary keys) + * @throws DeviceManagementDAOException if deletion fails + */ + private void removeEnrollmentDeviceApplicationMapping(Connection conn, List enrollmentIds) + throws DeviceManagementDAOException { + String sql = "DELETE FROM DM_DEVICE_APPLICATION_MAPPING WHERE ENROLMENT_ID = ?"; try { - String sql = "DELETE FROM DM_DEVICE_LOCATION WHERE ENROLMENT_ID = ?"; - stmt = conn.prepareStatement(sql); - stmt.setInt(1, enrollmentId); - stmt.executeUpdate(); + executeBatchOperation(conn, sql, enrollmentIds); } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while removing enrollment device location", e); - } finally { - DeviceManagementDAOUtil.cleanupResources(stmt, null); + String msg = "Error occurred while removing enrollment device application mapping"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); } } - private void removeEnrollmentDeviceInfo(Connection conn, int enrollmentId) throws DeviceManagementDAOException { - PreparedStatement stmt = null; + /*** + * This method removes records of a given list of enrollments from the DM_DEVICE_OPERATION_RESPONSE table + * @param conn Connection object + * @param enrollmentIds list of enrollment ids (primary keys) + * @throws DeviceManagementDAOException if deletion fails + */ + private void removeDeviceOperationResponse(Connection conn, List enrollmentIds) + throws DeviceManagementDAOException { + String sql = "DELETE FROM DM_DEVICE_OPERATION_RESPONSE WHERE ENROLMENT_ID = ?"; try { - String sql = "DELETE FROM DM_DEVICE_INFO WHERE ENROLMENT_ID = ?"; - stmt = conn.prepareStatement(sql); - stmt.setInt(1, enrollmentId); - stmt.executeUpdate(); + executeBatchOperation(conn, sql, enrollmentIds); } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while removing enrollment device info", e); - } finally { - DeviceManagementDAOUtil.cleanupResources(stmt, null); + String msg = "Error occurred while removing device operation response"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); } } - private void removeEnrollmentDeviceApplicationMapping(Connection conn, int enrollmentId) + /*** + * This method removes records of a given list of enrollments from the DM_ENROLMENT_OP_MAPPING table + * @param conn Connection object + * @param enrollmentIds list of enrollment ids (primary keys) + * @throws DeviceManagementDAOException if deletion fails + */ + private void removeEnrollmentOperationMapping(Connection conn, List enrollmentIds) throws DeviceManagementDAOException { - PreparedStatement stmt = null; + String sql = "DELETE FROM DM_ENROLMENT_OP_MAPPING WHERE ENROLMENT_ID = ?"; try { - String sql = "DELETE FROM DM_DEVICE_APPLICATION_MAPPING WHERE ENROLMENT_ID = ?"; - stmt = conn.prepareStatement(sql); - stmt.setInt(1, enrollmentId); - stmt.executeUpdate(); + executeBatchOperation(conn, sql, enrollmentIds); } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while removing enrollment device application " + - "mapping", e); - } finally { - DeviceManagementDAOUtil.cleanupResources(stmt, null); + String msg = "Error occurred while removing enrollment operation mapping"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); } } - private void removeDeviceOperationResponse(Connection conn, int enrollmentId) throws DeviceManagementDAOException { - PreparedStatement stmt = null; + /*** + * This method removes records of a given list of enrollments from the DM_ENROLMENT table + * @param conn Connection object + * @param enrollmentIds list of enrollment ids (primary keys) + * @throws DeviceManagementDAOException if deletion fails + */ + private void removeDeviceEnrollment(Connection conn, List enrollmentIds) + throws DeviceManagementDAOException { + String sql = "DELETE FROM DM_ENROLMENT WHERE DEVICE_ID = ?"; try { - String sql = "DELETE FROM DM_DEVICE_OPERATION_RESPONSE WHERE ENROLMENT_ID = ?"; - stmt = conn.prepareStatement(sql); - stmt.setInt(1, enrollmentId); - stmt.executeUpdate(); + executeBatchOperation(conn, sql, enrollmentIds); } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while removing device operation response", e); - } finally { - DeviceManagementDAOUtil.cleanupResources(stmt, null); + String msg = "Error occurred while removing enrollments of devices"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + /*** + * This method removes records of a given list of devices from the DM_DEVICE_GROUP_MAP table + * @param conn Connection object + * @param deviceIds list of device ids (primary keys) + * @throws DeviceManagementDAOException if deletion fails + */ + private void removeDeviceGroupMapping(Connection conn, List deviceIds) throws DeviceManagementDAOException { + String sql = "DELETE FROM DM_DEVICE_GROUP_MAP WHERE DEVICE_ID = ?"; + try { + executeBatchOperation(conn, sql, deviceIds); + } catch (SQLException e) { + String msg = "Error occurred while removing device group mapping"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + /*** + * This method removes records of a given list of devices from the DM_DEVICE table + * @param conn Connection object + * @param deviceIds list of device ids (primary keys) + * @throws DeviceManagementDAOException if deletion fails + */ + private void removeDevice(Connection conn, List deviceIds) throws DeviceManagementDAOException { + String sql = "DELETE FROM DM_DEVICE WHERE ID = ?"; + try { + executeBatchOperation(conn, sql, deviceIds); + } catch (SQLException e) { + String msg = "Error occurred while removing devices."; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + /*** + * This method executes batch operations for a given list of primary keys + * where the statement only has one param of type int, following the given pattern: + * DELETE FROM TABLE WHERE ID = ? + * @param sql SQL statement + * @param conn Connection object + * @param identifiers list of device ids (primary keys) + * @throws SQLException if deletion fails. + */ + private void executeBatchOperation(Connection conn, String sql, List identifiers) throws SQLException { + try (PreparedStatement ps = conn.prepareStatement(sql)) { + if (conn.getMetaData().supportsBatchUpdates()) { + for (int identifier : identifiers) { + ps.setInt(1, identifier); + ps.addBatch(); + } + for (int i : ps.executeBatch()) { + if (i == 0 || i == Statement.SUCCESS_NO_INFO || i == Statement.EXECUTE_FAILED) { + break; + } + } + } else { + for (int enrollmentId : identifiers) { + ps.setInt(1, enrollmentId); + if (ps.executeUpdate() == 0) { + break; + } + } + } } } - private void removeEnrollmentOperationMapping(Connection conn, int enrollmentId) + private int getDeviceId(Connection conn, DeviceIdentifier deviceIdentifier, int tenantId) throws DeviceManagementDAOException { PreparedStatement stmt = null; + ResultSet rs = null; + int deviceId = -1; try { - String sql = "DELETE FROM DM_ENROLMENT_OP_MAPPING WHERE ENROLMENT_ID = ?"; + String sql = "SELECT ID FROM DM_DEVICE WHERE DEVICE_IDENTIFICATION = ? AND TENANT_ID = ?"; stmt = conn.prepareStatement(sql); - stmt.setInt(1, enrollmentId); - stmt.executeUpdate(); + stmt.setString(1, deviceIdentifier.getId()); + stmt.setInt(2, tenantId); + rs = stmt.executeQuery(); + if (rs.next()) { + deviceId = rs.getInt("ID"); + } } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while removing enrollment operation mapping", e); + throw new DeviceManagementDAOException("Error occurred while retrieving device id of the device", e); } finally { - DeviceManagementDAOUtil.cleanupResources(stmt, null); + DeviceManagementDAOUtil.cleanupResources(stmt, rs); } + return deviceId; } - private void removeDeviceEnrollment(Connection conn, int deviceId) throws DeviceManagementDAOException { + public boolean transferDevice(String deviceType, String deviceIdentifier, String owner, int destinationTenantId) + throws DeviceManagementDAOException, SQLException { + Connection conn = this.getConnection(); + int deviceId = getDeviceId(conn, new DeviceIdentifier(deviceIdentifier, deviceType), -1234); PreparedStatement stmt = null; try { - String sql = "DELETE FROM DM_ENROLMENT WHERE DEVICE_ID = ?"; + String sql = "UPDATE DM_DEVICE SET TENANT_ID = ? WHERE ID = ? AND TENANT_ID = -1234"; stmt = conn.prepareStatement(sql); - stmt.setInt(1, deviceId); + stmt.setInt(1, destinationTenantId); + stmt.setInt(2, deviceId); stmt.executeUpdate(); } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while removing device enrollment", e); + conn.rollback(); + throw new DeviceManagementDAOException("Error occurred while removing device", e); } finally { DeviceManagementDAOUtil.cleanupResources(stmt, null); } - } - - private void removeDeviceGroupMapping(Connection conn, int deviceId) throws DeviceManagementDAOException { - PreparedStatement stmt = null; try { - String sql = "DELETE FROM DM_DEVICE_GROUP_MAP WHERE DEVICE_ID = ?"; + String sql = "UPDATE DM_DEVICE_PROPERTIES SET TENANT_ID = ? " + + "WHERE DEVICE_TYPE_NAME = ? AND DEVICE_IDENTIFICATION = ? AND TENANT_ID = -1234"; stmt = conn.prepareStatement(sql); - stmt.setInt(1, deviceId); + stmt.setInt(1, destinationTenantId); + stmt.setString(2, deviceType); + stmt.setString(3, deviceIdentifier); stmt.executeUpdate(); } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while removing device group mapping", e); + throw new DeviceManagementDAOException("Error occurred while removing device", e); } finally { DeviceManagementDAOUtil.cleanupResources(stmt, null); } - } - - private void removeDevice(Connection conn, int deviceId) throws DeviceManagementDAOException { - PreparedStatement stmt = null; try { - String sql = "DELETE FROM DM_DEVICE WHERE ID = ?"; + String sql = "UPDATE DM_ENROLMENT SET TENANT_ID = ?, OWNER = ? WHERE DEVICE_ID = ? AND TENANT_ID = -1234"; stmt = conn.prepareStatement(sql); - stmt.setInt(1, deviceId); + stmt.setInt(1, destinationTenantId); + stmt.setString(2, owner); + stmt.setInt(3, deviceId); stmt.executeUpdate(); } catch (SQLException e) { throw new DeviceManagementDAOException("Error occurred while removing device", e); } finally { DeviceManagementDAOUtil.cleanupResources(stmt, null); } + return true; } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/GenericGroupDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/GenericGroupDAOImpl.java index 7ad8b9981ee..584a4f9a455 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/GenericGroupDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/GenericGroupDAOImpl.java @@ -38,7 +38,6 @@ import java.util.List; * This class represents implementation of GroupDAO */ public class GenericGroupDAOImpl extends AbstractGroupDAOImpl { - @Override public List getGroups(GroupPaginationRequest request, int tenantId) throws GroupManagementDAOException { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java index 10cbe96df23..02925778fbd 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java @@ -37,6 +37,7 @@ package org.wso2.carbon.device.mgt.core.service; import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceTransferRequest; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceNotFoundException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceTypeNotFoundException; @@ -597,7 +598,7 @@ public interface DeviceManagementProviderService { boolean disenrollDevice(DeviceIdentifier deviceId) throws DeviceManagementException; - boolean deleteDevice(DeviceIdentifier deviceId) throws DeviceManagementException; + boolean deleteDevices(List deviceIdentifiers) throws DeviceManagementException, InvalidDeviceException; boolean isEnrolled(DeviceIdentifier deviceId) throws DeviceManagementException; @@ -760,4 +761,12 @@ public interface DeviceManagementProviderService { DeviceConfiguration getDeviceConfiguration(Map propertyMap) throws DeviceManagementException, DeviceNotFoundException, UnauthorizedDeviceAccessException, AmbiguousConfigurationException; + + /** + * Transfer device from super tenant to another tenant + * + * @param deviceTransferRequest DTO of the transfer request + * @return tru if device transferee, otherwise false + */ + List transferDeviceToTenant(DeviceTransferRequest deviceTransferRequest) throws DeviceManagementException, DeviceNotFoundException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index c6fa1ebb71f..8030f4a7ef6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java @@ -51,6 +51,7 @@ import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublish import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.DeviceEnrollmentInfoNotification; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceTransferRequest; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.DeviceManager; import org.wso2.carbon.device.mgt.common.exceptions.DeviceNotFoundException; @@ -100,6 +101,7 @@ import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypePlatformDetails; import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypePlatformVersion; import org.wso2.carbon.device.mgt.core.DeviceManagementConstants; import org.wso2.carbon.device.mgt.core.DeviceManagementPluginRepository; +import org.wso2.carbon.device.mgt.core.cache.DeviceCacheKey; import org.wso2.carbon.device.mgt.core.cache.impl.DeviceCacheManagerImpl; import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig; @@ -129,6 +131,8 @@ import org.wso2.carbon.email.sender.core.EmailSendingFailedException; import org.wso2.carbon.email.sender.core.EmailTransportNotConfiguredException; import org.wso2.carbon.email.sender.core.TypedValue; import org.wso2.carbon.email.sender.core.service.EmailSenderService; +import org.wso2.carbon.stratos.common.beans.TenantInfoBean; +import org.wso2.carbon.tenant.mgt.services.TenantMgtAdminService; import org.wso2.carbon.user.api.UserStoreException; import javax.xml.bind.JAXBContext; @@ -144,6 +148,7 @@ import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Arrays; import java.util.Map; import java.util.Properties; import java.util.Set; @@ -521,72 +526,90 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } @Override - public boolean deleteDevice(DeviceIdentifier deviceId) throws DeviceManagementException { - if (deviceId == null) { - String msg = "Required values are not set to permanently delete device"; - log.error(msg); - throw new DeviceManagementException(msg); - } - if (log.isDebugEnabled()) { - log.debug("Permanently deleting device: " + deviceId.getId() + " of type '" + deviceId.getType() + "'"); - } - DeviceManager deviceManager = this.getDeviceManager(deviceId.getType()); - if (deviceManager == null) { - if (log.isDebugEnabled()) { - log.debug("Device Manager associated with the device type '" + deviceId.getType() + "' is null. " + - "Therefore, not attempting method 'deleteDevice'"); - } - return false; - } - + public boolean deleteDevices(List deviceIdentifiers) throws DeviceManagementException, InvalidDeviceException { + List deviceIds = new ArrayList<>(); + List enrollmentIds = new ArrayList<>(); + Map> deviceIdentifierMap = new HashMap<>(); + Map deviceManagerMap = new HashMap<>(); + List deviceCacheKeyList = new ArrayList<>(); int tenantId = this.getTenantId(); - - Device device = this.getDevice(deviceId, false); - if (device == null) { - if (log.isDebugEnabled()) { - log.debug("Device not found for id '" + deviceId.getId() + "'"); + List existingDevices; + try { + DeviceManagementDAOFactory.beginTransaction(); + existingDevices = deviceDAO.getDevicesByIdentifiers(deviceIdentifiers, tenantId); + if (existingDevices.size() != deviceIdentifiers.size()) { + for (Device device : existingDevices) { + deviceIdentifiers.remove(device.getDeviceIdentifier()); + } + String msg = + "Couldn't find device ids for all the requested device identifiers. " + + "Therefore payload should contain device identifiers which are not in the system. " + + "Invalid device identifiers are " + deviceIdentifiers.toString(); + log.error(msg); + DeviceManagementDAOFactory.rollbackTransaction(); + throw new InvalidDeviceException(msg); } - return false; - } - - if (!device.getEnrolmentInfo().getStatus().equals(EnrolmentInfo.Status.REMOVED)) { - String msg = "Device " + deviceId.getId() + " of type " + deviceId.getType() + " is not dis-enrolled to " + - "permanently delete the device"; - log.error(msg); - throw new DeviceManagementException(msg); - } else { - try { - DeviceManagementDAOFactory.beginTransaction(); - deviceDAO.deleteDevice(deviceId, tenantId); + for (Device device : existingDevices) { + if (!device.getEnrolmentInfo().getStatus().equals(EnrolmentInfo.Status.REMOVED)) { + String msg = "Device " + device.getDeviceIdentifier() + " of type " + device.getType() + + " is not dis-enrolled to permanently delete the device"; + log.error(msg); + DeviceManagementDAOFactory.rollbackTransaction(); + throw new InvalidDeviceException(msg); + } + DeviceCacheKey deviceCacheKey = new DeviceCacheKey(); + deviceCacheKey.setDeviceId(device.getDeviceIdentifier()); + deviceCacheKey.setDeviceType(device.getType()); + deviceCacheKey.setTenantId(tenantId); + deviceCacheKeyList.add(deviceCacheKey); + deviceIds.add(device.getId()); + enrollmentIds.add(device.getEnrolmentInfo().getId()); + if (deviceIdentifierMap.containsKey(device.getType())) { + deviceIdentifierMap.get(device.getType()).add(device.getDeviceIdentifier()); + } else { + deviceIdentifierMap.put(device.getType(), + new ArrayList<>(Arrays.asList(device.getDeviceIdentifier()))); + DeviceManager deviceManager = this.getDeviceManager(device.getType()); + if (deviceManager == null) { + if (log.isDebugEnabled()) { + log.debug("Device Manager associated with the device type '" + + device.getType() + "' is null. Therefore, not attempting method 'deleteDevice'"); + } + return false; + } + deviceManagerMap.put(device.getType(), deviceManager); + } + } + //deleting device from the core + deviceDAO.deleteDevices(deviceIdentifiers, deviceIds, enrollmentIds); + for (Map.Entry entry : deviceManagerMap.entrySet()) { try { - deviceManager.deleteDevice(deviceId, device); + // deleting device from the plugin level + entry.getValue().deleteDevices(deviceIdentifierMap.get(entry.getKey())); } catch (DeviceManagementException e) { - String msg = "Error occurred while permanently deleting '" + deviceId.getType() + - "' device with the identifier '" + deviceId.getId() + "' in plugin."; + String msg = "Error occurred while permanently deleting '" + entry.getKey() + + "' devices with the identifiers: '" + deviceIdentifierMap.get(entry.getKey()) + + "' in plugin."; log.error(msg, e); + // a DeviceManagementException is thrown when the device deletion fails from the plugin level. + // Here, that exception is caught and a DeviceManagementDAOException is thrown throw new DeviceManagementDAOException(msg, e); } - DeviceManagementDAOFactory.commitTransaction(); - this.removeDeviceFromCache(deviceId); - } catch (DeviceManagementDAOException e) { - DeviceManagementDAOFactory.rollbackTransaction(); - String msg = "Error occurred while permanently deleting '" + deviceId.getType() + - "' device with the identifier '" + deviceId.getId() + "'"; - log.error(msg, e); - throw new DeviceManagementException(msg, e); - } catch (TransactionManagementException e) { - String msg = "Error occurred while initiating transaction"; - log.error(msg, e); - throw new DeviceManagementException(msg, e); - } catch (Exception e) { - String msg = "Error occurred while permanently deleting device: " + deviceId.getId(); - log.error(msg, e); - throw new DeviceManagementException(msg, e); - } finally { - DeviceManagementDAOFactory.closeConnection(); } + DeviceManagementDAOFactory.commitTransaction(); + this.removeDevicesFromCache(deviceCacheKeyList); + return true; + } catch (TransactionManagementException e) { + String msg = "Error occurred while initiating transaction"; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } catch (DeviceManagementDAOException e) { + DeviceManagementDAOFactory.rollbackTransaction(); + String msg = "Error occurred while permanently deleting '" + deviceIdentifiers + + "' devices"; + log.error(msg, e); + throw new DeviceManagementException(msg, e); } - return true; } @Override @@ -1407,29 +1430,26 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv publicSharedDeviceTypesInDB = deviceTypeDAO.getSharedDeviceTypes(); Map registeredTypes = pluginRepository.getAllDeviceManagementServices(tenantId); - Set deviceTypeSetForTenant = new HashSet<>(); - - if (registeredTypes != null) { - if (deviceTypesProvidedByTenant != null) { - for (DeviceType deviceType : deviceTypesProvidedByTenant) { - DeviceTypeServiceIdentifier providerKey = new DeviceTypeServiceIdentifier(deviceType.getName(), tenantId); - if (registeredTypes.get(providerKey) != null || deviceType.getDeviceTypeMetaDefinition() != null) { - deviceTypesResponse.add(deviceType.getName()); - deviceTypeSetForTenant.add(deviceType.getName()); - } + // Get the device from the public space, however if there is another device with same name then give + // priority to that + if (deviceTypesProvidedByTenant != null) { + for (DeviceType deviceType : deviceTypesProvidedByTenant) { + deviceTypesResponse.add(deviceType.getName()); + } + } + if (publicSharedDeviceTypesInDB != null) { + for (String deviceType: publicSharedDeviceTypesInDB) { + if (!deviceTypesResponse.contains(deviceType)) { + deviceTypesResponse.add(deviceType); } } - // Get the device from the public space, however if there is another device with same name then give - // priority to that - if (publicSharedDeviceTypesInDB != null) { - for (String deviceType : publicSharedDeviceTypesInDB) { - DeviceTypeServiceIdentifier providerKey = new DeviceTypeServiceIdentifier(deviceType); - if (registeredTypes.get(providerKey) != null && !deviceTypeSetForTenant.contains(deviceType)) { - deviceTypesResponse.add(deviceType); - } + } + if (registeredTypes != null) { + for (DeviceTypeServiceIdentifier deviceType: registeredTypes.keySet()) { + if (!deviceTypesResponse.contains(deviceType.getDeviceType())) { + deviceTypesResponse.add(deviceType.getDeviceType()); } } - } } catch (DeviceManagementDAOException e) { String msg = "Error occurred while obtaining the device types."; @@ -2979,6 +2999,14 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv DeviceCacheManagerImpl.getInstance().removeDeviceFromCache(deviceIdentifier, this.getTenantId()); } + /*** + * This method removes a given list of devices from the cache + * @param deviceList list of DeviceCacheKey objects + */ + private void removeDevicesFromCache(List deviceList) { + DeviceCacheManagerImpl.getInstance().removeDevicesFromCache(deviceList); + } + @Override public List findGeoClusters(String deviceType, GeoCoordinate southWest, GeoCoordinate northEast, int geohashLength) throws DeviceManagementException { @@ -3486,12 +3514,12 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } try { - Device device = this.getDevice(new DeviceIdentifier(deviceProperties.getDeviceIdentifier(), - deviceProperties.getDeviceTypeName()), false); - String owner = device.getEnrolmentInfo().getOwner(); PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); ctx.setTenantId(Integer.parseInt(deviceProperties.getTenantId()), true); + Device device = this.getDevice(new DeviceIdentifier(deviceProperties.getDeviceIdentifier(), + deviceProperties.getDeviceTypeName()), false); + String owner = device.getEnrolmentInfo().getOwner(); PlatformConfiguration configuration = this.getConfiguration(device.getType()); List configurationEntries = new ArrayList<>(); if (configuration != null) { @@ -3503,6 +3531,65 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } } + @Override + public List transferDeviceToTenant(DeviceTransferRequest deviceTransferRequest) + throws DeviceManagementException, DeviceNotFoundException { + if (log.isDebugEnabled()) { + log.debug("Attempting to transfer devices to '" + + deviceTransferRequest.getDestinationTenant() + "'"); + } + List enrolledDevices = new ArrayList<>(); + DeviceIdentifier deviceIdentifier; + for (String deviceId : deviceTransferRequest.getDeviceIds()) { + deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(deviceId); + deviceIdentifier.setType(deviceTransferRequest.getDeviceType()); + if (isEnrolled(deviceIdentifier)) { + enrolledDevices.add(deviceId); + } else { + log.warn("Device '" + deviceId + "' is not enrolled with super tenant. Hence excluding from transferring"); + } + } + + if (enrolledDevices.isEmpty()) { + throw new DeviceNotFoundException("No any enrolled device found to transfer"); + } + + int destinationTenantId; + String owner; + try { + TenantMgtAdminService tenantMgtAdminService = new TenantMgtAdminService(); + TenantInfoBean tenantInfoBean = tenantMgtAdminService.getTenant(deviceTransferRequest.getDestinationTenant()); + destinationTenantId = tenantInfoBean.getTenantId(); + owner = tenantInfoBean.getAdmin(); + } catch (Exception e) { + String msg = "Error getting destination tenant id and admin from domain'" + + deviceTransferRequest.getDestinationTenant() + "'"; + log.error(msg); + throw new DeviceManagementException(msg, e); + } + try { + DeviceManagementDAOFactory.openConnection(); + List movedDevices = new ArrayList<>(); + for (String deviceId : enrolledDevices) { + if (deviceDAO.transferDevice(deviceTransferRequest.getDeviceType(), deviceId, owner, destinationTenantId)){ + movedDevices.add(deviceId); + } else { + log.warn("Device '" + deviceId + "' not transferred to tenant " + destinationTenantId); + } + } + DeviceManagementDAOFactory.commitTransaction(); + return movedDevices; + } catch (SQLException | DeviceManagementDAOException e) { + DeviceManagementDAOFactory.rollbackTransaction(); + String msg = "Error in transferring devices to tenant '" + deviceTransferRequest.getDestinationTenant() + "'"; + log.error(msg); + throw new DeviceManagementException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + /** * Wrap the device configuration data into DeviceConfiguration bean * @param device Device queried using the properties diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderService.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderService.java index 182606eaa51..4e3dda809d6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderService.java @@ -164,7 +164,7 @@ public interface GroupManagementProviderService { * @return list of devices in group. * @throws GroupManagementException */ - List getDevices(int groupId, int startIndex, int rowCount) throws GroupManagementException; + List getDevices(int groupId, int startIndex, int rowCount, boolean requireDeviceProps) throws GroupManagementException; List getAllDevicesOfGroup(String groupName) throws GroupManagementException; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceImpl.java index 0f115cd7881..7266bf83da0 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceImpl.java @@ -36,6 +36,8 @@ import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException; import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException; import org.wso2.carbon.device.mgt.common.group.mgt.GroupNotExistException; import org.wso2.carbon.device.mgt.common.group.mgt.RoleDoesNotExistException; +import org.wso2.carbon.device.mgt.core.dao.DeviceDAO; +import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory; import org.wso2.carbon.device.mgt.core.dao.GroupDAO; import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOException; import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOFactory; @@ -56,12 +58,14 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid private static Log log = LogFactory.getLog(GroupManagementProviderServiceImpl.class); private GroupDAO groupDAO; + private DeviceDAO deviceDAO; /** * Set groupDAO from GroupManagementDAOFactory when class instantiate. */ public GroupManagementProviderServiceImpl() { this.groupDAO = GroupManagementDAOFactory.getGroupDAO(); + this.deviceDAO = DeviceManagementDAOFactory.getDeviceDAO(); } /** @@ -627,7 +631,7 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid * {@inheritDoc} */ @Override - public List getDevices(int groupId, int startIndex, int rowCount) + public List getDevices(int groupId, int startIndex, int rowCount, boolean requireDeviceProps) throws GroupManagementException { if (log.isDebugEnabled()) { log.debug("Group devices of group: " + groupId + " start index " + startIndex + " row count " + rowCount); @@ -638,6 +642,16 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid rowCount = DeviceManagerUtil.validateDeviceListPageSize(rowCount); GroupManagementDAOFactory.openConnection(); devices = this.groupDAO.getDevices(groupId, startIndex, rowCount, tenantId); + + if(requireDeviceProps) { + DeviceManagementDAOFactory.openConnection(); + for (Device device : devices) { + Device retrievedDevice = deviceDAO.getDeviceProps(device.getDeviceIdentifier(), tenantId); + if (retrievedDevice != null && !retrievedDevice.getProperties().isEmpty()) { + device.setProperties(retrievedDevice.getProperties()); + } + } + } } catch (GroupManagementDAOException | SQLException | DeviceManagementException e) { String msg = "Error occurred while getting devices in group."; log.error(msg, e); @@ -648,6 +662,9 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid throw new GroupManagementException(msg, e); } finally { GroupManagementDAOFactory.closeConnection(); + if(requireDeviceProps){ + DeviceManagementDAOFactory.closeConnection(); + } } return devices; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/TestDeviceManager.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/TestDeviceManager.java index b87a7ea5a68..30f2ec1141e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/TestDeviceManager.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/TestDeviceManager.java @@ -61,8 +61,7 @@ public class TestDeviceManager implements DeviceManager { } @Override - public boolean deleteDevice(DeviceIdentifier deviceId, Device device) throws DeviceManagementException { - return true; + public void deleteDevices(List deviceIdentifiers) throws DeviceManagementException { } @Override diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceNegativeTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceNegativeTest.java index 528b64a5e8b..719ebe5576a 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceNegativeTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceNegativeTest.java @@ -138,7 +138,7 @@ public class GroupManagementProviderServiceNegativeTest extends BaseDeviceManage @Test(description = "This method tests the getDevices method under negative circumstances", expectedExceptions = {GroupManagementException.class}) public void testGetDevicesWithPagination() throws GroupManagementException { - groupManagementProviderService.getDevices(1, 0, 10); + groupManagementProviderService.getDevices(1, 0, 10, false); } @Test(description = "This method tests the getGroupCount with username when the user name is given as null", diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceTest.java index 02296282026..3f96a8aede4 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceTest.java @@ -225,7 +225,7 @@ public class GroupManagementProviderServiceTest extends BaseDeviceManagementTest @Test(dependsOnMethods = ("createGroup")) public void getDevices() throws GroupManagementException { - List devices = groupManagementProviderService.getDevices(1, 1, 50); + List devices = groupManagementProviderService.getDevices(1, 1, 50, false); Assert.assertNotNull(devices); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java index 5cc28bc8ec3..917a7090484 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java @@ -587,31 +587,36 @@ public class DeviceTypeManager implements DeviceManager { } @Override - public boolean deleteDevice(DeviceIdentifier deviceIdentifier, Device device) throws DeviceManagementException { + public void deleteDevices(List deviceIdentifierList) throws DeviceManagementException { if (propertiesExist) { - boolean status; - Device existingDevice = this.getDevice(deviceIdentifier); - if (existingDevice == null) { - return false; - } try { if (log.isDebugEnabled()) { - log.debug("Deleting the details of " + deviceType + " device : " + device.getDeviceIdentifier()); + log.debug("Deleting the details of " + deviceType + " devices : " + deviceIdentifierList); } deviceTypePluginDAOManager.getDeviceTypeDAOHandler().beginTransaction(); - status = deviceTypePluginDAOManager.getDeviceDAO().deleteDevice(existingDevice); - deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction(); + if (deviceTypePluginDAOManager.getDeviceDAO().deleteDevices(deviceIdentifierList)) { + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction(); + } else { + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); + String msg = "Error occurred while deleting the " + deviceType + " devices: '" + + deviceIdentifierList; + log.error(msg); + throw new DeviceManagementException(msg); + } } catch (DeviceTypeMgtPluginException e) { deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); - throw new DeviceManagementException( - "Error occurred while deleting the " + deviceType + " device: '" + - device.getDeviceIdentifier() + "'", e); + if (log.isDebugEnabled()) { + log.debug("Error occurred while deleting the " + deviceType + " devices: '" + + deviceIdentifierList + "'. Transaction rolled back"); + } + String msg= "Error occurred while deleting the " + deviceType + " devices: '" + + deviceIdentifierList; + log.error(msg,e); + throw new DeviceManagementException(msg, e); } finally { deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); } - return status; } - return true; } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypePluginDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypePluginDAOImpl.java index 00c9e4ff402..e1427897d24 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypePluginDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypePluginDAOImpl.java @@ -39,6 +39,7 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypeMgtPluginException; import org.wso2.carbon.device.mgt.extensions.device.type.template.util.DeviceTypeUtils; @@ -46,6 +47,7 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Statement; import java.util.ArrayList; import java.util.List; @@ -215,30 +217,39 @@ public class DeviceTypePluginDAOImpl implements PluginDAO { } @Override - public boolean deleteDevice(Device device) throws DeviceTypeMgtPluginException { - boolean status = false; - Connection conn; - PreparedStatement stmt = null; + public boolean deleteDevices(List deviceIdentifiers) throws DeviceTypeMgtPluginException { try { - conn = deviceTypeDAOHandler.getConnection(); - stmt = conn.prepareStatement(deleteDBQueryForDeleteDevice); - stmt.setString(1, device.getDeviceIdentifier()); - int rows = stmt.executeUpdate(); - if (rows > 0) { - status = true; - if (log.isDebugEnabled()) { - log.debug("Device " + device.getDeviceIdentifier() + " data has been deleted."); + Connection conn = deviceTypeDAOHandler.getConnection(); + boolean status = true; + try (PreparedStatement ps = conn.prepareStatement(deleteDBQueryForDeleteDevice)) { + if (conn.getMetaData().supportsBatchUpdates()) { + for (String deviceId : deviceIdentifiers) { + ps.setString(1, deviceId); + ps.addBatch(); + } + for (int i : ps.executeBatch()) { + if (i == 0 || i == Statement.SUCCESS_NO_INFO || i == Statement.EXECUTE_FAILED) { + status = false; + break; + } + } + } else { + for (String deviceId : deviceIdentifiers) { + ps.setString(1, deviceId); + if (ps.executeUpdate() == 0) { + status = false; + break; + } + } } } + return status; } catch (SQLException e) { - String msg = "Error occurred while deleting the device '" + device.getDeviceIdentifier() + "' data in " - + deviceDAODefinition.getDeviceTableName(); + String msg = "Error occurred while deleting the data in " + + deviceDAODefinition.getDeviceTableName(); log.error(msg, e); throw new DeviceTypeMgtPluginException(msg, e); - } finally { - DeviceTypeUtils.cleanupResources(stmt, null); } - return status; } private String getDeviceTableColumnNames() { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/PluginDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/PluginDAO.java index a6bdbb79dfe..5ea6a1197b1 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/PluginDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/PluginDAO.java @@ -50,5 +50,5 @@ public interface PluginDAO { List getAllDevices() throws DeviceTypeMgtPluginException; - boolean deleteDevice(Device device) throws DeviceTypeMgtPluginException; + boolean deleteDevices(List deviceIdentifiers) throws DeviceTypeMgtPluginException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/PropertyBasedPluginDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/PropertyBasedPluginDAOImpl.java index 9b01e290d39..7cc32f6315d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/PropertyBasedPluginDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/PropertyBasedPluginDAOImpl.java @@ -46,6 +46,7 @@ import org.wso2.carbon.device.mgt.extensions.device.type.template.util.DeviceTyp import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.Statement; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; @@ -218,22 +219,38 @@ public class PropertyBasedPluginDAOImpl implements PluginDAO { } @Override - public boolean deleteDevice(Device device) throws DeviceTypeMgtPluginException { - Connection conn; - PreparedStatement stmt = null; + public boolean deleteDevices(List deviceIdentifiers) throws DeviceTypeMgtPluginException { try { - conn = deviceTypeDAOHandler.getConnection(); - stmt = conn.prepareStatement("DELETE FROM DM_DEVICE_PROPERTIES WHERE DEVICE_IDENTIFICATION = ?"); - stmt.setString(1, device.getDeviceIdentifier()); - stmt.executeUpdate(); - return true; + Connection conn = deviceTypeDAOHandler.getConnection(); + boolean status = true; + try (PreparedStatement ps = conn.prepareStatement("DELETE FROM DM_DEVICE_PROPERTIES WHERE DEVICE_IDENTIFICATION = ?")) { + if (conn.getMetaData().supportsBatchUpdates()) { + for (String deviceId : deviceIdentifiers) { + ps.setString(1, deviceId); + ps.addBatch(); + } + for (int i : ps.executeBatch()) { + if (i == 0 || i == Statement.SUCCESS_NO_INFO || i == Statement.EXECUTE_FAILED) { + status = false; + break; + } + } + } else { + for (String deviceId : deviceIdentifiers) { + ps.setString(1, deviceId); + if (ps.executeUpdate() == 0) { + status = false; + break; + } + } + } + } + return status; } catch (SQLException e) { - String msg = "Error occurred while deleting the device '" + device.getDeviceIdentifier() + "' data on" - + deviceType; + String msg = "Error occurred while deleting the data of the devices: '" + deviceIdentifiers + "'of type: " + + deviceType; log.error(msg, e); throw new DeviceTypeMgtPluginException(msg, e); - } finally { - DeviceTypeUtils.cleanupResources(stmt, null); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.dynamic.platform.configuration/configuration.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.dynamic.platform.configuration/configuration.hbs index b4c64f7fd52..7c3f83eec5a 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.dynamic.platform.configuration/configuration.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.dynamic.platform.configuration/configuration.hbs @@ -32,10 +32,3 @@ -{{#zone "bottomJs"}} - -{{/zone}} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/configuration.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/configuration.hbs index 597b38ce182..8e4131fa19e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/configuration.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/configuration.hbs @@ -193,4 +193,13 @@ {{/zone}} {{#zone "bottomJs"}} {{js "js/platform-configuration.js"}} + {{/zone}} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/public/js/platform-configuration.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/public/js/platform-configuration.js index d3a2152b06a..9e4176066b0 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/public/js/platform-configuration.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/public/js/platform-configuration.js @@ -163,7 +163,7 @@ var loadDynamicDeviceTypeConfig = function (deviceType) { configAPI, function (data) { data = JSON.parse(data); - var fieldWrapper = "#" + deviceType + "-config-field-wrapper"; + var fieldWrapper = "#" + escapeSelector(deviceType + "-config-field-wrapper"); $(fieldWrapper).html(""); if (data.configuration) { var config; @@ -197,15 +197,18 @@ var loadDynamicDeviceTypeConfig = function (deviceType) { var onDynamicConfigSubmit = function (deviceType) { - var errorMsgWrapper = "#" + deviceType + "-config-error-msg"; - var errorMsg = "#" + deviceType + "-config-error-msg span"; + var errorMsgWrapper = "#" + escapeSelector(deviceType + "-config-error-msg"); + var errorMsg = "#" + escapeSelector(deviceType + "-config-error-msg span"); + var filedRaw = '.' + escapeSelector(deviceType + '-config-row'); + var filedName = "." + escapeSelector(deviceType + "-config-name"); + var filedValue = "." + escapeSelector(deviceType + "-config-value"); var addConfigFormData = {}; var configList = []; - $('.' + deviceType + '-config-row').each(function () { - var configName = $(this).find("." + deviceType + "-config-name").val(); - var configVal = $(this).find("." + deviceType + "-config-value").val(); + $(filedRaw).each(function () { + var configName = $(this).find(filedName).val(); + var configVal = $(this).find(filedValue).val(); if (configName && configName.trim() !== "" && configVal && configVal.trim() !== "") { var configurationEntry = {}; configurationEntry.name = configName.trim(); @@ -252,7 +255,8 @@ var onDynamicConfigSubmit = function (deviceType) { }; var onDynamicConfigAddNew = function (deviceType, name, value) { - $("#" + deviceType + "-config-field-wrapper").append( + var fieldWrapper = "#" + escapeSelector(deviceType + "-config-field-wrapper"); + $(fieldWrapper).append( '
' + '
' + @@ -272,5 +276,13 @@ var onDynamicConfigAddNew = function (deviceType, name, value) { }; var onDynamicConfigRemove = function (deviceType, rawId) { - $("#" + deviceType + "-config-row-" + rawId).remove() + var fieldWrapper = "#" + escapeSelector(deviceType + "-config-row-" + rawId); + $(fieldWrapper).remove() +}; + +var escapeSelector = function (text) { + return text.replace( + /([$%&()*+,./:;<=>?@\[\\\]^\{|}~])/g, + '\\$1' + ); }; \ No newline at end of file diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mock/TypeXDeviceManager.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mock/TypeXDeviceManager.java index ad05789b46e..8e2790efbb7 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mock/TypeXDeviceManager.java +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mock/TypeXDeviceManager.java @@ -79,8 +79,7 @@ public class TypeXDeviceManager implements DeviceManager { } @Override - public boolean deleteDevice(DeviceIdentifier deviceId, Device device) throws DeviceManagementException { - return false; + public void deleteDevices(List deviceIdentifiers) throws DeviceManagementException { } @Override diff --git a/pom.xml b/pom.xml index dec0bcd9e8c..1a6f5035224 100644 --- a/pom.xml +++ b/pom.xml @@ -1761,6 +1761,12 @@ ${tomcat.websocket.version} provided + + org.wso2.carbon.multitenancy + org.wso2.carbon.tenant.mgt + ${carbon.multitenancy.version} + provided +