From 7381ece84726d783d4e6626f8d6fb808638e149b Mon Sep 17 00:00:00 2001 From: Pahansith Gunathilake Date: Wed, 29 Jan 2020 20:46:44 +0000 Subject: [PATCH] Introduce device type filtering and limit results in device types retrieve endpoint --- .../api/DeviceTypeManagementService.java | 22 ++++++- .../impl/DeviceTypeManagementServiceImpl.java | 29 +++++++- .../impl/DeviceTypeManagementServiceTest.java | 15 +++-- .../device/mgt/common/PaginationRequest.java | 9 +++ .../device/mgt/core/dao/DeviceTypeDAO.java | 10 +++ .../mgt/core/dao/impl/DeviceTypeDAOImpl.java | 66 ++++++++++++++++++- .../DeviceManagementProviderService.java | 14 +++- .../DeviceManagementProviderServiceImpl.java | 20 ++++++ 8 files changed, 174 insertions(+), 11 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java index 132f2c7f5a7..f92cf407b10 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java @@ -167,7 +167,27 @@ public interface DeviceTypeManagementService { "Example: Mon, 05 Jan 2014 15:10:00 +0200" ) @HeaderParam("If-Modified-Since") - String ifModifiedSince); + String ifModifiedSince, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + required = false) + @QueryParam("offset") + int offset, + @ApiParam( + name = "limit", + value = "Provide how many device details you require from the starting " + + "pagination index/offset.", + required = false) + @QueryParam("limit") + int limit, + @ApiParam( + name = "filter", + value = "Provide criteria for filter device type name", + required = false) + @QueryParam("filter") + String filter + ); @GET @Path("/{type}") diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java index 85279aed2fa..393fd31ff59 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java @@ -38,6 +38,7 @@ package org.wso2.carbon.device.mgt.jaxrs.service.impl; 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.PaginationRequest; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceTypeNotFoundException; import org.wso2.carbon.device.mgt.common.Feature; @@ -49,6 +50,8 @@ import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceTypeManagementService; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.InputValidationException; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; import javax.validation.constraints.Size; @@ -68,9 +71,26 @@ public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementServ @GET @Override - public Response getDeviceTypes(@HeaderParam("If-Modified-Since") String ifModifiedSince) { + public Response getDeviceTypes(@HeaderParam("If-Modified-Since") String ifModifiedSince, + @QueryParam("offset") int offset, + @QueryParam("limit") int limit, + @QueryParam("filter") String filter) { + try { - List deviceTypes = DeviceMgtAPIUtils.getDeviceManagementService().getDeviceTypes(); + RequestValidationUtil.validatePaginationParameters(offset, limit); + List deviceTypes; + if (offset == 0 && limit == 0 && StringUtils.isEmpty(filter)) { + deviceTypes = DeviceMgtAPIUtils.getDeviceManagementService() + .getDeviceTypes(); + } else { + PaginationRequest paginationRequest = new PaginationRequest(offset, limit); + if (!StringUtils.isEmpty(filter)) { + paginationRequest.setFilter(filter); + } + deviceTypes = DeviceMgtAPIUtils.getDeviceManagementService() + .getDeviceTypes(paginationRequest); + } + List filteredDeviceTypes = new ArrayList<>(); for (DeviceType deviceType : deviceTypes) { filteredDeviceTypes.add(clearMetaEntryInfo(deviceType)); @@ -80,7 +100,12 @@ public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementServ String msg = "Error occurred at server side while fetching device type."; log.error(msg, e); return Response.serverError().entity(msg).build(); + } catch (InputValidationException e) { + String msg = "Invalid pagination parameters"; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } + } @Override diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceTest.java index be7917ed837..09ef5b50a9d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceTest.java @@ -78,7 +78,8 @@ public class DeviceTypeManagementServiceTest { public void testExistingDeviceType() throws Exception { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) .toReturn(this.deviceManagementProviderService); - Response response = this.deviceTypeManagementService.getDeviceTypes(""); + Response response = this.deviceTypeManagementService + .getDeviceTypes("", 0, 0, null); Assert.assertNotNull(response, "The response object is null."); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), "The response states should be 200."); @@ -89,7 +90,8 @@ public class DeviceTypeManagementServiceTest { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) .toReturn(this.deviceManagementProviderService); Mockito.when(this.deviceManagementProviderService.getDeviceTypes()).thenThrow(new DeviceManagementException()); - Response response = this.deviceTypeManagementService.getDeviceTypes(MODIFIED_SINCE); + Response response = this.deviceTypeManagementService + .getDeviceTypes(MODIFIED_SINCE, 0, 0, null); Assert.assertNotNull(response, "The response object is null."); Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), "The response status should be 500."); @@ -102,7 +104,8 @@ public class DeviceTypeManagementServiceTest { .toReturn(this.deviceManagementProviderService); Mockito.when(this.deviceManagementProviderService.getDeviceTypes()).thenThrow(new DeviceManagementException()); - Response response = this.deviceTypeManagementService.getDeviceTypes(MODIFIED_SINCE); + Response response = this.deviceTypeManagementService + .getDeviceTypes(MODIFIED_SINCE, 0, 0, null); Assert.assertNotNull(response, "The response object is null."); Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), "The response status should be 500."); @@ -152,7 +155,8 @@ public class DeviceTypeManagementServiceTest { public void testGetDeviceTypes() throws Exception { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) .toReturn(this.deviceManagementProviderService); - Response response = this.deviceTypeManagementService.getDeviceTypes(MODIFIED_SINCE); + Response response = this.deviceTypeManagementService + .getDeviceTypes(MODIFIED_SINCE, 0, 0, null); Assert.assertNotNull(response, "The response object is null."); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), "The response status should be 200."); @@ -164,7 +168,8 @@ public class DeviceTypeManagementServiceTest { .toReturn(this.deviceManagementProviderService); List deviceTypes = DeviceMgtAPITestHelper.getDummyDeviceTypeList(5); Mockito.when(this.deviceManagementProviderService.getDeviceTypes()).thenReturn(deviceTypes); - Response response = this.deviceTypeManagementService.getDeviceTypes(MODIFIED_SINCE); + Response response = this.deviceTypeManagementService + .getDeviceTypes(MODIFIED_SINCE, 0, 0, null); Assert.assertNotNull(response, "The response object is null."); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), "The response state should be 200"); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/PaginationRequest.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/PaginationRequest.java index 4502400d605..aed55ea50c1 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/PaginationRequest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/PaginationRequest.java @@ -40,6 +40,7 @@ public class PaginationRequest { private String ownerRole; private Map property = new HashMap<>(); private Date since; + private String filter; public PaginationRequest(int start, int rowCount) { this.startIndex = start; @@ -152,6 +153,14 @@ public class PaginationRequest { return temp; } + public String getFilter() { + return filter; + } + + public void setFilter(String filter) { + this.filter = filter; + } + @Override public String toString() { return "Device type '" + this.deviceType + "' Device Name '" + this.deviceName + "' row count: " + this.rowCount diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceTypeDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceTypeDAO.java index def5ee32ffa..1bea5f35ed8 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceTypeDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceTypeDAO.java @@ -34,6 +34,7 @@ */ package org.wso2.carbon.device.mgt.core.dao; +import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.dto.DeviceTypeVersion; @@ -154,4 +155,13 @@ public interface DeviceTypeDAO { * @throws DeviceManagementDAOException Might occur while executing database queries */ void deleteDeviceType(int tenantId, int deviceTypeId) throws DeviceManagementDAOException; + + /** + * + * @param tenantId current tenant's ID + * @param paginationRequest request object for filter data. Using only offset limit and filter + * @return List of filtered device types + */ + List getDeviceTypes(int tenantId, PaginationRequest paginationRequest) + throws DeviceManagementDAOException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/DeviceTypeDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/DeviceTypeDAOImpl.java index 68a029c90ec..fbf54324e69 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/DeviceTypeDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/DeviceTypeDAOImpl.java @@ -35,6 +35,10 @@ package org.wso2.carbon.device.mgt.core.dao.impl; import com.google.gson.Gson; +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.PaginationRequest; import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeMetaDefinition; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory; @@ -42,6 +46,7 @@ import org.wso2.carbon.device.mgt.core.dao.DeviceTypeDAO; import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil; import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.dto.DeviceTypeVersion; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl; import java.io.BufferedWriter; import java.io.File; @@ -60,6 +65,8 @@ import java.util.List; public class DeviceTypeDAOImpl implements DeviceTypeDAO { + private static Log log = LogFactory.getLog(DeviceTypeDAOImpl.class); + @Override public void addDeviceType(DeviceType deviceType, int providerTenantId, boolean isSharedWithAllTenants) throws DeviceManagementDAOException { @@ -308,6 +315,64 @@ public class DeviceTypeDAOImpl implements DeviceTypeDAO { } } + @Override + public List getDeviceTypes(int tenantId, PaginationRequest paginationRequest) throws + DeviceManagementDAOException { + List deviceTypes = new ArrayList<>(); + boolean isFilterProvided = false; + boolean isPaginationRangeProvided = false; + try { + Connection conn = this.getConnection(); + String sql = "SELECT ID AS DEVICE_TYPE_ID, " + + "NAME AS DEVICE_TYPE_NAME, " + + "DEVICE_TYPE_META " + + "FROM DM_DEVICE_TYPE " + + "WHERE (PROVIDER_TENANT_ID =? OR " + + "SHARED_WITH_ALL_TENANTS = ?) "; + + if (!StringUtils.isEmpty(paginationRequest.getFilter())) { + sql += "AND NAME LIKE ? "; + isFilterProvided = true; + } + + if (paginationRequest.getStartIndex() >= 0 && paginationRequest.getRowCount() > 0) { + sql += "LIMIT ?, ?"; + isPaginationRangeProvided = true; + } + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + int paramIndex = 1; + stmt.setInt(paramIndex++, tenantId); + stmt.setBoolean(paramIndex++, true); + if (isFilterProvided) { + stmt.setString(paramIndex++, paginationRequest.getFilter()); + } + if (isPaginationRangeProvided) { + stmt.setInt(paramIndex++, paginationRequest.getStartIndex()); + stmt.setInt(paramIndex, paginationRequest.getRowCount()); + } + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + DeviceType deviceType = new DeviceType(); + deviceType.setId(rs.getInt("DEVICE_TYPE_ID")); + deviceType.setName(rs.getString("DEVICE_TYPE_NAME")); + String devicetypeMeta = rs.getString("DEVICE_TYPE_META"); + if (devicetypeMeta != null && devicetypeMeta.length() > 0) { + Gson gson = new Gson(); + deviceType.setDeviceTypeMetaDefinition + (gson.fromJson(devicetypeMeta, DeviceTypeMetaDefinition.class)); + } + deviceTypes.add(deviceType); + } + } + } + return deviceTypes; + } catch (SQLException e) { + String msg = "Error occurred while fetching device types"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + @Override public void removeDeviceType(String type, int tenantId) throws DeviceManagementDAOException { @@ -452,5 +517,4 @@ public class DeviceTypeDAOImpl implements DeviceTypeDAO { private Connection getConnection() throws SQLException { return DeviceManagementDAOFactory.getConnection(); } - } 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 e593221869d..cbb055e7f2c 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 @@ -722,12 +722,22 @@ public interface DeviceManagementProviderService { */ DeviceType getDeviceType(String deviceType) throws DeviceManagementException; + /** - * This retrieves the device type info for the given type - * @throws DeviceManagementException + * This method will return device type list without filtering or limiting + * @return DeviceTypeList + * @throws DeviceManagementException will be thrown when Error in Backend occurs */ List getDeviceTypes() throws DeviceManagementException; + /** + * This method will return device type list using limit and filtering provided + * @param paginationRequest request parameters to filter devices + * @return filterd device types + * @throws DeviceManagementException + */ + List getDeviceTypes(PaginationRequest paginationRequest) throws DeviceManagementException; + /** * This retrieves the device location histories * 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 c74d7b2ca9d..836613ba772 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 @@ -2918,6 +2918,26 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } } + @Override + public List getDeviceTypes(PaginationRequest paginationRequest) + throws DeviceManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + try { + DeviceManagementDAOFactory.openConnection(); + return deviceTypeDAO.getDeviceTypes(tenantId, paginationRequest); + } catch (SQLException e) { + String msg = "Error occurred while opening a connection to the data source"; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } catch (DeviceManagementDAOException e) { + String msg = "Error occurred while obtaining the device types for tenant " + tenantId; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + @Override public List getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to) throws DeviceManagementException {