From ef47f0c20a2b83728170529a2f70cf9236081f58 Mon Sep 17 00:00:00 2001 From: pasindu Date: Fri, 8 Sep 2023 11:36:05 +0530 Subject: [PATCH 1/5] Update scopes including already existing roles --- .../apimgt/webapp/publisher/APIPublisherServiceImpl.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherServiceImpl.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherServiceImpl.java index 871450c824..61196a1da0 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherServiceImpl.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherServiceImpl.java @@ -513,8 +513,15 @@ public class APIPublisherServiceImpl implements APIPublisherService { if (scopeObj.getString("name").equals(scopeMapping[2] != null ? StringUtils.trim(scopeMapping[2]) : StringUtils.EMPTY)) { scope.setId(scopeObj.getString("id")); + +// Including already existing roles + JSONArray existingRolesArray = (JSONArray) scopeObj.get("bindings"); + for (int j = 0; j < existingRolesArray.length(); j++) { + roleString = roleString + "," + existingRolesArray.get(j); + } } } + scope.setRoles(roleString); if (publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo, scope.getKey())) { publisherRESTAPIServices.updateSharedScope(apiApplicationKey, accessTokenInfo, scope); From 9011273ff4b2531b0d46b091491586980f5175d1 Mon Sep 17 00:00:00 2001 From: Charitha Goonetilleke Date: Tue, 12 Sep 2023 11:55:29 +0530 Subject: [PATCH 2/5] Apply role permission mapping along with scope role mapping --- .../pom.xml | 2 +- .../publisher/APIPublisherServiceImpl.java | 75 ++++++++++++++++--- .../internal/APIPublisherDataHolder.java | 24 ++++++ 3 files changed, 90 insertions(+), 11 deletions(-) diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/pom.xml b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/pom.xml index e108eb7fb1..876a269e11 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/pom.xml +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/pom.xml @@ -187,6 +187,7 @@ io.entgra.device.mgt.core.apimgt.webapp.publisher.lifecycle.util, org.wso2.carbon.base;version="1.0", org.wso2.carbon.context;version="4.6", + org.wso2.carbon;version="4.6", org.wso2.carbon.core;version="4.6", org.wso2.carbon.core.util;version="4.6", org.wso2.carbon.registry.core.service;version="1.0", @@ -195,7 +196,6 @@ org.wso2.carbon.user.core.tenant;version="4.6", org.wso2.carbon.utils;version="4.6", org.wso2.carbon.utils.multitenancy;version="4.6", - org.wso2.carbon.apimgt.impl.definitions, org.apache.commons.lang, org.json diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherServiceImpl.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherServiceImpl.java index 61196a1da0..e815b5877a 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherServiceImpl.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherServiceImpl.java @@ -38,23 +38,24 @@ import io.entgra.device.mgt.core.apimgt.webapp.publisher.config.WebappPublisherC import io.entgra.device.mgt.core.apimgt.webapp.publisher.dto.ApiScope; import io.entgra.device.mgt.core.apimgt.webapp.publisher.dto.ApiUriTemplate; import io.entgra.device.mgt.core.apimgt.webapp.publisher.exception.APIManagerPublisherException; +import io.entgra.device.mgt.core.apimgt.webapp.publisher.internal.APIPublisherDataHolder; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.json.JSONArray; import org.json.JSONObject; +import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.apimgt.api.APIManagementException; import org.wso2.carbon.apimgt.api.APIProvider; import org.wso2.carbon.apimgt.api.model.APIIdentifier; import org.wso2.carbon.apimgt.impl.APIConstants; import org.wso2.carbon.apimgt.impl.APIManagerFactory; import org.wso2.carbon.apimgt.impl.utils.APIUtil; -import io.entgra.device.mgt.core.apimgt.webapp.publisher.config.WebappPublisherConfig; -import io.entgra.device.mgt.core.apimgt.webapp.publisher.dto.ApiScope; -import io.entgra.device.mgt.core.apimgt.webapp.publisher.dto.ApiUriTemplate; -import io.entgra.device.mgt.core.apimgt.webapp.publisher.exception.APIManagerPublisherException; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.user.api.AuthorizationManager; +import org.wso2.carbon.user.api.Permission; import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.user.core.tenant.Tenant; import org.wso2.carbon.user.core.tenant.TenantSearchResult; @@ -454,6 +455,7 @@ public class APIPublisherServiceImpl implements APIPublisherService { log.error(errorMsg, e); throw new APIManagerPublisherException(e); } + UserStoreManager userStoreManager; try { for (String tenantDomain : tenants) { @@ -466,20 +468,40 @@ public class APIPublisherServiceImpl implements APIPublisherService { String fileName = CarbonUtils.getCarbonConfigDirPath() + File.separator + "etc" + File.separator + tenantDomain + ".csv"; + try { + userStoreManager = APIPublisherDataHolder.getInstance().getUserStoreManager(); + } catch (UserStoreException e) { + log.error("Unable to retrieve user store manager for tenant: " + tenantDomain); + return; + } if (Files.exists(Paths.get(fileName))) { BufferedReader br = new BufferedReader(new FileReader(fileName)); int lineNumber = 0; Map roles = new HashMap<>(); - String line = ""; + Map> rolePermissions = new HashMap<>(); + String line; String splitBy = ","; - while ((line = br.readLine()) != null) //returns a Boolean value - { + while ((line = br.readLine()) != null) { //returns a Boolean value lineNumber++; String[] scopeMapping = line.split(splitBy); // use comma as separator + String role; if (lineNumber == 1) { // skip titles - for (int i = 0; i < scopeMapping.length; i++) { - if (i > 3) { - roles.put(i, scopeMapping[i]); // add roles to the map + for (int i = 4; i < scopeMapping.length; i++) { + role = scopeMapping[i]; + roles.put(i, role); // add roles to the map + if (!"admin".equals(role)) { + try { + if (!userStoreManager.isExistingRole(role)) { + try { + addRole(role); + } catch (UserStoreException e) { + log.error("Error occurred when adding new role: " + role, e); + } + } + } catch (UserStoreException e) { + log.error("Error occurred when checking the existence of role: " + role, e); + } + rolePermissions.put(role, new ArrayList<>()); } } continue; @@ -494,11 +516,15 @@ public class APIPublisherServiceImpl implements APIPublisherService { scopeMapping[2] != null ? StringUtils.trim(scopeMapping[2]) : StringUtils.EMPTY); // scope.setPermissions( // scopeMapping[3] != null ? StringUtils.trim(scopeMapping[3]) : StringUtils.EMPTY); + String permission = scopeMapping[3] != null ? StringUtils.trim(scopeMapping[3]) : StringUtils.EMPTY; String roleString = ""; for (int i = 4; i < scopeMapping.length; i++) { if (scopeMapping[i] != null && StringUtils.trim(scopeMapping[i]).equals("Yes")) { roleString = roleString + "," + roles.get(i); + if (rolePermissions.containsKey(roles.get(i)) && StringUtils.isNotEmpty(permission)) { + rolePermissions.get(roles.get(i)).add(permission); + } } } if (roleString.length() > 1) { @@ -532,6 +558,13 @@ public class APIPublisherServiceImpl implements APIPublisherService { } } } + for (String role : rolePermissions.keySet()) { + try { + updatePermissions(role, rolePermissions.get(role)); + } catch (UserStoreException e) { + log.error("Error occurred when adding permissions to role: " + role, e); + } + } } } catch (IOException | DirectoryIteratorException ex) { log.error("failed to read scopes from file.", ex); @@ -560,6 +593,28 @@ public class APIPublisherServiceImpl implements APIPublisherService { } } + private void updatePermissions(String role, List permissions) throws UserStoreException { + AuthorizationManager authorizationManager = APIPublisherDataHolder.getInstance().getUserRealm() + .getAuthorizationManager(); + if (log.isDebugEnabled()) { + log.debug("Updating the role '" + role + "'"); + } + if (permissions != null && !permissions.isEmpty()) { + authorizationManager.clearRoleAuthorization(role); + for (String permission : permissions) { + authorizationManager.authorizeRole(role, permission, CarbonConstants.UI_PERMISSION_ACTION); + } + } + } + + private void addRole(String role) throws UserStoreException { + UserStoreManager userStoreManager = APIPublisherDataHolder.getInstance().getUserStoreManager(); + if (log.isDebugEnabled()) { + log.debug("Persisting the role " + role + " in the underlying user store"); + } + userStoreManager.addRole(role, new String[]{"admin"}, new Permission[0]); + } + private APIInfo getAPI(APIConfig config, boolean includeScopes) { APIInfo apiInfo = new APIInfo(); diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/internal/APIPublisherDataHolder.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/internal/APIPublisherDataHolder.java index bc7b8af32c..4b47f8ba0f 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/internal/APIPublisherDataHolder.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/internal/APIPublisherDataHolder.java @@ -19,7 +19,12 @@ package io.entgra.device.mgt.core.apimgt.webapp.publisher.internal; import io.entgra.device.mgt.core.apimgt.webapp.publisher.APIConfig; import io.entgra.device.mgt.core.apimgt.webapp.publisher.APIPublisherService; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.registry.core.service.RegistryService; +import org.wso2.carbon.user.api.UserRealm; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.user.core.tenant.TenantManager; import org.wso2.carbon.utils.ConfigurationContextService; @@ -79,6 +84,25 @@ public class APIPublisherDataHolder { realmService.getTenantManager() : null); } + public UserStoreManager getUserStoreManager() throws UserStoreException { + if (realmService == null) { + String msg = "Realm service has not initialized."; + throw new IllegalStateException(msg); + } + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + return realmService.getTenantUserRealm(tenantId).getUserStoreManager(); + } + + public UserRealm getUserRealm() throws UserStoreException { + UserRealm realm; + if (realmService == null) { + throw new IllegalStateException("Realm service not initialized"); + } + int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId(); + realm = realmService.getTenantUserRealm(tenantId); + return realm; + } + private void setTenantManager(TenantManager tenantManager) { this.tenantManager = tenantManager; } From 26a049473c6f067945be32d5c5dd1c0dab32a1ac Mon Sep 17 00:00:00 2001 From: Sasini_Sandamali Date: Tue, 12 Sep 2023 16:02:31 +0530 Subject: [PATCH 3/5] Modify View Activities endpoint by including operation id --- .../api/ActivityInfoProviderService.java | 5 +++++ .../impl/ActivityProviderServiceImpl.java | 4 ++++ .../mgt/common/ActivityPaginationRequest.java | 9 +++++++++ .../mgt/common/operation/mgt/Activity.java | 16 ++++++++++++++++ .../mgt/dao/impl/GenericOperationDAOImpl.java | 18 ++++++++++++++++++ .../mgt/dao/util/OperationDAOUtil.java | 1 + 6 files changed, 53 insertions(+) diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/ActivityInfoProviderService.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/ActivityInfoProviderService.java index 23076328e4..240f6bfb01 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/ActivityInfoProviderService.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/ActivityInfoProviderService.java @@ -466,6 +466,11 @@ public interface ActivityInfoProviderService { value = "Operation Code to filter" ) @QueryParam("operationCode") String operationCode, + @ApiParam( + name = "operationId", + value = "Operation Id to filter" + ) + @QueryParam("operationId") int operationId, @ApiParam( name = "deviceType", value = "Device Type to filter" diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/ActivityProviderServiceImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/ActivityProviderServiceImpl.java index d9fec4b91b..0474a81a79 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/ActivityProviderServiceImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/ActivityProviderServiceImpl.java @@ -253,6 +253,7 @@ public class ActivityProviderServiceImpl implements ActivityInfoProviderService @QueryParam("since") String since, @QueryParam("initiatedBy") String initiatedBy, @QueryParam("operationCode") String operationCode, + @QueryParam("operationId") int operationId, @QueryParam("deviceType") String deviceType, @QueryParam("deviceId") List deviceIds, @QueryParam("type") String type, @@ -321,6 +322,9 @@ public class ActivityProviderServiceImpl implements ActivityInfoProviderService if (operationCode != null && !operationCode.isEmpty()) { activityPaginationRequest.setOperationCode(operationCode); } + if (operationId > 0) { + activityPaginationRequest.setOperationId(operationId); + } if (deviceType != null && !deviceType.isEmpty()) { activityPaginationRequest.setDeviceType(deviceType); } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/ActivityPaginationRequest.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/ActivityPaginationRequest.java index b535ab4bd6..058b82dd2f 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/ActivityPaginationRequest.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/ActivityPaginationRequest.java @@ -32,6 +32,7 @@ public class ActivityPaginationRequest { private String deviceType; private List deviceIds; private String operationCode; + private int operationId; private String initiatedBy; private long since; private Operation.Type type; @@ -132,4 +133,12 @@ public class ActivityPaginationRequest { public void setEndTimestamp(long endTimestamp) { this.endTimestamp = endTimestamp; } + + public int getOperationId() { + return operationId; + } + + public void setOperationId(int operationId) { + this.operationId = operationId; + } } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/operation/mgt/Activity.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/operation/mgt/Activity.java index e001d72929..3c68fc74b2 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/operation/mgt/Activity.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/operation/mgt/Activity.java @@ -49,6 +49,14 @@ public class Activity { @JsonProperty("code") private String code; + @ApiModelProperty( + name = "operationId", + value = "Operation Id", + required = false, + example = "10") + @JsonProperty("operationId") + private int operationId; + @ApiModelProperty( name = "type", value = "Activity type", @@ -122,6 +130,14 @@ public class Activity { this.code = code; } + public int getOperationId() { + return operationId; + } + + public void setOperationId(int operationId) { + this.operationId = operationId; + } + public Type getType() { return type; } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java index ff071365c6..5f95cbb62a 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java @@ -2233,6 +2233,9 @@ public class GenericOperationDAOImpl implements OperationDAO { } sql.append("?) "); } + if (activityPaginationRequest.getOperationId() > 0) { + sql.append("AND OPERATION_ID = ? "); + } if (activityPaginationRequest.getOperationCode() != null) { sql.append("AND OPERATION_CODE = ? "); } @@ -2269,6 +2272,9 @@ public class GenericOperationDAOImpl implements OperationDAO { if (activityPaginationRequest.getOperationCode() != null) { sql.append("AND eom.OPERATION_CODE = ? "); } + if (activityPaginationRequest.getOperationId() > 0) { + sql.append("AND eom.OPERATION_ID = ? "); + } if (activityPaginationRequest.getInitiatedBy() != null) { sql.append("AND eom.INITIATED_BY = ? "); } @@ -2301,6 +2307,9 @@ public class GenericOperationDAOImpl implements OperationDAO { if (activityPaginationRequest.getOperationCode() != null) { stmt.setString(index++, activityPaginationRequest.getOperationCode()); } + if (activityPaginationRequest.getOperationId() > 0) { + stmt.setInt(index++, activityPaginationRequest.getOperationId()); + } if (activityPaginationRequest.getInitiatedBy() != null) { stmt.setString(index++, activityPaginationRequest.getInitiatedBy()); } @@ -2333,6 +2342,9 @@ public class GenericOperationDAOImpl implements OperationDAO { if (activityPaginationRequest.getOperationCode() != null) { stmt.setString(index++, activityPaginationRequest.getOperationCode()); } + if (activityPaginationRequest.getOperationId() > 0) { + stmt.setInt(index++, activityPaginationRequest.getOperationId()); + } if (activityPaginationRequest.getInitiatedBy() != null) { stmt.setString(index++, activityPaginationRequest.getInitiatedBy()); } @@ -2390,6 +2402,9 @@ public class GenericOperationDAOImpl implements OperationDAO { if (activityPaginationRequest.getOperationCode() != null) { sql.append("AND OPERATION_CODE = ? "); } + if (activityPaginationRequest.getOperationId() > 0) { + sql.append("AND OPERATION_ID = ? "); + } if (activityPaginationRequest.getInitiatedBy() != null) { sql.append("AND INITIATED_BY = ? "); } @@ -2421,6 +2436,9 @@ public class GenericOperationDAOImpl implements OperationDAO { if (activityPaginationRequest.getOperationCode() != null) { stmt.setString(index++, activityPaginationRequest.getOperationCode()); } + if (activityPaginationRequest.getOperationId() > 0) { + stmt.setInt(index++, activityPaginationRequest.getOperationId()); + } if (activityPaginationRequest.getInitiatedBy() != null) { stmt.setString(index++, activityPaginationRequest.getInitiatedBy()); } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/util/OperationDAOUtil.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/util/OperationDAOUtil.java index 273ec5c089..178cf8f8b3 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/util/OperationDAOUtil.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/util/OperationDAOUtil.java @@ -248,6 +248,7 @@ public class OperationDAOUtil { activity.setCreatedTimeStamp( new java.util.Date(rs.getLong(("CREATED_TIMESTAMP")) * 1000).toString()); activity.setCode(rs.getString("OPERATION_CODE")); + activity.setOperationId(rs.getInt("OPERATION_ID")); activity.setInitiatedBy(rs.getString("INITIATED_BY")); DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); From 4a6e0ce7278a8041deae50b2d400402ab789a2ae Mon Sep 17 00:00:00 2001 From: Sasini_Sandamali Date: Tue, 12 Sep 2023 16:14:54 +0530 Subject: [PATCH 4/5] Update get Activities to increase the performance --- .../mgt/dao/impl/GenericOperationDAOImpl.java | 334 +++++++++++------- .../src/main/resources/dbscripts/cdm/h2.sql | 1 + .../main/resources/dbscripts/cdm/mssql.sql | 10 + .../main/resources/dbscripts/cdm/mysql.sql | 6 + .../main/resources/dbscripts/cdm/oracle.sql | 1 + .../resources/dbscripts/cdm/postgresql.sql | 6 +- 6 files changed, 237 insertions(+), 121 deletions(-) diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java index 5f95cbb62a..fa831c317a 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java @@ -2220,44 +2220,70 @@ public class GenericOperationDAOImpl implements OperationDAO { " DM_ENROLMENT_OP_MAPPING eom " + "LEFT JOIN " + " DM_DEVICE_OPERATION_RESPONSE opr ON opr.EN_OP_MAP_ID = eom.ID " + - "INNER JOIN " + - " (SELECT DISTINCT OPERATION_ID FROM DM_ENROLMENT_OP_MAPPING WHERE TENANT_ID = ? "); + "INNER JOIN "); - if (activityPaginationRequest.getDeviceType() != null) { - sql.append("AND DEVICE_TYPE = ? "); - } - if (activityPaginationRequest.getDeviceIds() != null && !activityPaginationRequest.getDeviceIds().isEmpty()) { - sql.append("AND DEVICE_IDENTIFICATION IN ("); - for (int i = 0; i < activityPaginationRequest.getDeviceIds().size() - 1; i++) { - sql.append("?, "); + if (activityPaginationRequest.getDeviceType() != null || + (activityPaginationRequest.getDeviceIds() != null && !activityPaginationRequest.getDeviceIds().isEmpty()) || + activityPaginationRequest.getSince() != 0 || + activityPaginationRequest.getStatus() != null) { + + sql.append("(SELECT DISTINCT OPERATION_ID FROM DM_ENROLMENT_OP_MAPPING eom WHERE TENANT_ID = ? "); + + if (activityPaginationRequest.getDeviceType() != null) { + sql.append("AND DEVICE_TYPE = ? "); + } + if (activityPaginationRequest.getDeviceIds() != null && !activityPaginationRequest.getDeviceIds().isEmpty()) { + sql.append("AND eom.DEVICE_IDENTIFICATION IN ("); + for (int i = 0; i < activityPaginationRequest.getDeviceIds().size() - 1; i++) { + sql.append("?, "); + } + sql.append("?) "); + } + if (activityPaginationRequest.getOperationId() > 0) { + sql.append("AND OPERATION_ID = ? "); + } + if (activityPaginationRequest.getOperationCode() != null) { + sql.append("AND OPERATION_CODE = ? "); + } + if (activityPaginationRequest.getInitiatedBy() != null) { + sql.append("AND INITIATED_BY = ? "); + } + if (activityPaginationRequest.getSince() != 0) { + sql.append("AND UPDATED_TIMESTAMP > ? "); + } + if (activityPaginationRequest.getStartTimestamp() > 0 && activityPaginationRequest.getEndTimestamp() > 0) { + isTimeDurationFilteringProvided = true; + sql.append("AND CREATED_TIMESTAMP BETWEEN ? AND ? "); + } + if (activityPaginationRequest.getType() != null) { + sql.append("AND TYPE = ? "); + } + if (activityPaginationRequest.getStatus() != null) { + sql.append("AND STATUS = ? "); } - sql.append("?) "); - } - if (activityPaginationRequest.getOperationId() > 0) { - sql.append("AND OPERATION_ID = ? "); - } - if (activityPaginationRequest.getOperationCode() != null) { - sql.append("AND OPERATION_CODE = ? "); - } - if (activityPaginationRequest.getInitiatedBy() != null) { - sql.append("AND INITIATED_BY = ? "); - } - if (activityPaginationRequest.getSince() != 0) { - sql.append("AND UPDATED_TIMESTAMP > ? "); - } - if (activityPaginationRequest.getStartTimestamp() > 0 && activityPaginationRequest.getEndTimestamp() > 0) { - isTimeDurationFilteringProvided = true; - sql.append("AND CREATED_TIMESTAMP BETWEEN ? AND ? "); - } - if (activityPaginationRequest.getType() != null) { - sql.append("AND TYPE = ? "); - } - if (activityPaginationRequest.getStatus() != null) { - sql.append("AND STATUS = ? "); - } - sql.append("ORDER BY OPERATION_ID ASC limit ? , ? ) eom_ordered " + - "ON eom_ordered.OPERATION_ID = eom.OPERATION_ID WHERE eom.TENANT_ID = ? "); + sql.append("ORDER BY OPERATION_ID ASC limit ? , ? ) eom_ordered " + + "ON eom_ordered.OPERATION_ID = eom.OPERATION_ID WHERE eom.TENANT_ID = ? "); + } else { + sql.append("(SELECT ID AS OPERATION_ID FROM DM_OPERATION WHERE TENANT_ID = ? "); + + if (activityPaginationRequest.getStartTimestamp() > 0 && activityPaginationRequest.getEndTimestamp() > 0) { + isTimeDurationFilteringProvided = true; + sql.append("AND CREATED_TIMESTAMP BETWEEN ? AND ? "); + } + if (activityPaginationRequest.getOperationId() > 0) { + sql.append("AND ID = ? "); + } + if (activityPaginationRequest.getOperationCode() != null) { + sql.append("AND OPERATION_CODE = ? "); + } + if (activityPaginationRequest.getInitiatedBy() != null) { + sql.append("AND INITIATED_BY = ? "); + } + + sql.append("ORDER BY ID ASC ) dm_ordered " + + "ON dm_ordered.OPERATION_ID = eom.OPERATION_ID WHERE eom.TENANT_ID = ? "); + } if (activityPaginationRequest.getDeviceType() != null) { sql.append("AND eom.DEVICE_TYPE = ? "); @@ -2282,7 +2308,7 @@ public class GenericOperationDAOImpl implements OperationDAO { sql.append("AND eom.UPDATED_TIMESTAMP > ? "); } if (isTimeDurationFilteringProvided) { - sql.append("AND eom.CREATED_TIMESTAMP BETWEEN ? AND ? "); + sql.append("AND eom.CREATED_TIMESTAMP BETWEEN ? AND ? "); } if (activityPaginationRequest.getType() != null) { sql.append("AND eom.TYPE = ? "); @@ -2296,47 +2322,78 @@ public class GenericOperationDAOImpl implements OperationDAO { int index = 1; try (PreparedStatement stmt = conn.prepareStatement(sql.toString())) { stmt.setInt(index++, tenantId); - if (activityPaginationRequest.getDeviceType() != null) { - stmt.setString(index++, activityPaginationRequest.getDeviceType()); - } - if (activityPaginationRequest.getDeviceIds() != null && !activityPaginationRequest.getDeviceIds().isEmpty()) { - for (String deviceId : activityPaginationRequest.getDeviceIds()) { - stmt.setString(index++, deviceId); + if (activityPaginationRequest.getDeviceType() != null || + (activityPaginationRequest.getDeviceIds() != null && !activityPaginationRequest.getDeviceIds().isEmpty()) || + activityPaginationRequest.getSince() != 0 || + activityPaginationRequest.getStatus() != null) { + + if (activityPaginationRequest.getDeviceType() != null) { + stmt.setString(index++, activityPaginationRequest.getDeviceType()); + } + if (activityPaginationRequest.getDeviceIds() != null && !activityPaginationRequest.getDeviceIds().isEmpty()) { + for (String deviceId : activityPaginationRequest.getDeviceIds()) { + stmt.setString(index++, deviceId); + } + } + if (activityPaginationRequest.getOperationCode() != null) { + stmt.setString(index++, activityPaginationRequest.getOperationCode()); + } + if (activityPaginationRequest.getOperationId() > 0) { + stmt.setInt(index++, activityPaginationRequest.getOperationId()); + } + if (activityPaginationRequest.getInitiatedBy() != null) { + stmt.setString(index++, activityPaginationRequest.getInitiatedBy()); + } + if (activityPaginationRequest.getSince() != 0) { + stmt.setLong(index++, activityPaginationRequest.getSince()); + } + if (isTimeDurationFilteringProvided) { + stmt.setLong(index++, activityPaginationRequest.getStartTimestamp()); + stmt.setLong(index++, activityPaginationRequest.getEndTimestamp()); + } + if (activityPaginationRequest.getType() != null) { + stmt.setString(index++, activityPaginationRequest.getType().name()); + } + if (activityPaginationRequest.getStatus() != null) { + stmt.setString(index++, activityPaginationRequest.getStatus().name()); } - } - if (activityPaginationRequest.getOperationCode() != null) { - stmt.setString(index++, activityPaginationRequest.getOperationCode()); - } - if (activityPaginationRequest.getOperationId() > 0) { - stmt.setInt(index++, activityPaginationRequest.getOperationId()); - } - if (activityPaginationRequest.getInitiatedBy() != null) { - stmt.setString(index++, activityPaginationRequest.getInitiatedBy()); - } - if (activityPaginationRequest.getSince() != 0) { - stmt.setLong(index++, activityPaginationRequest.getSince()); - } - if (isTimeDurationFilteringProvided) { - stmt.setLong(index++, activityPaginationRequest.getStartTimestamp()); - stmt.setLong(index++, activityPaginationRequest.getEndTimestamp()); - } - if (activityPaginationRequest.getType() != null) { - stmt.setString(index++, activityPaginationRequest.getType().name()); - } - if (activityPaginationRequest.getStatus() != null) { - stmt.setString(index++, activityPaginationRequest.getStatus().name()); - } - stmt.setInt(index++, activityPaginationRequest.getOffset()); - stmt.setInt(index++, activityPaginationRequest.getLimit()); - stmt.setInt(index++, tenantId); + stmt.setInt(index++, activityPaginationRequest.getOffset()); + stmt.setInt(index++, activityPaginationRequest.getLimit()); + stmt.setInt(index++, tenantId); - if (activityPaginationRequest.getDeviceType() != null) { - stmt.setString(index++, activityPaginationRequest.getDeviceType()); - } - if (activityPaginationRequest.getDeviceIds() != null && !activityPaginationRequest.getDeviceIds().isEmpty()) { - for (String deviceId : activityPaginationRequest.getDeviceIds()) { - stmt.setString(index++, deviceId); + if (activityPaginationRequest.getDeviceType() != null) { + stmt.setString(index++, activityPaginationRequest.getDeviceType()); + } + if (activityPaginationRequest.getDeviceIds() != null && !activityPaginationRequest.getDeviceIds().isEmpty()) { + for (String deviceId : activityPaginationRequest.getDeviceIds()) { + stmt.setString(index++, deviceId); + } + } + } else { + if (isTimeDurationFilteringProvided) { + stmt.setLong(index++, activityPaginationRequest.getStartTimestamp()); + stmt.setLong(index++, activityPaginationRequest.getEndTimestamp()); + } + if (activityPaginationRequest.getOperationCode() != null) { + stmt.setString(index++, activityPaginationRequest.getOperationCode()); + } + if (activityPaginationRequest.getOperationId() > 0) { + stmt.setInt(index++, activityPaginationRequest.getOperationId()); + } + if (activityPaginationRequest.getInitiatedBy() != null) { + stmt.setString(index++, activityPaginationRequest.getInitiatedBy()); + } + + stmt.setInt(index++, tenantId); + + if (activityPaginationRequest.getDeviceType() != null) { + stmt.setString(index++, activityPaginationRequest.getDeviceType()); + } + if (activityPaginationRequest.getDeviceIds() != null && !activityPaginationRequest.getDeviceIds().isEmpty()) { + for (String deviceId : activityPaginationRequest.getDeviceIds()) { + stmt.setString(index++, deviceId); + } } } if (activityPaginationRequest.getOperationCode() != null) { @@ -2386,70 +2443,107 @@ public class GenericOperationDAOImpl implements OperationDAO { boolean isTimeDurationFilteringProvided = false; Connection conn = OperationManagementDAOFactory.getConnection(); int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); - StringBuilder sql = new StringBuilder("SELECT count(DISTINCT OPERATION_ID) AS ACTIVITY_COUNT " + - "FROM DM_ENROLMENT_OP_MAPPING WHERE TENANT_ID = ? "); + StringBuilder sql = new StringBuilder(); - if (activityPaginationRequest.getDeviceType() != null) { - sql.append("AND DEVICE_TYPE = ? "); - } - if (activityPaginationRequest.getDeviceIds() != null && !activityPaginationRequest.getDeviceIds().isEmpty()) { - sql.append("AND DEVICE_IDENTIFICATION IN ("); - for (int i = 0; i < activityPaginationRequest.getDeviceIds().size() - 1; i++) { - sql.append("?, "); - } - sql.append("?) "); - } - if (activityPaginationRequest.getOperationCode() != null) { - sql.append("AND OPERATION_CODE = ? "); - } - if (activityPaginationRequest.getOperationId() > 0) { - sql.append("AND OPERATION_ID = ? "); - } - if (activityPaginationRequest.getInitiatedBy() != null) { - sql.append("AND INITIATED_BY = ? "); - } - if (activityPaginationRequest.getSince() != 0) { - sql.append("AND UPDATED_TIMESTAMP > ? "); - } - if (activityPaginationRequest.getType() != null) { - sql.append("AND TYPE = ? "); - } - if (activityPaginationRequest.getStatus() != null) { - sql.append("AND STATUS = ? "); - } - if (activityPaginationRequest.getStartTimestamp() > 0 && activityPaginationRequest.getEndTimestamp() > 0) { - isTimeDurationFilteringProvided = true; - sql.append("AND CREATED_TIMESTAMP BETWEEN ? AND ? "); - } + if (activityPaginationRequest.getDeviceType() != null || + (activityPaginationRequest.getDeviceIds() != null && !activityPaginationRequest.getDeviceIds().isEmpty()) || + activityPaginationRequest.getSince() != 0 || + activityPaginationRequest.getStatus() != null) { + + sql.append("SELECT count(DISTINCT OPERATION_ID) AS ACTIVITY_COUNT " + + "FROM DM_ENROLMENT_OP_MAPPING WHERE TENANT_ID = ? "); - int index = 1; - try (PreparedStatement stmt = conn.prepareStatement(sql.toString())) { - stmt.setInt(index++, tenantId); if (activityPaginationRequest.getDeviceType() != null) { - stmt.setString(index++, activityPaginationRequest.getDeviceType()); + sql.append("AND DEVICE_TYPE = ? "); } if (activityPaginationRequest.getDeviceIds() != null && !activityPaginationRequest.getDeviceIds().isEmpty()) { - for (String deviceId : activityPaginationRequest.getDeviceIds()) { - stmt.setString(index++, deviceId); + sql.append("AND DEVICE_IDENTIFICATION IN ("); + for (int i = 0; i < activityPaginationRequest.getDeviceIds().size() - 1; i++) { + sql.append("?, "); } + sql.append("?) "); } if (activityPaginationRequest.getOperationCode() != null) { - stmt.setString(index++, activityPaginationRequest.getOperationCode()); + sql.append("AND OPERATION_CODE = ? "); } if (activityPaginationRequest.getOperationId() > 0) { - stmt.setInt(index++, activityPaginationRequest.getOperationId()); + sql.append("AND OPERATION_ID = ? "); } if (activityPaginationRequest.getInitiatedBy() != null) { - stmt.setString(index++, activityPaginationRequest.getInitiatedBy()); + sql.append("AND INITIATED_BY = ? "); } if (activityPaginationRequest.getSince() != 0) { - stmt.setLong(index++, activityPaginationRequest.getSince()); + sql.append("AND UPDATED_TIMESTAMP > ? "); } if (activityPaginationRequest.getType() != null) { - stmt.setString(index++, activityPaginationRequest.getType().name()); + sql.append("AND TYPE = ? "); } if (activityPaginationRequest.getStatus() != null) { - stmt.setString(index++, activityPaginationRequest.getStatus().name()); + sql.append("AND STATUS = ? "); + } + + } else { + sql.append("SELECT count(ID) AS ACTIVITY_COUNT FROM DM_OPERATION WHERE TENANT_ID = ? "); + + if (activityPaginationRequest.getOperationCode() != null) { + sql.append("AND OPERATION_CODE = ? "); + } + if (activityPaginationRequest.getOperationId() > 0) { + sql.append("AND ID = ? "); + } + if (activityPaginationRequest.getInitiatedBy() != null) { + sql.append("AND INITIATED_BY = ? "); + } + } + if (activityPaginationRequest.getStartTimestamp() > 0 && activityPaginationRequest.getEndTimestamp() > 0) { + isTimeDurationFilteringProvided = true; + sql.append("AND CREATED_TIMESTAMP BETWEEN ? AND ? "); + } + + int index = 1; + try (PreparedStatement stmt = conn.prepareStatement(sql.toString())) { + stmt.setInt(index++, tenantId); + + if (activityPaginationRequest.getDeviceType() != null || + (activityPaginationRequest.getDeviceIds() != null && !activityPaginationRequest.getDeviceIds().isEmpty()) || + activityPaginationRequest.getSince() != 0 || + activityPaginationRequest.getStatus() != null) { + if (activityPaginationRequest.getDeviceType() != null) { + stmt.setString(index++, activityPaginationRequest.getDeviceType()); + } + if (activityPaginationRequest.getDeviceIds() != null && !activityPaginationRequest.getDeviceIds().isEmpty()) { + for (String deviceId : activityPaginationRequest.getDeviceIds()) { + stmt.setString(index++, deviceId); + } + } + if (activityPaginationRequest.getOperationCode() != null) { + stmt.setString(index++, activityPaginationRequest.getOperationCode()); + } + if (activityPaginationRequest.getOperationId() > 0) { + stmt.setInt(index++, activityPaginationRequest.getOperationId()); + } + if (activityPaginationRequest.getInitiatedBy() != null) { + stmt.setString(index++, activityPaginationRequest.getInitiatedBy()); + } + if (activityPaginationRequest.getSince() != 0) { + stmt.setLong(index++, activityPaginationRequest.getSince()); + } + if (activityPaginationRequest.getType() != null) { + stmt.setString(index++, activityPaginationRequest.getType().name()); + } + if (activityPaginationRequest.getStatus() != null) { + stmt.setString(index++, activityPaginationRequest.getStatus().name()); + } + } else { + if (activityPaginationRequest.getOperationCode() != null) { + stmt.setString(index++, activityPaginationRequest.getOperationCode()); + } + if (activityPaginationRequest.getOperationId() > 0) { + stmt.setInt(index++, activityPaginationRequest.getOperationId()); + } + if (activityPaginationRequest.getInitiatedBy() != null) { + stmt.setString(index++, activityPaginationRequest.getInitiatedBy()); + } } if (isTimeDurationFilteringProvided) { stmt.setLong(index++, activityPaginationRequest.getStartTimestamp()); diff --git a/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql b/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql index a0be9fd704..f261a3b49e 100644 --- a/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql +++ b/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql @@ -92,6 +92,7 @@ CREATE TABLE IF NOT EXISTS DM_OPERATION ( INITIATED_BY VARCHAR(100) NULL, OPERATION_DETAILS BLOB DEFAULT NULL, ENABLED BOOLEAN NOT NULL DEFAULT FALSE, + TENANT_ID INT NOT NULL, PRIMARY KEY (ID) ); diff --git a/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql b/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql index 16af46d997..1c0a4b75a4 100644 --- a/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql +++ b/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql @@ -126,9 +126,17 @@ CREATE TABLE DM_OPERATION ( INITIATED_BY VARCHAR(100) NULL, OPERATION_DETAILS VARBINARY(MAX) DEFAULT NULL, ENABLED BIT NOT NULL DEFAULT 0, + TENANT_ID INTEGER NOT NULL, PRIMARY KEY (ID) ); +IF NOT EXISTS (SELECT * FROM SYS.INDEXES WHERE NAME = 'IDX_OP_CREATED' AND OBJECT_ID = OBJECT_ID('DM_OPERATION')) +CREATE INDEX IDX_OP_CREATED ON DM_OPERATION(CREATED_TIMESTAMP); +IF NOT EXISTS (SELECT * FROM SYS.INDEXES WHERE NAME = 'IDX_OP_CODE' AND OBJECT_ID = OBJECT_ID('DM_OPERATION')) +CREATE INDEX IDX_OP_CODE ON DM_OPERATION(OPERATION_CODE); +IF NOT EXISTS (SELECT * FROM SYS.INDEXES WHERE NAME = 'IDX_OP_INITIATED_BY' AND OBJECT_ID = OBJECT_ID('DM_OPERATION')) +CREATE INDEX IDX_OP_INITIATED_BY ON DM_OPERATION(INITIATED_BY); + IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[DM_ENROLMENT]') AND TYPE IN (N'U')) CREATE TABLE DM_ENROLMENT ( ID INTEGER IDENTITY(1,1) NOT NULL, @@ -196,6 +204,8 @@ IF NOT EXISTS (SELECT * FROM SYS.INDEXES WHERE NAME = 'IDX_EN_OP_MAPPING_OP_ID' CREATE INDEX IDX_EN_OP_MAPPING_OP_ID ON DM_ENROLMENT_OP_MAPPING(OPERATION_ID); IF NOT EXISTS (SELECT * FROM SYS.INDEXES WHERE NAME = 'IDX_EN_OP_MAPPING_EN_ID_STATUS' AND OBJECT_ID = OBJECT_ID('DM_ENROLMENT_OP_MAPPING')) CREATE INDEX IDX_EN_OP_MAPPING_EN_ID_STATUS ON DM_ENROLMENT_OP_MAPPING(ENROLMENT_ID, STATUS); +IF NOT EXISTS (SELECT * FROM SYS.INDEXES WHERE NAME = 'IDX_ENROLMENT_OP_MAPPING_CREATED_TS' AND OBJECT_ID = OBJECT_ID('DM_ENROLMENT_OP_MAPPING')) +CREATE INDEX IDX_ENROLMENT_OP_MAPPING_CREATED_TS ON DM_ENROLMENT_OP_MAPPING(CREATED_TIMESTAMP); IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[DM_DEVICE_OPERATION_RESPONSE]') AND TYPE IN (N'U')) CREATE TABLE DM_DEVICE_OPERATION_RESPONSE ( diff --git a/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql b/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql index d184237d44..1ea355fb81 100644 --- a/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql +++ b/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql @@ -107,9 +107,14 @@ CREATE TABLE IF NOT EXISTS DM_OPERATION ( INITIATED_BY VARCHAR(100) NULL, OPERATION_DETAILS BLOB DEFAULT NULL, ENABLED BOOLEAN NOT NULL DEFAULT FALSE, + TENANT_ID INT NOT NULL, PRIMARY KEY (ID) )ENGINE = InnoDB; +CREATE INDEX IDX_OP_CREATED ON DM_OPERATION (CREATED_TIMESTAMP ASC); +CREATE INDEX IDX_OP_CODE ON DM_OPERATION (OPERATION_CODE ASC); +CREATE INDEX IDX_OP_INITIATED_BY ON DM_OPERATION (INITIATED_BY ASC); + CREATE TABLE IF NOT EXISTS DM_ENROLMENT ( ID INTEGER AUTO_INCREMENT NOT NULL, DEVICE_ID INTEGER NOT NULL, @@ -170,6 +175,7 @@ CREATE INDEX IDX_ENROLMENT_OP_MAPPING ON DM_ENROLMENT_OP_MAPPING (UPDATED_TIMEST CREATE INDEX IDX_EN_OP_MAPPING_EN_ID ON DM_ENROLMENT_OP_MAPPING(ENROLMENT_ID); CREATE INDEX IDX_EN_OP_MAPPING_OP_ID ON DM_ENROLMENT_OP_MAPPING(OPERATION_ID); CREATE INDEX IDX_EN_OP_MAPPING_EN_ID_STATUS ON DM_ENROLMENT_OP_MAPPING(ENROLMENT_ID, STATUS); +CREATE INDEX IDX_ENROLMENT_OP_MAPPING_CREATED_TS ON DM_ENROLMENT_OP_MAPPING (CREATED_TIMESTAMP ASC); CREATE TABLE IF NOT EXISTS DM_DEVICE_OPERATION_RESPONSE ( diff --git a/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql b/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql index 60c7aaf89e..f19645cdb7 100644 --- a/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql +++ b/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql @@ -181,6 +181,7 @@ CREATE TABLE DM_OPERATION ( INITIATED_BY VARCHAR2(100) NULL, ENABLED NUMBER(10) DEFAULT 0 NOT NULL, OPERATION_DETAILS BLOB DEFAULT NULL, + TENANT_ID INTEGER NOT NULL, CONSTRAINT PK_DM_OPERATION PRIMARY KEY (ID) ) / diff --git a/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql b/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql index f9f6879338..51361a90d3 100644 --- a/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql +++ b/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql @@ -100,10 +100,13 @@ CREATE TABLE IF NOT EXISTS DM_OPERATION ( INITIATED_BY VARCHAR(100) NULL, OPERATION_DETAILS BYTEA DEFAULT NULL, ENABLED BOOLEAN NOT NULL DEFAULT FALSE, + TENANT_ID INTEGER NOT NULL, PRIMARY KEY (ID) ); - +CREATE INDEX IDX_OP_CREATED ON DM_OPERATION (CREATED_TIMESTAMP); +CREATE INDEX IDX_OP_CODE ON DM_OPERATION (OPERATION_CODE); +CREATE INDEX IDX_OP_INITIATED_BY ON DM_OPERATION (INITIATED_BY); CREATE SEQUENCE DM_ENROLMENT_seq; @@ -161,6 +164,7 @@ CREATE TABLE IF NOT EXISTS DM_ENROLMENT_OP_MAPPING ( CREATE INDEX fk_dm_device_operation_mapping_operation ON DM_ENROLMENT_OP_MAPPING (OPERATION_ID); CREATE INDEX IDX_DM_ENROLMENT_OP_MAPPING ON DM_ENROLMENT_OP_MAPPING (ENROLMENT_ID,OPERATION_ID); CREATE INDEX ID_DM_ENROLMENT_OP_MAPPING_UPDATED_TIMESTAMP ON DM_ENROLMENT_OP_MAPPING (UPDATED_TIMESTAMP); +CREATE INDEX IDX_ENROLMENT_OP_MAPPING_CREATED_TS ON DM_ENROLMENT_OP_MAPPING (CREATED_TIMESTAMP); ALTER TABLE DM_ENROLMENT_OP_MAPPING ADD OPERATION_CODE VARCHAR(50) NOT NULL, From fccae9b8c09049b152ec210b2851c517fb97395a Mon Sep 17 00:00:00 2001 From: Pramila Niroshan Date: Fri, 15 Sep 2023 04:02:34 +0000 Subject: [PATCH 5/5] Add Devices filtering by a Custom Property feature to API and dao layer (#208) ## Purpose * Related ticket https://roadmap.entgra.net/issues/10262 ## Description This modifed API accept any custom property key value pair as a encoded JSON String for filtering devices /devicescustomProperty=%7B%22FIRMWARE_APP_VERSION%22%3A%22122%22%2C%22FIRMWARE_VERSION%22%3A%22123%22%7D ## Add Custom property to mdm-ui-config.xml ``` FIRMWARE_VERSION label_firmware_version deviceDetailsMap FIRMWARE_APP_VERSION label_app_version deviceDetailsMap FIRMWARE_SYSTEM_VERSION label_firmware_system_version deviceDetailsMap ``` DefinedValue = Key_value in DM_DEVECE_INFO table DisplayValue = UI display text for filtering Type = Dont change Co-authored-by: pramilaniroshan Reviewed-on: https://repository.entgra.net/community/device-mgt-core/pulls/208 Co-authored-by: Pramila Niroshan Co-committed-by: Pramila Niroshan --- .../service/api/DeviceManagementService.java | 7 ++ .../impl/DeviceManagementServiceImpl.java | 26 ++++- .../impl/DeviceManagementServiceImplTest.java | 34 +++---- .../device/mgt/common/PaginationRequest.java | 13 +++ .../dao/impl/device/GenericDeviceDAOImpl.java | 97 +++++++++++++++++-- .../dao/impl/device/OracleDeviceDAOImpl.java | 97 +++++++++++++++++-- .../impl/device/PostgreSQLDeviceDAOImpl.java | 97 +++++++++++++++++-- .../impl/device/SQLServerDeviceDAOImpl.java | 97 +++++++++++++++++-- 8 files changed, 414 insertions(+), 54 deletions(-) diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/DeviceManagementService.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/DeviceManagementService.java index 467dd238c7..e3d9416a2c 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/DeviceManagementService.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/DeviceManagementService.java @@ -65,6 +65,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.sql.Timestamp; import java.util.List; +import java.util.Map; /** * Device related REST-API. This can be used to manipulated device related details. @@ -283,6 +284,12 @@ public interface DeviceManagementService { required = false) @QueryParam("serialNumber") String serialNumber, + @ApiParam( + name = "customProperty", + value = "CustomProperty from device as a JSON encoded string.", + required = false) + @QueryParam("customProperty") + String customProperty, @ApiParam( name = "status", value = "Provide the device status details, such as active or inactive.", diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/DeviceManagementServiceImpl.java index 2eaa0a5595..1960d0e41d 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/DeviceManagementServiceImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -18,6 +18,7 @@ package io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.impl; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstallResponse; import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType; @@ -29,7 +30,6 @@ import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.json.JSONObject; import io.entgra.device.mgt.core.apimgt.keymgt.extension.DCRResponse; import io.entgra.device.mgt.core.apimgt.keymgt.extension.TokenRequest; import io.entgra.device.mgt.core.apimgt.keymgt.extension.TokenResponse; @@ -64,7 +64,6 @@ import io.entgra.device.mgt.core.device.mgt.common.type.mgt.DeviceStatus; import io.entgra.device.mgt.core.device.mgt.core.app.mgt.ApplicationManagementProviderService; import io.entgra.device.mgt.core.device.mgt.core.config.DeviceConfigurationManager; import io.entgra.device.mgt.core.device.mgt.core.config.DeviceManagementConfig; -import io.entgra.device.mgt.core.device.mgt.core.dao.TrackerManagementDAOException; import io.entgra.device.mgt.core.device.mgt.core.device.details.mgt.DeviceDetailsMgtException; import io.entgra.device.mgt.core.device.mgt.core.device.details.mgt.DeviceInformationManager; import io.entgra.device.mgt.core.device.mgt.core.dto.DeviceType; @@ -75,10 +74,7 @@ import io.entgra.device.mgt.core.device.mgt.core.search.mgt.SearchManagerService import io.entgra.device.mgt.core.device.mgt.core.search.mgt.SearchMgtException; import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService; import io.entgra.device.mgt.core.device.mgt.core.service.GroupManagementProviderService; -import io.entgra.device.mgt.core.device.mgt.core.traccar.api.service.DeviceAPIClientService; -import io.entgra.device.mgt.core.device.mgt.core.traccar.common.TraccarHandlerConstants; import io.entgra.device.mgt.core.device.mgt.core.util.DeviceManagerUtil; -import io.entgra.device.mgt.core.device.mgt.core.util.HttpReportingUtil; import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.*; import io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.api.DeviceManagementService; import io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.impl.util.InputValidationException; @@ -98,6 +94,7 @@ import javax.validation.Valid; import javax.validation.constraints.Size; import javax.ws.rs.*; import javax.ws.rs.core.Response; +import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -105,6 +102,7 @@ import java.util.Date; import java.util.List; import java.util.Properties; import java.util.concurrent.ExecutionException; +import java.util.Map; @Path("/devices") public class DeviceManagementServiceImpl implements DeviceManagementService { @@ -142,6 +140,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { @QueryParam("role") String role, @QueryParam("ownership") String ownership, @QueryParam("serialNumber") String serialNumber, + @QueryParam("customProperty") String customProperty, @QueryParam("status") List status, @QueryParam("groupId") int groupId, @QueryParam("since") String since, @@ -155,6 +154,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } // RequestValidationUtil.validateSelectionCriteria(type, user, roleName, ownership, status); + final ObjectMapper objectMapper = new ObjectMapper(); RequestValidationUtil.validatePaginationParameters(offset, limit); DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); DeviceAccessAuthorizationService deviceAccessAuthorizationService = @@ -166,6 +166,22 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { if (name != null && !name.isEmpty()) { request.setDeviceName(name); } + if (customProperty != null && !customProperty.isEmpty()) { + try { + Map customProperties = objectMapper.readValue(customProperty, Map.class); + // Extract and set custom properties + for (Map.Entry entry : customProperties.entrySet()) { + String propertyName = entry.getKey(); + String propertyValue = entry.getValue(); + // Add custom property to the paginationRequest object + request.addCustomProperty(propertyName, propertyValue); + } + } catch (IOException e) { + String msg = "Error occurred while converting custom property string to a Java Map"; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } if (type != null && !type.isEmpty()) { request.setDeviceType(type); } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/test/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/DeviceManagementServiceImplTest.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/test/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/DeviceManagementServiceImplTest.java index 3a24db49f5..2ef62073bd 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/test/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/DeviceManagementServiceImplTest.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/test/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/DeviceManagementServiceImplTest.java @@ -157,7 +157,7 @@ public class DeviceManagementServiceImplTest { .toReturn(this.deviceAccessAuthorizationService); Response response = this.deviceManagementService .getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - null, DEFAULT_STATUS_LIST, 1, null, null, false, + null, null, DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); } @@ -177,22 +177,22 @@ public class DeviceManagementServiceImplTest { Response response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - null, DEFAULT_STATUS_LIST, 1, null, null, false, + null,null, DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); response = this.deviceManagementService .getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, null, DEFAULT_OWNERSHIP, - null, DEFAULT_STATUS_LIST, 1, null, null, false, + null, null, DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); response = this.deviceManagementService .getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, null, null, null, DEFAULT_OWNERSHIP, - null, DEFAULT_STATUS_LIST, 1, null, null, false, + null, null, DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); response = this.deviceManagementService .getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, null, null, null, DEFAULT_OWNERSHIP, - null, DEFAULT_STATUS_LIST, 1, null, null, true, + null, null, DEFAULT_STATUS_LIST, 1, null, null, true, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); } @@ -306,7 +306,7 @@ public class DeviceManagementServiceImplTest { .toReturn(this.deviceManagementProviderService); Mockito.when(deviceAccessAuthorizationService.isDeviceAdminUser()).thenReturn(true); deviceManagementService.getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, - DEFAULT_ROLE, DEFAULT_OWNERSHIP, null, DEFAULT_STATUS_LIST, 1, + DEFAULT_ROLE, DEFAULT_OWNERSHIP, null,null, DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); } @@ -326,11 +326,11 @@ public class DeviceManagementServiceImplTest { Response response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP - , null, DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); + , null, null, DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, null, DEFAULT_USERNAME, DEFAULT_ROLE, DEFAULT_OWNERSHIP - , null, DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); + , null, null, DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); } @@ -352,7 +352,7 @@ public class DeviceManagementServiceImplTest { Response response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, "newuser", null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - null, DEFAULT_STATUS_LIST, 0, null, null, false, + null, null, DEFAULT_STATUS_LIST, 0, null, null, false, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode()); Mockito.reset(this.deviceAccessAuthorizationService); @@ -374,17 +374,17 @@ public class DeviceManagementServiceImplTest { Response response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - null, DEFAULT_STATUS_LIST, 0, null, ifModifiedSince, false, + null, null, DEFAULT_STATUS_LIST, 0, null, ifModifiedSince, false, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.NOT_MODIFIED.getStatusCode()); response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - null, DEFAULT_STATUS_LIST, 0, null, ifModifiedSince, true, + null, null, DEFAULT_STATUS_LIST, 0, null, ifModifiedSince, true, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.NOT_MODIFIED.getStatusCode()); response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - null, DEFAULT_STATUS_LIST, 0, null, "ErrorModifiedSince", + null, null, DEFAULT_STATUS_LIST, 0, null, "ErrorModifiedSince", false, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); } @@ -405,17 +405,17 @@ public class DeviceManagementServiceImplTest { Response response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - null, DEFAULT_STATUS_LIST, 0, since, null, false, + null, null,DEFAULT_STATUS_LIST, 0, since, null, false, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - null, DEFAULT_STATUS_LIST, 0, since, null, true, + null, null,DEFAULT_STATUS_LIST, 0, since, null, true, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - null, DEFAULT_STATUS_LIST, 0, "ErrorSince", null, false, + null, null,DEFAULT_STATUS_LIST, 0, "ErrorSince", null, false, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); } @@ -438,7 +438,7 @@ public class DeviceManagementServiceImplTest { Response response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - null, DEFAULT_STATUS_LIST, 1, null, null, false, + null, null, DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); Mockito.reset(this.deviceManagementProviderService); @@ -461,7 +461,7 @@ public class DeviceManagementServiceImplTest { Response response = this.deviceManagementService .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, - null, DEFAULT_STATUS_LIST, 1, null, null, false, + null, null, DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); Mockito.reset(this.deviceAccessAuthorizationService); diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/PaginationRequest.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/PaginationRequest.java index d9c2c62d47..c0783fe18f 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/PaginationRequest.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/PaginationRequest.java @@ -41,6 +41,7 @@ public class PaginationRequest { private Date since; private String filter; private String serialNumber; + private Map customProperty = new HashMap<>(); private Map property = new HashMap<>(); private List statusList = new ArrayList<>(); private OperationLogFilters operationLogFilters = new OperationLogFilters(); @@ -115,6 +116,18 @@ public class PaginationRequest { return ownership; } + public Map getCustomProperty() { + return customProperty; + } + + public void setCustomProperty(Map customProperty) { + this.customProperty = customProperty; + } + + public void addCustomProperty(String key, String value) { + customProperty.put(key, value); + } + public void setOwnership(String ownership) { this.ownership = ownership; } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java index b3c6b8f18a..fbd3b05d24 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java @@ -41,6 +41,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.StringJoiner; +import java.util.Map; /** * This class holds the generic implementation of DeviceDAO which can be used to support ANSI db syntax. @@ -92,14 +93,40 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { "d.DEVICE_IDENTIFICATION, " + "t.NAME AS DEVICE_TYPE "; - if (serial != null) { - sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_INFO i " + - "WHERE DEVICE_TYPE_ID = t.ID " + - "AND d.ID= i.DEVICE_ID " + - "AND i.KEY_FIELD = 'serial' " + - "AND i.VALUE_FIELD LIKE ? " + - "AND d.TENANT_ID = ? "; - isSerialProvided = true; + //Filter by serial number or any Custom Property in DM_DEVICE_INFO + if (serial != null || !request.getCustomProperty().isEmpty()) { + sql = sql + + "FROM DM_DEVICE d " + + "INNER JOIN DM_DEVICE_TYPE t ON d.DEVICE_TYPE_ID = t.ID " + + "WHERE "; + if (serial != null) { + sql += "EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di " + + "WHERE di.DEVICE_ID = d.ID " + + "AND di.KEY_FIELD = 'serial' " + + "AND di.VALUE_FIELD LIKE ? ) "; + isSerialProvided = true; + } + if (!request.getCustomProperty().isEmpty()) { + if (serial != null) { + sql += "AND "; + } + boolean firstCondition = true; + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + if (!firstCondition) { + sql += "AND "; + } + sql += "EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di " + + "WHERE di.DEVICE_ID = d.ID " + + "AND di.KEY_FIELD = '" + entry.getKey() + "' " + + "AND di.VALUE_FIELD LIKE ? ) "; + firstCondition = false; + } + } + sql += "AND d.TENANT_ID = ? "; } else { sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ? "; } @@ -143,6 +170,11 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { if (isSerialProvided) { stmt.setString(paramIdx++, "%" + serial + "%"); } + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + stmt.setString(paramIdx++, "%" + entry.getValue() + "%"); + } + } stmt.setInt(paramIdx++, tenantId); if (isSinceProvided) { stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime())); @@ -624,6 +656,8 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { boolean isStatusProvided = false; Date since = request.getSince(); boolean isSinceProvided = false; + String serial = request.getSerialNumber(); + boolean isSerialProvided = false; try { Connection conn = getConnection(); @@ -692,6 +726,28 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { sql += buildStatusQuery(statusList); isStatusProvided = true; } + //Filter Group with serial number or any Custom Property in DM_DEVICE_INFO + if (serial != null || !request.getCustomProperty().isEmpty()) { + if (serial != null) { + sql += "AND EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di " + + "WHERE di.DEVICE_ID = d1.DEVICE_ID " + + "AND di.KEY_FIELD = 'serial' " + + "AND di.VALUE_FIELD LIKE ?) "; + isSerialProvided = true; + } + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + sql += "AND EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di2 " + + "WHERE di2.DEVICE_ID = d1.DEVICE_ID " + + "AND di2.KEY_FIELD = '" + entry.getKey() + "' " + + "AND di2.VALUE_FIELD LIKE ?)"; + } + } + } sql = sql + " LIMIT ?,?"; try (PreparedStatement stmt = conn.prepareStatement(sql)) { @@ -721,6 +777,14 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { stmt.setString(paramIdx++, status); } } + if (isSerialProvided) { + stmt.setString(paramIdx++, "%" + serial + "%"); + } + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + stmt.setString(paramIdx++, "%" + entry.getValue() + "%"); + } + } stmt.setInt(paramIdx++, request.getStartIndex()); stmt.setInt(paramIdx, request.getRowCount()); @@ -1250,6 +1314,17 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { query += buildStatusQuery(status); isStatusProvided = true; } + // Loop through custom properties and add conditions + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + query += " AND EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di2 " + + "WHERE di2.DEVICE_ID = DM_DEVICE.ID " + + "AND di2.KEY_FIELD = '" + entry.getKey() + "' " + + "AND di2.VALUE_FIELD LIKE ?)"; + } + } query = query + " LIMIT ?,?"; @@ -1277,6 +1352,12 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { ps.setString(index++, deviceStatus); } } + // Set custom property values in the loop + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + ps.setString(index++, "%" + entry.getValue() + "%"); + } + } ps.setInt(index++, offsetValue); ps.setInt(index, limitValue); diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java index 722a19b4bf..cecf4e510b 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java @@ -42,6 +42,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.StringJoiner; +import java.util.Map; /** * This class holds the generic implementation of DeviceDAO which can be used to support ANSI db syntax. @@ -93,14 +94,40 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { "d.DEVICE_IDENTIFICATION, " + "t.NAME AS DEVICE_TYPE "; - if (serial != null) { - sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_INFO i " + - "WHERE DEVICE_TYPE_ID = t.ID " + - "AND d.ID= i.DEVICE_ID " + - "AND i.KEY_FIELD = 'serial' " + - "AND i.VALUE_FIELD LIKE ? " + - "AND d.TENANT_ID = ? "; - isSerialProvided = true; + //Filter by serial number or any Custom Property in DM_DEVICE_INFO + if (serial != null || !request.getCustomProperty().isEmpty()) { + sql = sql + + "FROM DM_DEVICE d " + + "INNER JOIN DM_DEVICE_TYPE t ON d.DEVICE_TYPE_ID = t.ID " + + "WHERE "; + if (serial != null) { + sql += "EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di " + + "WHERE di.DEVICE_ID = d.ID " + + "AND di.KEY_FIELD = 'serial' " + + "AND di.VALUE_FIELD LIKE ? ) "; + isSerialProvided = true; + } + if (!request.getCustomProperty().isEmpty()) { + if (serial != null) { + sql += "AND "; + } + boolean firstCondition = true; + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + if (!firstCondition) { + sql += "AND "; + } + sql += "EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di " + + "WHERE di.DEVICE_ID = d.ID " + + "AND di.KEY_FIELD = '" + entry.getKey() + "' " + + "AND di.VALUE_FIELD LIKE ? ) "; + firstCondition = false; + } + } + sql += "AND d.TENANT_ID = ? "; } else { sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ? "; } @@ -144,6 +171,11 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { if (isSerialProvided) { stmt.setString(paramIdx++, "%" + serial + "%"); } + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + stmt.setString(paramIdx++, "%" + entry.getValue() + "%"); + } + } stmt.setInt(paramIdx++, tenantId); if (isSinceProvided) { stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime())); @@ -454,6 +486,8 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { boolean isStatusProvided = false; Date since = request.getSince(); boolean isSinceProvided = false; + String serial = request.getSerialNumber(); + boolean isSerialProvided = false; try { conn = getConnection(); @@ -522,6 +556,28 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { sql += buildStatusQuery(statusList); isStatusProvided = true; } + //Filter Group with serial number or any Custom Property in DM_DEVICE_INFO + if (serial != null || !request.getCustomProperty().isEmpty()) { + if (serial != null) { + sql += "AND EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di " + + "WHERE di.DEVICE_ID = d1.DEVICE_ID " + + "AND di.KEY_FIELD = 'serial' " + + "AND di.VALUE_FIELD LIKE ?) "; + isSerialProvided = true; + } + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + sql += "AND EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di2 " + + "WHERE di2.DEVICE_ID = d1.DEVICE_ID " + + "AND di2.KEY_FIELD = '" + entry.getKey() + "' " + + "AND di2.VALUE_FIELD LIKE ?)"; + } + } + } sql = sql + " ORDER BY ENROLMENT_ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; try (PreparedStatement stmt = conn.prepareStatement(sql)) { @@ -551,6 +607,14 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { stmt.setString(paramIdx++, status); } } + if (isSerialProvided) { + stmt.setString(paramIdx++, "%" + serial + "%"); + } + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + stmt.setString(paramIdx++, "%" + entry.getValue() + "%"); + } + } stmt.setInt(paramIdx++, request.getStartIndex()); stmt.setInt(paramIdx, request.getRowCount()); @@ -1035,6 +1099,17 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { query += buildStatusQuery(status); isStatusProvided = true; } + // Loop through custom properties and add conditions + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + query += " AND EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di2 " + + "WHERE di2.DEVICE_ID = DM_DEVICE.ID " + + "AND di2.KEY_FIELD = '" + entry.getKey() + "' " + + "AND di2.VALUE_FIELD LIKE ?)"; + } + } query = query + " ORDER BY DM_DEVICE.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; @@ -1059,6 +1134,12 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { ps.setString(index++, deviceStatus); } } + // Set custom property values in the loop + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + ps.setString(index++, "%" + entry.getValue() + "%"); + } + } ps.setInt(index++, offsetValue); ps.setInt(index, limitValue); diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java index 7b0cd9369b..c467165851 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java @@ -41,6 +41,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.StringJoiner; +import java.util.Map; /** * This class holds the generic implementation of DeviceDAO which can be used to support ANSI db syntax. @@ -92,14 +93,40 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl { "d.DEVICE_IDENTIFICATION, " + "t.NAME AS DEVICE_TYPE "; - if (serial != null) { - sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_INFO i " + - "WHERE DEVICE_TYPE_ID = t.ID " + - "AND d.ID= i.DEVICE_ID " + - "AND i.KEY_FIELD = 'serial' " + - "AND i.VALUE_FIELD LIKE ? " + - "AND d.TENANT_ID = ? "; - isSerialProvided = true; + //Filter by serial number or any Custom Property in DM_DEVICE_INFO + if (serial != null || !request.getCustomProperty().isEmpty()) { + sql = sql + + "FROM DM_DEVICE d " + + "INNER JOIN DM_DEVICE_TYPE t ON d.DEVICE_TYPE_ID = t.ID " + + "WHERE "; + if (serial != null) { + sql += "EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di " + + "WHERE di.DEVICE_ID = d.ID " + + "AND di.KEY_FIELD = 'serial' " + + "AND di.VALUE_FIELD LIKE ? ) "; + isSerialProvided = true; + } + if (!request.getCustomProperty().isEmpty()) { + if (serial != null) { + sql += "AND "; + } + boolean firstCondition = true; + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + if (!firstCondition) { + sql += "AND "; + } + sql += "EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di " + + "WHERE di.DEVICE_ID = d.ID " + + "AND di.KEY_FIELD = '" + entry.getKey() + "' " + + "AND di.VALUE_FIELD LIKE ? ) "; + firstCondition = false; + } + } + sql += "AND d.TENANT_ID = ? "; } else { sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ? "; } @@ -138,6 +165,11 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl { if (isSerialProvided) { stmt.setString(paramIdx++, "%" + serial + "%"); } + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + stmt.setString(paramIdx++, "%" + entry.getValue() + "%"); + } + } stmt.setInt(paramIdx++, tenantId); if (isDeviceTypeProvided) { stmt.setString(paramIdx++, deviceType); @@ -435,6 +467,8 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl { boolean isStatusProvided = false; Date since = request.getSince(); boolean isSinceProvided = false; + String serial = request.getSerialNumber(); + boolean isSerialProvided = false; try { conn = getConnection(); @@ -502,6 +536,28 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl { sql += buildStatusQuery(statusList); isStatusProvided = true; } + //Filter Group with serial number or any Custom Property in DM_DEVICE_INFO + if (serial != null || !request.getCustomProperty().isEmpty()) { + if (serial != null) { + sql += "AND EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di " + + "WHERE di.DEVICE_ID = d1.DEVICE_ID " + + "AND di.KEY_FIELD = 'serial' " + + "AND di.VALUE_FIELD LIKE ?) "; + isSerialProvided = true; + } + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + sql += "AND EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di2 " + + "WHERE di2.DEVICE_ID = d1.DEVICE_ID " + + "AND di2.KEY_FIELD = '" + entry.getKey() + "' " + + "AND di2.VALUE_FIELD LIKE ?)"; + } + } + } sql = sql + " LIMIT ? OFFSET ?"; try (PreparedStatement stmt = conn.prepareStatement(sql)) { @@ -531,6 +587,14 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl { stmt.setString(paramIdx++, status); } } + if (isSerialProvided) { + stmt.setString(paramIdx++, "%" + serial + "%"); + } + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + stmt.setString(paramIdx++, "%" + entry.getValue() + "%"); + } + } stmt.setInt(paramIdx++, request.getRowCount()); stmt.setInt(paramIdx, request.getStartIndex()); @@ -1014,6 +1078,17 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl { query += buildStatusQuery(status); isStatusProvided = true; } + // Loop through custom properties and add conditions + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + query += " AND EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di2 " + + "WHERE di2.DEVICE_ID = DM_DEVICE.ID " + + "AND di2.KEY_FIELD = '" + entry.getKey() + "' " + + "AND di2.VALUE_FIELD LIKE ?)"; + } + } query = query + " LIMIT ? OFFSET ?"; @@ -1038,6 +1113,12 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl { ps.setString(index++, deviceStatus); } } + // Set custom property values in the loop + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + ps.setString(index++, "%" + entry.getValue() + "%"); + } + } ps.setInt(index++, offsetValue); ps.setInt(index, limitValue); diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java index 3a7f0f95b9..5628b77a2d 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java @@ -43,6 +43,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.StringJoiner; +import java.util.Map; /** * This class holds the generic implementation of DeviceDAO which can be used to support ANSI db syntax. @@ -94,14 +95,40 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { "d.DEVICE_IDENTIFICATION, " + "t.NAME AS DEVICE_TYPE "; - if (serial != null) { - sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_INFO i " + - "WHERE DEVICE_TYPE_ID = t.ID " + - "AND d.ID= i.DEVICE_ID " + - "AND i.KEY_FIELD = 'serial' " + - "AND i.VALUE_FIELD LIKE ? " + - "AND d.TENANT_ID = ? "; - isSerialProvided = true; + //Filter by serial number or any Custom Property in DM_DEVICE_INFO + if (serial != null || !request.getCustomProperty().isEmpty()) { + sql = sql + + "FROM DM_DEVICE d " + + "INNER JOIN DM_DEVICE_TYPE t ON d.DEVICE_TYPE_ID = t.ID " + + "WHERE "; + if (serial != null) { + sql += "EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di " + + "WHERE di.DEVICE_ID = d.ID " + + "AND di.KEY_FIELD = 'serial' " + + "AND di.VALUE_FIELD LIKE ? ) "; + isSerialProvided = true; + } + if (!request.getCustomProperty().isEmpty()) { + if (serial != null) { + sql += "AND "; + } + boolean firstCondition = true; + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + if (!firstCondition) { + sql += "AND "; + } + sql += "EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di " + + "WHERE di.DEVICE_ID = d.ID " + + "AND di.KEY_FIELD = '" + entry.getKey() + "' " + + "AND di.VALUE_FIELD LIKE ? ) "; + firstCondition = false; + } + } + sql += "AND d.TENANT_ID = ? "; } else { sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ? "; } @@ -145,6 +172,11 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { if (isSerialProvided) { stmt.setString(paramIdx++, "%" + serial + "%"); } + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + stmt.setString(paramIdx++, "%" + entry.getValue() + "%"); + } + } stmt.setInt(paramIdx++, tenantId); if (isSinceProvided) { stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime())); @@ -455,6 +487,8 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { boolean isStatusProvided = false; Date since = request.getSince(); boolean isSinceProvided = false; + String serial = request.getSerialNumber(); + boolean isSerialProvided = false; try { conn = getConnection(); @@ -522,6 +556,28 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { sql += buildStatusQuery(statusList); isStatusProvided = true; } + //Filter Group with serial number or any Custom Property in DM_DEVICE_INFO + if (serial != null || !request.getCustomProperty().isEmpty()) { + if (serial != null) { + sql += "AND EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di " + + "WHERE di.DEVICE_ID = d1.DEVICE_ID " + + "AND di.KEY_FIELD = 'serial' " + + "AND di.VALUE_FIELD LIKE ?) "; + isSerialProvided = true; + } + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + sql += "AND EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di2 " + + "WHERE di2.DEVICE_ID = d1.DEVICE_ID " + + "AND di2.KEY_FIELD = '" + entry.getKey() + "' " + + "AND di2.VALUE_FIELD LIKE ?)"; + } + } + } sql = sql + " ORDER BY ENROLMENT_ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; try (PreparedStatement stmt = conn.prepareStatement(sql)) { @@ -551,6 +607,14 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { stmt.setString(paramIdx++, status); } } + if (isSerialProvided) { + stmt.setString(paramIdx++, "%" + serial + "%"); + } + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + stmt.setString(paramIdx++, "%" + entry.getValue() + "%"); + } + } stmt.setInt(paramIdx++, request.getStartIndex()); stmt.setInt(paramIdx, request.getRowCount()); @@ -883,6 +947,17 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { query += buildStatusQuery(status); isStatusProvided = true; } + // Loop through custom properties and add conditions + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + query += " AND EXISTS (" + + "SELECT VALUE_FIELD " + + "FROM DM_DEVICE_INFO di2 " + + "WHERE di2.DEVICE_ID = DM_DEVICE.ID " + + "AND di2.KEY_FIELD = '" + entry.getKey() + "' " + + "AND di2.VALUE_FIELD LIKE ?)"; + } + } query = query + " ORDER BY DM_DEVICE.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; @@ -907,6 +982,12 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { ps.setString(index++, deviceStatus); } } + // Set custom property values in the loop + if (!request.getCustomProperty().isEmpty()) { + for (Map.Entry entry : request.getCustomProperty().entrySet()) { + ps.setString(index++, "%" + entry.getValue() + "%"); + } + } ps.setInt(index++, offsetValue); ps.setInt(index, limitValue);