mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
Add device transferring across tenants
This commit is contained in:
parent
30d4a5707a
commit
2c7463a072
@ -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);
|
||||
}
|
||||
|
||||
@ -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<String> 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("&", "\",\"");
|
||||
|
||||
@ -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<String> 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<String> getDeviceIds() {
|
||||
return deviceIds;
|
||||
}
|
||||
|
||||
public void setDeviceId(List<String> deviceIds) {
|
||||
this.deviceIds = deviceIds;
|
||||
}
|
||||
|
||||
public String getDestinationTenant() {
|
||||
return destinationTenant;
|
||||
}
|
||||
|
||||
public void setDestinationTenant(String destinationTenant) {
|
||||
this.destinationTenant = destinationTenant;
|
||||
}
|
||||
|
||||
}
|
||||
@ -356,6 +356,10 @@
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-api-mockito</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.multitenancy</groupId>
|
||||
<artifactId>org.wso2.carbon.tenant.mgt</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@ -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;
|
||||
@ -529,4 +530,7 @@ public interface DeviceDAO {
|
||||
* @throws DeviceManagementDAOException
|
||||
*/
|
||||
void deleteDevice(DeviceIdentifier deviceIdentifier, int tenantId) throws DeviceManagementDAOException;
|
||||
|
||||
boolean transferDevice(String deviceType, String deviceId, String owner, int destinationTenantId)
|
||||
throws DeviceManagementDAOException, SQLException;
|
||||
}
|
||||
|
||||
@ -1937,4 +1937,49 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
|
||||
DeviceManagementDAOUtil.cleanupResources(stmt, null);
|
||||
}
|
||||
}
|
||||
|
||||
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 = "UPDATE DM_DEVICE SET TENANT_ID = ? WHERE ID = ? AND TENANT_ID = -1234";
|
||||
stmt = conn.prepareStatement(sql);
|
||||
stmt.setInt(1, destinationTenantId);
|
||||
stmt.setInt(2, deviceId);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
conn.rollback();
|
||||
throw new DeviceManagementDAOException("Error occurred while removing device", e);
|
||||
} finally {
|
||||
DeviceManagementDAOUtil.cleanupResources(stmt, null);
|
||||
}
|
||||
try {
|
||||
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, destinationTenantId);
|
||||
stmt.setString(2, deviceType);
|
||||
stmt.setString(3, deviceIdentifier);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
throw new DeviceManagementDAOException("Error occurred while removing device", e);
|
||||
} finally {
|
||||
DeviceManagementDAOUtil.cleanupResources(stmt, null);
|
||||
}
|
||||
try {
|
||||
String sql = "UPDATE DM_ENROLMENT SET TENANT_ID = ?, OWNER = ? WHERE DEVICE_ID = ? AND TENANT_ID = -1234";
|
||||
stmt = conn.prepareStatement(sql);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
@ -760,4 +761,12 @@ public interface DeviceManagementProviderService {
|
||||
DeviceConfiguration getDeviceConfiguration(Map<String, String> 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<String> transferDeviceToTenant(DeviceTransferRequest deviceTransferRequest) throws DeviceManagementException, DeviceNotFoundException;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
@ -129,6 +130,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;
|
||||
@ -3503,6 +3506,65 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> transferDeviceToTenant(DeviceTransferRequest deviceTransferRequest)
|
||||
throws DeviceManagementException, DeviceNotFoundException {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Attempting to transfer devices to '" +
|
||||
deviceTransferRequest.getDestinationTenant() + "'");
|
||||
}
|
||||
List<String> 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<String> 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
|
||||
|
||||
6
pom.xml
6
pom.xml
@ -1761,6 +1761,12 @@
|
||||
<version>${tomcat.websocket.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.multitenancy</groupId>
|
||||
<artifactId>org.wso2.carbon.tenant.mgt</artifactId>
|
||||
<version>${carbon.multitenancy.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user