diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/ReportManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/ReportManagementService.java index 6ce1b09403c..aa5424abd3a 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/ReportManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/ReportManagementService.java @@ -313,12 +313,12 @@ public interface ReportManagementService { int limit) throws ReportManagementException; @GET - @Path("expired-devices/{deviceType}") + @Path("/expired-devices/{deviceType}") @ApiOperation( produces = MediaType.APPLICATION_JSON, httpMethod = "GET", - value = "Getting Details of Registered Devices filtered by OS version build date", - notes = "Provides details of devices that have a version build date older than the provided date.", + value = "Getting Details of Registered Devices filtered by OS version", + notes = "Provides details of devices that have a OS version older than the provided version.", tags = "Device Management", extensions = { @Extension(properties = { @@ -337,9 +337,9 @@ public interface ReportManagementService { name = "Content-Type", description = "The content type of the body")}), @ApiResponse( - code = 404, - message = "Not Found. " + - "\n Device type does not exist", + code = 400, + message = "Bad Request. " + + "\n Contents of the request are invalid", response = ErrorResponse.class), @ApiResponse( code = 500, @@ -354,10 +354,10 @@ public interface ReportManagementService { required = true) @PathParam("deviceType") String deviceType, @ApiParam( - name = "osBuildDate", - value = "Minimum OS version build date which is used to filter the devices.", + name = "osVersion", + value = "Minimum OS version which is used to filter the devices.", required = true) - @QueryParam("osBuildDate") Long osBuildDate, + @QueryParam("osVersion") String osVersion, @ApiParam( name = "offset", value = "The starting pagination index for the list of filtered devices.", diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ReportManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ReportManagementServiceImpl.java index 331a3bfdd2b..4ecf7b7bd63 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ReportManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ReportManagementServiceImpl.java @@ -25,6 +25,7 @@ import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.PaginationResult; +import org.wso2.carbon.device.mgt.common.exceptions.BadRequestException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceTypeNotFoundException; import org.wso2.carbon.device.mgt.common.exceptions.ReportManagementException; import org.wso2.carbon.device.mgt.core.report.mgt.Constants; @@ -169,10 +170,10 @@ public class ReportManagementServiceImpl implements ReportManagementService { } @GET - @Path("expired-devices/{deviceType}") + @Path("/expired-devices/{deviceType}") @Override public Response getExpiredDevicesByOSVersion(@PathParam("deviceType") String deviceType, - @QueryParam("osBuildDate") Long osBuildDate, + @QueryParam("osVersion") String osVersion, @DefaultValue("0") @QueryParam("offset") int offset, @DefaultValue("5") @@ -180,20 +181,23 @@ public class ReportManagementServiceImpl implements ReportManagementService { try { PaginationRequest request = new PaginationRequest(offset, limit); request.setDeviceType(deviceType); - request.setProperty(Constants.OS_BUILD_DATE, osBuildDate); + request.setProperty(Constants.OS_VERSION, osVersion); PaginationResult paginationResult = DeviceMgtAPIUtils .getReportManagementService() .getDevicesExpiredByOSVersion(request); - return Response.status(Response.Status.OK).entity(paginationResult).build(); - } catch (DeviceTypeNotFoundException e) { - String msg = "Error occurred while retrieving devices list. Device type: " + deviceType + - "is not valid"; - log.error(msg); - return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + DeviceList devices = new DeviceList(); + devices.setList((List) paginationResult.getData()); + devices.setCount(paginationResult.getRecordsTotal()); + + return Response.status(Response.Status.OK).entity(devices).build(); + } catch (BadRequestException e) { + String msg = "Error occurred while validating device type or the OS version."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } catch (ReportManagementException e) { - String msg = "Error occurred while retrieving devices list with out-dated OS build versions"; + String msg = "Error occurred while retrieving list of devices with out-dated OS versions."; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/BadRequestException.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/BadRequestException.java new file mode 100644 index 00000000000..b7d99da0e09 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/BadRequestException.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.wso2.carbon.device.mgt.common.exceptions; + +public class BadRequestException extends Exception { + private static final long serialVersionUID = 2304023531260840549L; + + public BadRequestException() { + super(); + } + + public BadRequestException(String msg) { + super(msg); + } + + public BadRequestException(Throwable cause) { + super(cause); + } + + public BadRequestException(String msg, Exception nestedEx) { + super(msg, nestedEx); + } + + public BadRequestException(String message, Throwable cause) { + super(message, cause); + } +} + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/report/mgt/ReportManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/report/mgt/ReportManagementService.java index 6e001fd73bf..ef5806d798d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/report/mgt/ReportManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/report/mgt/ReportManagementService.java @@ -21,6 +21,7 @@ import com.google.gson.JsonObject; import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.PaginationResult; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException; +import org.wso2.carbon.device.mgt.common.exceptions.BadRequestException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceTypeNotFoundException; import org.wso2.carbon.device.mgt.common.exceptions.ReportManagementException; @@ -56,10 +57,10 @@ public interface ReportManagementService { * @param request {@link PaginationRequest} * @return {@link PaginationResult} * @throws ReportManagementException Might occur during the business logic or building database query - * @throws DeviceTypeNotFoundException Might occur while validating the device type + * @throws BadRequestException Might occur if the given os version or the device type doesn't match */ PaginationResult getDevicesExpiredByOSVersion(PaginationRequest request) - throws ReportManagementException, DeviceTypeNotFoundException; + throws ReportManagementException, BadRequestException; /** * Get a paginated list of devices which is filtered by given encryption status 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 5ba8cc956f2..4eb94b606b3 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 @@ -637,12 +637,12 @@ public interface DeviceDAO { * Count the number of devices older than the given OS version of a device type * * @param deviceType Device type name - * @param osBuildDate BUild date off the current OS version + * @param osValue Generated value for the OS version * @param tenantId Id of the current tenant. * @return {@link Integer} * @throws DeviceManagementDAOException Thrown if error occurs while database transactions */ - int getCountOfDeviceExpiredByOSVersion(String deviceType, long osBuildDate, int tenantId) + int getCountOfDeviceExpiredByOSVersion(String deviceType, Long osValue, int tenantId) 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/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 f0d78aef013..0279c654bf2 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 @@ -1915,108 +1915,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { throw new DeviceManagementDAOException(msg, e); } } - - @Override - public List getDevicesExpiredByOSVersion(PaginationRequest request, int tenantId) - throws DeviceManagementDAOException { - try { - Long osBuildDate = (Long) request.getProperty(Constants.OS_BUILD_DATE); - Connection conn = getConnection(); - String sql = "SELECT " + - "dt.NAME AS DEVICE_TYPE, " + - "d.ID AS DEVICE_ID, " + - "d.NAME AS DEVICE_NAME, " + - "d.DESCRIPTION, " + - "d.DEVICE_IDENTIFICATION, " + - "dd.OS_VERSION, " + - "dd.OS_BUILD_DATE, " + - "e.ID AS ENROLMENT_ID, " + - "e.OWNER, " + - "e.OWNERSHIP, " + - "e.STATUS, " + - "e.DATE_OF_LAST_UPDATE, " + - "e.DATE_OF_ENROLMENT " + - "FROM DM_DEVICE d, " + - "DM_DEVICE_DETAIL dd, " + - "DM_ENROLMENT e, " + - "(SELECT ID, NAME " + - "FROM DM_DEVICE_TYPE " + - "WHERE NAME = ? " + - "AND PROVIDER_TENANT_ID = ?) dt " + - "WHERE dt.ID = d.DEVICE_TYPE_ID " + - "AND d.ID = e.DEVICE_ID " + - "AND d.ID = dd.DEVICE_ID " + - "AND dd.OS_BUILD_DATE < ? " + - "LIMIT ? OFFSET ?"; - - try (PreparedStatement ps = conn.prepareStatement(sql)) { - int paramIDx = 1; - ps.setString(paramIDx++, request.getDeviceType()); - ps.setInt(paramIDx++, tenantId); - ps.setLong(paramIDx++, osBuildDate); - ps.setInt(paramIDx++, request.getRowCount()); - ps.setInt(paramIDx, request.getStartIndex()); - - try (ResultSet rs = ps.executeQuery()) { - List devices = new ArrayList<>(); - DeviceInfo deviceInfo = new DeviceInfo(); - while (rs.next()) { - Device device = DeviceManagementDAOUtil.loadDevice(rs); - deviceInfo.setOsVersion(rs.getString(Constants.OS_VERSION)); - deviceInfo.setOsBuildDate(rs.getString(Constants.OS_BUILD_DATE)); - device.setDeviceInfo(deviceInfo); - devices.add(device); - } - return devices; - } - } - } catch (SQLException e) { - String msg = "Error occurred while building or executing queries to retrieve information " + - "of devices with an older OS build date"; - log.error(msg, e); - throw new DeviceManagementDAOException(msg, e); - } - } - - @Override - public int getCountOfDeviceExpiredByOSVersion(String deviceType, long osBuildDate, int tenantId) - throws DeviceManagementDAOException { - try { - Connection conn = getConnection(); - String sql = "SELECT " + - "COUNT(dd.DEVICE_ID) AS DEVICE_COUNT " + - "FROM DM_DEVICE d, " + - "DM_DEVICE_DETAIL dd, " + - "(SELECT ID " + - "FROM DM_DEVICE_TYPE " + - "WHERE NAME = ? " + - "AND PROVIDER_TENANT_ID = ?) dt " + - "WHERE d.DEVICE_TYPE_ID = dt.ID " + - "AND d.ID = dd.DEVICE_ID " + - "AND dd.OS_BUILD_DATE < ?"; - - try (PreparedStatement ps = conn.prepareStatement(sql)) { - int paramIdx = 1; - ps.setString(paramIdx++, deviceType); - ps.setInt(paramIdx++, tenantId); - ps.setLong(paramIdx, osBuildDate); - - try (ResultSet rs = ps.executeQuery()) { - int deviceCount = 0; - if (rs.next()) { - deviceCount = rs.getInt("DEVICE_COUNT"); - } - return deviceCount; - } - } - } catch (SQLException e) { - String msg = "Error occurred while building or executing queries to retrieve the count " + - "of devices with an older OS build date"; - log.error(msg, e); - throw new DeviceManagementDAOException(msg, e); - } - } - + @Override public List getAppNotInstalledDevices( PaginationRequest request, int tenantId, String packageName, String version) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java index 471929dc128..e2a35770c2b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java @@ -23,11 +23,14 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.mgt.common.Count; import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; import org.wso2.carbon.device.mgt.common.PaginationRequest; +import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory; import org.wso2.carbon.device.mgt.core.dao.impl.AbstractDeviceDAOImpl; import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil; +import org.wso2.carbon.device.mgt.core.report.mgt.Constants; import java.sql.Connection; import java.sql.PreparedStatement; @@ -858,6 +861,127 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { } } + @Override + public List getDevicesExpiredByOSVersion(PaginationRequest request, int tenantId) + throws DeviceManagementDAOException { + try { + Long osValue = (Long) request.getProperty(Constants.OS_VALUE); + Connection conn = getConnection(); + /* following variable is used to identify the datasource type.This is due to a + convert function performed in the query which will depend on the datasource */ + String dataSourceType = conn.getMetaData().getDatabaseProductName(); + String sql="SELECT " + + "d1.DEVICE_TYPE, " + + "d1.DEVICE_ID, " + + "d1.DEVICE_NAME, " + + "d1.DESCRIPTION, " + + "d1.DEVICE_IDENTIFICATION, " + + "ddd.OS_VERSION, " + + "e.ID AS ENROLMENT_ID, " + + "e.OWNER, " + + "e.OWNERSHIP, " + + "e.STATUS, " + + "e.DATE_OF_LAST_UPDATE, " + + "e.DATE_OF_ENROLMENT " + + "FROM DM_DEVICE_INFO ddi," + + "DM_DEVICE_DETAIL ddd, " + + "DM_ENROLMENT e, " + + "(SELECT dt.NAME AS DEVICE_TYPE, " + + "d.ID AS DEVICE_ID, " + + "d.NAME AS DEVICE_NAME, " + + "DESCRIPTION, " + + "DEVICE_IDENTIFICATION " + + "FROM DM_DEVICE_TYPE dt, " + + "DM_DEVICE d " + + "WHERE dt.NAME = ? " + + "AND PROVIDER_TENANT_ID = ? " + + "AND dt.ID = d.DEVICE_TYPE_ID " + + ") d1 " + + "WHERE d1.DEVICE_ID = e.DEVICE_ID " + + "AND d1.DEVICE_ID = ddi.DEVICE_ID " + + "AND ddi.KEY_FIELD = ? "; + if (dataSourceType.contains(DeviceManagementConstants.DataBaseTypes.DB_TYPE_H2)) { + sql += "AND CAST( ddi.VALUE_FIELD AS BIGINT ) < ? "; + } else if (dataSourceType.contains(DeviceManagementConstants.DataBaseTypes.DB_TYPE_MYSQL)) { + sql += "AND CAST( ddi.VALUE_FIELD AS UNSIGNED ) < ? "; + } + sql += "LIMIT ? OFFSET ?"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, request.getDeviceType()); + ps.setInt(2, tenantId); + ps.setString(3, Constants.OS_VALUE); + ps.setLong(4, osValue); + ps.setInt(5, request.getRowCount()); + ps.setInt(6, request.getStartIndex()); + + try (ResultSet rs = ps.executeQuery()) { + List devices = new ArrayList<>(); + while (rs.next()) { + Device device = DeviceManagementDAOUtil.loadDevice(rs); + DeviceInfo deviceInfo = new DeviceInfo(); + deviceInfo.setOsVersion(rs.getString("OS_VERSION")); + device.setDeviceInfo(deviceInfo); + devices.add(device); + } + return devices; + } + } + } catch (SQLException e) { + String msg = "Error occurred while building or executing queries to retrieve information " + + "of devices with an older OS build date"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public int getCountOfDeviceExpiredByOSVersion(String deviceType, Long osValue, int tenantId) + throws DeviceManagementDAOException { + try { + Connection conn = getConnection(); + /* following variable is used to identify the datasource type.This is due to a + convert function performed in the query which will depend on the datasource */ + String dataSourceType = conn.getMetaData().getDatabaseProductName(); + String sql = "SELECT " + + "COUNT(ddi.DEVICE_ID) AS DEVICE_COUNT " + + "FROM DM_DEVICE_INFO ddi, " + + "(SELECT d.ID AS DEVICE_ID " + + "FROM DM_DEVICE_TYPE dt, " + + "DM_DEVICE d " + + "WHERE dt.NAME = ? " + + "AND PROVIDER_TENANT_ID = ? " + + "AND dt.ID = d.DEVICE_TYPE_ID " + + ") d1 " + + "WHERE d1.DEVICE_ID = ddi.DEVICE_ID " + + "AND ddi.KEY_FIELD = ? "; + if (dataSourceType.contains(DeviceManagementConstants.DataBaseTypes.DB_TYPE_H2)) { + sql += "AND CAST( ddi.VALUE_FIELD AS BIGINT ) < ? "; + } else if (dataSourceType.contains(DeviceManagementConstants.DataBaseTypes.DB_TYPE_MYSQL)) { + sql += "AND CAST( ddi.VALUE_FIELD AS UNSIGNED ) < ? "; + } + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, deviceType); + ps.setInt(2, tenantId); + ps.setString(3, Constants.OS_VALUE); + ps.setLong(4, osValue); + + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + return rs.getInt("DEVICE_COUNT"); + } + return 0; + } + } + } catch (SQLException e) { + String msg = "Error occurred while building or executing queries to retrieve the count " + + "of devices with an older OS build date"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + 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/dao/impl/device/OracleDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java index 37a64568b6c..2ef6697453c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java @@ -834,52 +834,57 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { public List getDevicesExpiredByOSVersion(PaginationRequest request, int tenantId) throws DeviceManagementDAOException { try { - Long osBuildDate = (Long) request.getProperty(Constants.OS_BUILD_DATE); + Long osValue = (Long) request.getProperty(Constants.OS_VALUE); Connection conn = getConnection(); - String sql = "SELECT " + - "dt.NAME AS DEVICE_TYPE, " + - "d.ID AS DEVICE_ID, " + - "d.NAME AS DEVICE_NAME, " + - "d.DESCRIPTION, " + - "d.DEVICE_IDENTIFICATION, " + - "dd.OS_VERSION, " + - "dd.OS_BUILD_DATE, " + - "e.ID AS ENROLMENT_ID, " + - "e.OWNER, " + - "e.OWNERSHIP, " + - "e.STATUS, " + - "e.DATE_OF_LAST_UPDATE, " + - "e.DATE_OF_ENROLMENT " + - "FROM DM_DEVICE d, " + - "DM_DEVICE_DETAIL dd, " + - "DM_ENROLMENT e, " + - "(SELECT ID, NAME " + - "FROM DM_DEVICE_TYPE " + - "WHERE NAME = ? " + - "AND PROVIDER_TENANT_ID = ?) dt " + - "WHERE dt.ID = d.DEVICE_TYPE_ID " + - "AND d.ID = e.DEVICE_ID " + - "AND d.ID = dd.DEVICE_ID " + - "AND dd.OS_BUILD_DATE < ? " + - "ORDER BY ENROLMENT_ID " + - "OFFSET ? ROWS " + - "FETCH NEXT ? ROWS ONLY"; + String sql="SELECT " + + "d1.DEVICE_TYPE, " + + "d1.DEVICE_ID, " + + "d1.DEVICE_NAME, " + + "d1.DESCRIPTION, " + + "d1.DEVICE_IDENTIFICATION, " + + "ddd.OS_VERSION, " + + "e.ID AS ENROLMENT_ID, " + + "e.OWNER, " + + "e.OWNERSHIP, " + + "e.STATUS, " + + "e.DATE_OF_LAST_UPDATE, " + + "e.DATE_OF_ENROLMENT " + + "FROM DM_DEVICE_INFO ddi, " + + "DM_DEVICE_DETAIL ddd, " + + "DM_ENROLMENT e, " + + "(SELECT dt.NAME AS DEVICE_TYPE, " + + "d.ID AS DEVICE_ID, " + + "d.NAME AS DEVICE_NAME, " + + "DESCRIPTION, " + + "DEVICE_IDENTIFICATION " + + " FROM DM_DEVICE_TYPE dt, " + + "DM_DEVICE d " + + "WHERE dt.NAME = ? " + + "AND PROVIDER_TENANT_ID = ? " + + "AND dt.ID = d.DEVICE_TYPE_ID " + + ") d1 " + + "WHERE d1.DEVICE_ID = e.DEVICE_ID " + + "AND d1.DEVICE_ID = ddi.DEVICE_ID " + + "AND ddi.KEY_FIELD = ? " + + "AND CAST( ddi.VALUE_FIELD AS BIGINT ) < ? " + + "ORDER BY ENROLMENT_ID " + + "OFFSET ? ROWS " + + "FETCH NEXT ? ROWS ONLY"; try (PreparedStatement ps = conn.prepareStatement(sql)) { - int paramIDx = 1; - ps.setString(paramIDx++, request.getDeviceType()); - ps.setInt(paramIDx++, tenantId); - ps.setLong(paramIDx++, osBuildDate); - ps.setInt(paramIDx++, request.getStartIndex()); - ps.setInt(paramIDx, request.getRowCount()); + ps.setString(1, request.getDeviceType()); + ps.setInt(2, tenantId); + ps.setString(3, Constants.OS_VALUE); + ps.setLong(4, osValue); + ps.setInt(5, request.getStartIndex()); + ps.setInt(6, request.getRowCount()); try (ResultSet rs = ps.executeQuery()) { List devices = new ArrayList<>(); - DeviceInfo deviceInfo = new DeviceInfo(); while (rs.next()) { Device device = DeviceManagementDAOUtil.loadDevice(rs); - deviceInfo.setOsVersion(rs.getString(Constants.OS_VERSION)); - deviceInfo.setOsBuildDate(rs.getString(Constants.OS_BUILD_DATE)); + DeviceInfo deviceInfo = new DeviceInfo(); + deviceInfo.setOsVersion(rs.getString("OS_VERSION")); device.setDeviceInfo(deviceInfo); devices.add(device); } @@ -887,8 +892,48 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { } } } catch (SQLException e) { - String msg = "Error occurred while retrieving information of devices with an older OS date " + - "than the minimum date"; + String msg = "Error occurred while building or executing queries to retrieve information " + + "of devices with an older OS build date"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public int getCountOfDeviceExpiredByOSVersion(String deviceType, Long osValue, int tenantId) + throws DeviceManagementDAOException { + try { + Connection conn = getConnection(); + String sql = "SELECT " + + "COUNT(ddi.DEVICE_ID) AS DEVICE_COUNT " + + "FROM DM_DEVICE_INFO ddi, " + + "(SELECT d.ID AS DEVICE_ID " + + "FROM DM_DEVICE_TYPE dt, " + + "DM_DEVICE d " + + "WHERE dt.NAME = ? " + + "AND PROVIDER_TENANT_ID = ? " + + "AND dt.ID = d.DEVICE_TYPE_ID " + + ") d1 " + + "WHERE d1.DEVICE_ID = ddi.DEVICE_ID " + + "AND ddi.KEY_FIELD = ? " + + "AND CAST( ddi.VALUE_FIELD AS BIGINT ) < ?"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, deviceType); + ps.setInt(2, tenantId); + ps.setString(3, Constants.OS_VALUE); + ps.setLong(4, osValue); + + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + return rs.getInt("DEVICE_COUNT"); + } + return 0; + } + } + } catch (SQLException e) { + String msg = "Error occurred while building or executing queries to retrieve the count " + + "of devices with an older OS build date"; log.error(msg, e); throw new DeviceManagementDAOException(msg, e); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java index 5df5f823bb8..fc137897bbe 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java @@ -24,10 +24,12 @@ import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.mgt.common.Count; import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.PaginationRequest; +import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory; import org.wso2.carbon.device.mgt.core.dao.impl.AbstractDeviceDAOImpl; import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil; +import org.wso2.carbon.device.mgt.core.report.mgt.Constants; import java.sql.Connection; import java.sql.PreparedStatement; @@ -814,6 +816,113 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl { } } + @Override + public List getDevicesExpiredByOSVersion(PaginationRequest request, int tenantId) + throws DeviceManagementDAOException { + try { + Long osValue = (Long) request.getProperty(Constants.OS_VALUE); + Connection conn = getConnection(); + String sql="SELECT " + + "d1.DEVICE_TYPE, " + + "d1.DEVICE_ID, " + + "d1.DEVICE_NAME, " + + "d1.DESCRIPTION, " + + "d1.DEVICE_IDENTIFICATION, " + + "ddd.OS_VERSION, " + + "e.ID AS ENROLMENT_ID, " + + "e.OWNER, " + + "e.OWNERSHIP, " + + "e.STATUS, " + + "e.DATE_OF_LAST_UPDATE, " + + "e.DATE_OF_ENROLMENT " + + "FROM DM_DEVICE_INFO ddi, " + + "DM_DEVICE_DETAIL ddd, " + + "DM_ENROLMENT e, " + + "(SELECT dt.NAME AS DEVICE_TYPE, " + + "d.ID AS DEVICE_ID, " + + "d.NAME AS DEVICE_NAME, " + + "DESCRIPTION, " + + "DEVICE_IDENTIFICATION " + + " FROM DM_DEVICE_TYPE dt, " + + "DM_DEVICE d " + + "WHERE dt.NAME = ? " + + "AND PROVIDER_TENANT_ID = ? " + + "AND dt.ID = d.DEVICE_TYPE_ID " + + ") d1 " + + "WHERE d1.DEVICE_ID = e.DEVICE_ID " + + "AND d1.DEVICE_ID = ddi.DEVICE_ID " + + "AND ddi.KEY_FIELD = ? " + + "AND CAST( ddi.VALUE_FIELD AS BIGINT ) < ? " + + "LIMIT ? OFFSET ?"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, request.getDeviceType()); + ps.setInt(2, tenantId); + ps.setString(3, Constants.OS_VALUE); + ps.setLong(4, osValue); + ps.setInt(5, request.getRowCount()); + ps.setInt(6, request.getStartIndex()); + + try (ResultSet rs = ps.executeQuery()) { + List devices = new ArrayList<>(); + while (rs.next()) { + Device device = DeviceManagementDAOUtil.loadDevice(rs); + DeviceInfo deviceInfo = new DeviceInfo(); + deviceInfo.setOsVersion(rs.getString("OS_VERSION")); + device.setDeviceInfo(deviceInfo); + devices.add(device); + } + return devices; + } + } + } catch (SQLException e) { + String msg = "Error occurred while building or executing queries to retrieve information " + + "of devices with an older OS build date"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public int getCountOfDeviceExpiredByOSVersion(String deviceType, Long osValue, int tenantId) + throws DeviceManagementDAOException { + try { + Connection conn = getConnection(); + String sql = "SELECT " + + "COUNT(ddi.DEVICE_ID) AS DEVICE_COUNT " + + "FROM DM_DEVICE_INFO ddi, " + + "(SELECT d.ID AS DEVICE_ID " + + "FROM DM_DEVICE_TYPE dt, " + + "DM_DEVICE d " + + "WHERE dt.NAME = ? " + + "AND PROVIDER_TENANT_ID = ? " + + "AND dt.ID = d.DEVICE_TYPE_ID " + + ") d1 " + + "WHERE d1.DEVICE_ID = ddi.DEVICE_ID " + + "AND ddi.KEY_FIELD = ? " + + "AND CAST( ddi.VALUE_FIELD AS BIGINT ) < ?"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, deviceType); + ps.setInt(2, tenantId); + ps.setString(3, Constants.OS_VALUE); + ps.setLong(4, osValue); + + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + return rs.getInt("DEVICE_COUNT"); + } + return 0; + } + } + } catch (SQLException e) { + String msg = "Error occurred while building or executing queries to retrieve the count " + + "of devices with an older OS build date"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + 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/dao/impl/device/SQLServerDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java index 299917edd2c..ecda3ef66d7 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java @@ -24,12 +24,14 @@ import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.mgt.common.Count; import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.PaginationRequest; +import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory; import org.wso2.carbon.device.mgt.core.dao.impl.AbstractDeviceDAOImpl; import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil; import org.wso2.carbon.device.mgt.core.geo.GeoCluster; import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; +import org.wso2.carbon.device.mgt.core.report.mgt.Constants; import java.sql.Connection; import java.sql.PreparedStatement; @@ -630,6 +632,113 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { } } + @Override + public List getDevicesExpiredByOSVersion(PaginationRequest request, int tenantId) + throws DeviceManagementDAOException { + try { + Long osValue = (Long) request.getProperty(Constants.OS_VALUE); + Connection conn = getConnection(); + String sql="SELECT " + + "d1.DEVICE_TYPE, " + + "d1.DEVICE_ID, " + + "d1.DEVICE_NAME, " + + "d1.DESCRIPTION, " + + "d1.DEVICE_IDENTIFICATION, " + + "ddd.OS_VERSION, " + + "e.ID AS ENROLMENT_ID, " + + "e.OWNER, " + + "e.OWNERSHIP, " + + "e.STATUS, " + + "e.DATE_OF_LAST_UPDATE, " + + "e.DATE_OF_ENROLMENT " + + "FROM DM_DEVICE_INFO ddi, " + + "DM_DEVICE_DETAIL ddd, " + + "DM_ENROLMENT e, " + + "(SELECT dt.NAME AS DEVICE_TYPE, " + + "d.ID AS DEVICE_ID, " + + "d.NAME AS DEVICE_NAME, " + + "DESCRIPTION, " + + "DEVICE_IDENTIFICATION " + + " FROM DM_DEVICE_TYPE dt, " + + "DM_DEVICE d " + + "WHERE dt.NAME = ? " + + "AND PROVIDER_TENANT_ID = ? " + + "AND dt.ID = d.DEVICE_TYPE_ID " + + ") d1 " + + "WHERE d1.DEVICE_ID = e.DEVICE_ID " + + "AND d1.DEVICE_ID = ddi.DEVICE_ID " + + "AND ddi.KEY_FIELD = ? " + + "AND CAST( ddi.VALUE_FIELD AS BIGINT ) < ? " + + "LIMIT ? OFFSET ?"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, request.getDeviceType()); + ps.setInt(2, tenantId); + ps.setString(3, Constants.OS_VALUE); + ps.setLong(4, osValue); + ps.setInt(5, request.getRowCount()); + ps.setInt(6, request.getStartIndex()); + + try (ResultSet rs = ps.executeQuery()) { + List devices = new ArrayList<>(); + while (rs.next()) { + Device device = DeviceManagementDAOUtil.loadDevice(rs); + DeviceInfo deviceInfo = new DeviceInfo(); + deviceInfo.setOsVersion(rs.getString("OS_VERSION")); + device.setDeviceInfo(deviceInfo); + devices.add(device); + } + return devices; + } + } + } catch (SQLException e) { + String msg = "Error occurred while building or executing queries to retrieve information " + + "of devices with an older OS build date"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public int getCountOfDeviceExpiredByOSVersion(String deviceType, Long osValue, int tenantId) + throws DeviceManagementDAOException { + try { + Connection conn = getConnection(); + String sql = "SELECT " + + "COUNT(ddi.DEVICE_ID) AS DEVICE_COUNT " + + "FROM DM_DEVICE_INFO ddi, " + + "(SELECT d.ID AS DEVICE_ID " + + "FROM DM_DEVICE_TYPE dt, " + + "DM_DEVICE d " + + "WHERE dt.NAME = ? " + + "AND PROVIDER_TENANT_ID = ? " + + "AND dt.ID = d.DEVICE_TYPE_ID " + + ") d1 " + + "WHERE d1.DEVICE_ID = ddi.DEVICE_ID " + + "AND ddi.KEY_FIELD = ? " + + "AND CAST( ddi.VALUE_FIELD AS BIGINT ) < ?"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, deviceType); + ps.setInt(2, tenantId); + ps.setString(3, Constants.OS_VALUE); + ps.setLong(4, osValue); + + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + return rs.getInt("DEVICE_COUNT"); + } + return 0; + } + } + } catch (SQLException e) { + String msg = "Error occurred while building or executing queries to retrieve the count " + + "of devices with an older OS build date"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + 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/device/details/mgt/impl/DeviceInformationManagerImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/device/details/mgt/impl/DeviceInformationManagerImpl.java index 67360baf900..c6c5e9f270b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/device/details/mgt/impl/DeviceInformationManagerImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/device/details/mgt/impl/DeviceInformationManagerImpl.java @@ -18,6 +18,7 @@ package org.wso2.carbon.device.mgt.core.device.details.mgt.impl; +import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.CarbonContext; @@ -39,6 +40,7 @@ import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManag import org.wso2.carbon.device.mgt.core.device.details.mgt.dao.DeviceDetailsDAO; import org.wso2.carbon.device.mgt.core.device.details.mgt.dao.DeviceDetailsMgtDAOException; import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; +import org.wso2.carbon.device.mgt.core.report.mgt.Constants; import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil; import org.wso2.carbon.device.mgt.core.util.HttpReportingUtil; @@ -98,6 +100,8 @@ public class DeviceInformationManagerImpl implements DeviceInformationManager { } else { Map updatableProps = new HashMap<>(); Map injectableProps = new HashMap<>(); + // generate a default value depending on the devices OS version + addOSVersionValue(device, newDeviceInfo); for (String key : newDeviceInfo.getDeviceDetailsMap().keySet()) { if (previousDeviceProperties.containsKey(key)) { updatableProps.put(key, newDeviceInfo.getDeviceDetailsMap().get(key)); @@ -420,5 +424,39 @@ public class DeviceInformationManagerImpl implements DeviceInformationManager { return newDeviceInfo; } + /** + * Generate and add a value depending on the device's OS version included in device info + * + * @param device device data + * @param newDeviceInfo device info data + */ + private void addOSVersionValue(Device device, DeviceInfo newDeviceInfo) { + String deviceTypeName = device.getType(); + if (StringUtils.isBlank(device.getType())) { + if (log.isDebugEnabled()) { + log.debug("Unable to generate a OS version value for device type: " + + deviceTypeName + ". Device type cannot be null or empty"); + } + } else { + if (!deviceTypeName.equals("android") && !deviceTypeName.equals("ios")) { + if (log.isDebugEnabled()) { + log.debug("Unable to generate a OS version value for device type: " + + deviceTypeName + ". OS version value is only generatable for " + + "android and ios"); + } + } else { + String osVersion = newDeviceInfo.getOsVersion(); + String osValue = String.valueOf(DeviceManagerUtil.generateOSVersionValue(osVersion)); + if (StringUtils.isBlank(osValue)) { + if (log.isDebugEnabled()) { + log.debug("Unable to generate a OS version value for OS version: " + + osVersion + " for device type: " + deviceTypeName); + } + } else { + newDeviceInfo.getDeviceDetailsMap().put(Constants.OS_VALUE, osValue); + } + } + } + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/report/mgt/Constants.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/report/mgt/Constants.java index 49db80418bc..2be36d0acfc 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/report/mgt/Constants.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/report/mgt/Constants.java @@ -1,27 +1,33 @@ /* - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2020, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at + * Entgra (pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ - package org.wso2.carbon.device.mgt.core.report.mgt; public class Constants { - -// device properties + // device types + public static final String ANDROID = "android"; + public static final String IOS = "ios"; + // device properties public static final String OS_BUILD_DATE = "OS_BUILD_DATE"; public static final String OS_VERSION = "OS_VERSION"; + public static final String OS_VALUE = "OS_VALUE"; + // OS version value generating properties + public static final int NUM_OF_OS_VERSION_DIGITS= 5; + public static final int NUM_OF_OS_VERSION_POSITIONS = 3; } + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/report/mgt/ReportManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/report/mgt/ReportManagementServiceImpl.java index 4c097906555..ce63ff965d7 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/report/mgt/ReportManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/report/mgt/ReportManagementServiceImpl.java @@ -23,6 +23,9 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.mgt.common.Count; import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.app.mgt.Application; +import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException; +import org.wso2.carbon.device.mgt.common.exceptions.BadRequestException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.PaginationResult; @@ -157,46 +160,55 @@ public class ReportManagementServiceImpl implements ReportManagementService { @Override public PaginationResult getDevicesExpiredByOSVersion(PaginationRequest request) - throws ReportManagementException, DeviceTypeNotFoundException { + throws ReportManagementException, BadRequestException { if (request == null || StringUtils.isBlank(request.getDeviceType()) || - !request.getProperties().containsKey(Constants.OS_BUILD_DATE) || - (Long) request.getProperty(Constants.OS_BUILD_DATE) == 0) { - + request.getProperties() == null || + !request.getProperties().containsKey(Constants.OS_VERSION) || + StringUtils.isBlank((String) request.getProperty(Constants.OS_VERSION))) { String msg = "Error Invalid data received from the request.\n" + - "osBuildDate cannot be null or 0 and device type cannot be null or empty"; + "osVersion and device type cannot be null or empty."; log.error(msg); - throw new ReportManagementException(msg); + throw new BadRequestException(msg); } + + String deviceType = request.getDeviceType(); + if (!deviceType.equals(Constants.ANDROID) && !deviceType.equals(Constants.IOS)) { + String msg = "Error Invalid device type:" + deviceType + " received. Valid device types " + + "are android and ios."; + log.error(msg); + throw new BadRequestException(msg); + } + try { int tenantId = DeviceManagementDAOUtil.getTenantId(); - String deviceType = request.getDeviceType(); PaginationResult paginationResult = new PaginationResult(); - DeviceManagerUtil.validateDeviceListPageSize(request); - DeviceType deviceTypeObj = DeviceManagerUtil.getDeviceType( - deviceType, tenantId); - if (deviceTypeObj == null) { - String msg = "Error, device of type: " + deviceType + " does not exist"; + String osVersion = (String) request.getProperty(Constants.OS_VERSION); + Long osVersionValue = DeviceManagerUtil.generateOSVersionValue(osVersion); + if (osVersionValue == null){ + String msg = "Failed to generate OS value, received OS version: " + osVersion + + " is in incorrect format([0-9]+([.][0-9]+)*) or version is invalid."; log.error(msg); - throw new DeviceTypeNotFoundException(msg); + throw new BadRequestException(msg); } + request.setProperty(Constants.OS_VALUE, osVersionValue); try { DeviceManagementDAOFactory.openConnection(); - List devices = deviceDAO.getDevicesExpiredByOSVersion(request, tenantId); + + List devices = deviceDAO.getDevicesExpiredByOSVersion( + request, tenantId); int deviceCount = deviceDAO.getCountOfDeviceExpiredByOSVersion( - deviceType, - (Long) request.getProperty(Constants.OS_BUILD_DATE), - tenantId); + deviceType, osVersionValue, tenantId); paginationResult.setData(devices); paginationResult.setRecordsFiltered(devices.size()); paginationResult.setRecordsTotal(deviceCount); return paginationResult; } catch (SQLException e) { - String msg = "Error occurred while opening a connection to the data source"; + String msg = "Error occurred while opening a connection to the data source."; log.error(msg, e); throw new ReportManagementException(msg, e); } finally { @@ -204,12 +216,12 @@ public class ReportManagementServiceImpl implements ReportManagementService { } } catch (DeviceManagementDAOException e) { - String msg = "Error occurred while retrieving expired devices by a OS build date " + - "for the tenant"; + String msg = "Error occurred while retrieving expired devices by a OS version " + + "for the tenant."; log.error(msg, e); throw new ReportManagementException(msg, e); } catch (DeviceManagementException e) { - String msg = "Error occurred while validating the request"; + String msg = "Error occurred while validating the request."; log.error(msg, e); throw new ReportManagementException(msg, e); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java index 1890d399cd9..0c0308d6b1a 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java @@ -60,6 +60,7 @@ 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.internal.DeviceManagementDataHolder; import org.wso2.carbon.device.mgt.core.operation.mgt.util.DeviceIDHolder; +import org.wso2.carbon.device.mgt.core.report.mgt.Constants; import org.wso2.carbon.identity.jwt.client.extension.JWTClient; import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; @@ -89,7 +90,11 @@ import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; +import java.util.StringJoiner; import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.IntStream; public final class DeviceManagerUtil { @@ -694,4 +699,109 @@ public final class DeviceManagerUtil { JWTClient jwtClient = jwtClientManagerService.getJWTClient(); return jwtClient.getAccessToken(clientId, clientSecret, deviceOwner, scopes); } + + /** + *

Generate a value for the passed os version

+ * + *

Value is generated by isolating each position of OS version then adding Zeros up until + * Minor version and Revision have a constant number of digits. + * Eg: 5.1.1 will be 50000100001, 9 will be 90000000000 + *

+ * + *

Above conversion is done in order to fail proof in situations where 6.0.0 can be + * smaller than 5.12.1. + * Eg: 5.12.1 will be 5121 and 6.0.0 will be 600 and 5121 > 600(this statement is incorrect) + *

+ * + * @param osVersion os version(eg: 5.1.1) + * @return {@link Long} generated value + */ + public static Long generateOSVersionValue(String osVersion) { + Matcher osMatcher = Pattern.compile("[0-9]+([.][0-9]+)*").matcher(osVersion); + if (!osMatcher.find()) { + if (log.isDebugEnabled()) { + log.debug("Unable to read OS version. OS version: " + osVersion + "is invalid. " + + "Please follow the following convention [0-9]+([.][0-9]+)*"); + } + return null; + } + osVersion = osMatcher.group(); + + String[] osVersions = osVersion.split("[.]"); + int osVersionsLength = osVersions.length; + + /* + *

Equation explanation

+ * + *

+ Eg: {@code osVersion == "5.1.1"} will generate an array of {@code ["5","1","1"]} + Following loop for the above result can be broken down as below + * Iteration 1 : {@code Math.pow} result = 5 00000 00000, {@code sum} = 5 00000 00000 + * Iteration 2 : {@code Math.pow} result = 1 00000, {@code sum} = 5 00001 00000 + * Iteration 3 : {@code Math.pow} result = 1, {@code sum} = 5 00001 00001 + To generate the above results I have multiplied the array values with powers of 10. + The constraints used to generate the power of 10 is explained below, + *

+ * + *

+ {@code Constants.NUM_OF_OS_VERSION_POSITIONS - (i + 1)} was done in-order to identify + which position of the OS version is been used for generation process, so correct number + of Zeros can be generated. + *

+ * + *

+ {@code Constants.NUM_OF_OS_VERSION_DIGITS} this multiplication will make sure that the + values generated will reduce in following order main OS version, minor OS version, Revision. + *

+ */ + return IntStream + .range(0, osVersionsLength) + .mapToLong(i -> (long) (Math.pow(10, (Constants.NUM_OF_OS_VERSION_POSITIONS - (i + 1)) + * Constants.NUM_OF_OS_VERSION_DIGITS) + * Integer.parseInt(osVersions[i]))).sum(); + } + + /** + * Revert a generated value back to a OS version + * + * @param osVersionValue value that should be reverted + * @return {@link String} OS version + */ + /* Following method is unused but was still included in case a requirement occurs to revert the + * generated values in DM_DEVICE_INFO back to a OS versions */ + public static String reverseOSVersionValue(Long osVersionValue) { + StringJoiner joiner = new StringJoiner("."); + + /* + *

Equation explanation

+ * + *

+ Eg: {@code osVersionValue == "5 00001 00001"} + Following loop will divide to break down the above number to regenerate the os version + * Iteration 1 : {@code osVersion} = 5 , {@code osVersionValue} = 00001 00001 + * Iteration 2 : {@code osVersion} = 1 , {@code osVersionValue} = 00001 + * Iteration 3 : {@code osVersion} = 1 , {@code osVersionValue} = 0 + Final array = {@code ["5","1","1"]} + To generate the above results I have divided the generated value with powers of 10. + The constraints used to generate the power of 10 is explained below, + *

+ * + *

+ {@code 10, (i - 1) * Constants.NUM_OF_OS_VERSION_DIGITS} this will break the generated value + creating each OS version position in following order main OS version, minor OS version, + Revision. + *

+ * + */ + for (int i = Constants.NUM_OF_OS_VERSION_POSITIONS; i > 0; i--) { + long osVersion = Double.valueOf( + osVersionValue / Math.pow(10, (i - 1) * Constants.NUM_OF_OS_VERSION_DIGITS)) + .longValue(); + osVersionValue = Double.valueOf( + osVersionValue % Math.pow(10, (i - 1) * Constants.NUM_OF_OS_VERSION_DIGITS)) + .longValue(); + joiner.add(String.valueOf(osVersion)); + } + return joiner.toString(); + } }