From 65ac47aec0d4bac537e9db9dd870e7b8e90971ea Mon Sep 17 00:00:00 2001 From: Rajitha Kumara Date: Fri, 31 May 2024 07:21:12 +0530 Subject: [PATCH 1/6] Add missing permission --- .../templates/repository/conf/cdm-config.xml.j2 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/conf_templates/templates/repository/conf/cdm-config.xml.j2 b/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/conf_templates/templates/repository/conf/cdm-config.xml.j2 index 259a12301a..59e026f679 100644 --- a/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/conf_templates/templates/repository/conf/cdm-config.xml.j2 +++ b/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/conf_templates/templates/repository/conf/cdm-config.xml.j2 @@ -469,6 +469,14 @@ Internal/devicemgt-user + + /permission/admin/device-mgt/devices/any-group/permitted-actions-under-owning-group + + Apply permitted actions on any group + dm:group:any:permitted + Internal/devicemgt-user + + From aca7aa3ccc7ac6105fa7513c90f98787427e17f0 Mon Sep 17 00:00:00 2001 From: Charitha Date: Sun, 2 Jun 2024 10:04:47 +0530 Subject: [PATCH 2/6] Disable validateOperationCodeFiltering for validateOperationLogFilters --- .../api/jaxrs/service/impl/util/RequestValidationUtil.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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/util/RequestValidationUtil.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/util/RequestValidationUtil.java index 5eb474cb32..71d875a6b9 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/util/RequestValidationUtil.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/util/RequestValidationUtil.java @@ -574,7 +574,11 @@ public class RequestValidationUtil { } if (operationCode != null && !operationCode.isEmpty()) { - validateOperationCodeFiltering(operationCode, type); + /* + Commenting this as dynamic device types doesn't have configuration based feature manager which + used to define fixed set of operation codes. + */ +// validateOperationCodeFiltering(operationCode, type); operationLogFilters.setOperationCode(operationCode); } return operationLogFilters; From 641ddbfb85c8f3b8cdcfeba30d423502c087b80f Mon Sep 17 00:00:00 2001 From: pramilaniroshan Date: Thu, 6 Jun 2024 09:50:27 +0530 Subject: [PATCH 3/6] Fix sql syntax errors --- .../jaxrs/service/impl/GroupManagementServiceImpl.java | 2 +- .../device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java | 7 +++---- .../device/mgt/core/dao/impl/AbstractGroupDAOImpl.java | 8 ++++---- 3 files changed, 8 insertions(+), 9 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/impl/GroupManagementServiceImpl.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/GroupManagementServiceImpl.java index fc8f080b07..e8c56680b1 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/GroupManagementServiceImpl.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/GroupManagementServiceImpl.java @@ -273,7 +273,7 @@ public class GroupManagementServiceImpl implements GroupManagementService { ); return Response.status(Response.Status.OK).build(); } catch (GroupManagementException e) { - String msg = "Error occurred while adding new group."; + String msg = "Error occurred while updating group. "; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } catch (GroupNotExistException e) { 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/AbstractDeviceDAOImpl.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/AbstractDeviceDAOImpl.java index 7ab1cdb6e3..e95183d8c3 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/AbstractDeviceDAOImpl.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/AbstractDeviceDAOImpl.java @@ -176,7 +176,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { + "d.DESCRIPTION, " + "d.NAME, " + "d.LAST_UPDATED_TIMESTAMP " - + "FROM DM_DEVICE d" + + "FROM DM_DEVICE d WHERE " + "d.DEVICE_IDENTIFICATION = ? AND " + "d.TENANT_ID = ?"; @@ -197,7 +197,6 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { try (PreparedStatement stmt = conn.prepareStatement(sql)) { int paramIndx = 1; - stmt.setString(paramIndx++, deviceData.getDeviceIdentifier().getType()); stmt.setString(paramIndx++, deviceData.getDeviceIdentifier().getId()); stmt.setInt(paramIndx++, tenantId); if (deviceData.getLastModifiedDate() != null) { @@ -964,12 +963,12 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { + "d.NAME AS DEVICE_NAME, " + "d.DEVICE_IDENTIFICATION, " + "d.LAST_UPDATED_TIMESTAMP, " - + "e.DEVICE_TYPE " + + "e1.DEVICE_TYPE " + "FROM " + "DM_DEVICE d, " + "(SELECT " + "e.OWNER, " - + "e.DEVICE_TYPE " + + "e.DEVICE_TYPE, " + "e.OWNERSHIP, " + "e.ID AS ENROLMENT_ID, " + "e.DEVICE_ID, " 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/AbstractGroupDAOImpl.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/AbstractGroupDAOImpl.java index 374c1ca0aa..c65692870d 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/AbstractGroupDAOImpl.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/AbstractGroupDAOImpl.java @@ -1282,8 +1282,8 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { StringJoiner joiner = new StringJoiner(",","SELECT " + "d1.DEVICE_ID, " + "d1.DESCRIPTION, " - + "e.DEVICE_NAME, " - + "d1.DEVICE_TYPE, " + + "d1.NAME AS DEVICE_NAME, " + + "e.DEVICE_TYPE, " + "d1.DEVICE_IDENTIFICATION, " + "d1.LAST_UPDATED_TIMESTAMP, " + "e.OWNER, " @@ -1343,8 +1343,8 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { String sql = "SELECT " + "d1.DEVICE_ID, " + "d1.DESCRIPTION, " - + "e.DEVICE_NAME, " - + "d1.DEVICE_TYPE, " + + "d1.NAME AS DEVICE_NAME, " + + "e.DEVICE_TYPE, " + "d1.DEVICE_IDENTIFICATION, " + "d1.LAST_UPDATED_TIMESTAMP, " + "e.OWNER, " From f0c48c585de2311dd71cae55e46164b77645158d Mon Sep 17 00:00:00 2001 From: pramilaniroshan Date: Fri, 7 Jun 2024 13:04:51 +0530 Subject: [PATCH 4/6] Fix sql syntax errors --- .../mgt/core/dao/impl/AbstractDeviceDAOImpl.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 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/dao/impl/AbstractDeviceDAOImpl.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/AbstractDeviceDAOImpl.java index e95183d8c3..58bfed7d4a 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/AbstractDeviceDAOImpl.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/AbstractDeviceDAOImpl.java @@ -1036,12 +1036,12 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { "(SELECT gd.DEVICE_ID, " + "gd.DESCRIPTION, " + "gd.NAME, " + - "gd.DEVICE_IDENTIFICATION, " + + "gd.DEVICE_IDENTIFICATION " + "FROM " + "(SELECT d.ID AS DEVICE_ID, " + "d.DESCRIPTION, " + "d.NAME, " + - "d.DEVICE_IDENTIFICATION, " + + "d.DEVICE_IDENTIFICATION " + "FROM DM_DEVICE d, " + "(SELECT dgm.DEVICE_ID " + "FROM DM_DEVICE_GROUP_MAP dgm " + @@ -2365,7 +2365,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { "e.device_id," + "e.status, " + "e.date_of_last_update, " + - "e.date_of_enrolment " + + "e.date_of_enrolment, " + "e.DEVICE_TYPE " + "FROM dm_enrolment e " + "INNER JOIN " + @@ -2375,7 +2375,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { "KEY_FIELD = 'encryptionEnabled' " + "AND VALUE_FIELD = ?) AS di " + "ON di.DEVICE_ID = e.DEVICE_ID " + - "WHERE e.tenant_id = ?) e1, " + + "WHERE e.tenant_id = ?) e1 " + "WHERE d.id = e1.device_id " + "ORDER BY e1.date_of_last_update DESC " + "LIMIT ? OFFSET ?"; @@ -2409,7 +2409,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { try { Connection conn = getConnection(); String sql = - "SELECT COUNT(DEVICE_ID) " + + "SELECT COUNT(DEVICE_ID) AS DEVICE_COUNT " + "FROM DM_DEVICE_INFO " + "WHERE KEY_FIELD = 'encryptionEnabled' " + "AND VALUE_FIELD = ?"; @@ -2417,7 +2417,6 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { try (PreparedStatement ps = conn.prepareStatement(sql)) { ps.setBoolean(1, isEncrypted); - ps.setInt(2, tenantId); try (ResultSet rs = ps.executeQuery()) { return rs.next() ? rs.getInt("DEVICE_COUNT") : 0; From 2da954275aec70ad263c42e76c4f335d59214c00 Mon Sep 17 00:00:00 2001 From: Kavin Prathaban Date: Tue, 28 May 2024 11:18:44 +0000 Subject: [PATCH 5/6] Modify methods to categorize device subscriptions ## Purpose * Fixes https://roadmap.entgra.net/issues/11162 Co-authored-by: Kavin Prathaban Co-committed-by: Kavin Prathaban --- .../common/CategorizedSubscriptionResult.java | 41 ++++++++ .../common/services/SubscriptionManager.java | 3 +- .../core/impl/SubscriptionManagerImpl.java | 95 +++++++++++-------- 3 files changed, 96 insertions(+), 43 deletions(-) create mode 100644 components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java new file mode 100644 index 0000000000..8e59f287a3 --- /dev/null +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java @@ -0,0 +1,41 @@ +package io.entgra.device.mgt.core.application.mgt.common; + +import java.util.List; + +public class CategorizedSubscriptionResult { + private List installedDevices; + private List pendingDevices; + private List errorDevices; + + public CategorizedSubscriptionResult(List installedDevices, + List pendingDevices, + List errorDevices) { + this.installedDevices = installedDevices; + this.pendingDevices = pendingDevices; + this.errorDevices = errorDevices; + } + + public List getInstalledDevices() { + return installedDevices; + } + + public void setInstalledDevices(List installedDevices) { + this.installedDevices = installedDevices; + } + + public List getPendingDevices() { + return pendingDevices; + } + + public void setPendingDevices(List pendingDevices) { + this.pendingDevices = pendingDevices; + } + + public List getErrorDevices() { + return errorDevices; + } + + public void setErrorDevices(List errorDevices) { + this.errorDevices = errorDevices; + } +} diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java index e06a17cb9b..c5b8ac8153 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java @@ -18,6 +18,7 @@ package io.entgra.device.mgt.core.application.mgt.common.services; import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstallResponse; +import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus; import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException; @@ -194,7 +195,7 @@ public interface SubscriptionManager { * application release for given UUID, if an error occurred while getting device details of subscribed device ids, * if an error occurred while getting subscription details of given application release UUID. */ - PaginationResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, String action, String installedVersion) + CategorizedSubscriptionResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, String action, String installedVersion) throws ApplicationManagementException; /*** diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java index 931c45ddcf..ddfd1cfe46 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java @@ -19,17 +19,28 @@ package io.entgra.device.mgt.core.application.mgt.core.impl; import com.google.gson.Gson; +import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstallResponse; +import io.entgra.device.mgt.core.application.mgt.common.ApplicationSubscriptionInfo; +import io.entgra.device.mgt.core.application.mgt.common.ApplicationType; +import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; +import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscriptionData; +import io.entgra.device.mgt.core.application.mgt.common.DeviceTypes; +import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus; +import io.entgra.device.mgt.core.application.mgt.common.SubAction; +import io.entgra.device.mgt.core.application.mgt.common.SubscribingDeviceIdHolder; +import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType; import io.entgra.device.mgt.core.application.mgt.common.dto.VppAssetDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.VppUserDTO; import io.entgra.device.mgt.core.application.mgt.common.services.VPPApplicationManager; import io.entgra.device.mgt.core.application.mgt.core.dao.VppApplicationDAO; import io.entgra.device.mgt.core.application.mgt.core.exception.BadRequestException; +import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; +import io.entgra.device.mgt.core.device.mgt.common.PaginationResult; import io.entgra.device.mgt.core.device.mgt.core.DeviceManagementConstants; import io.entgra.device.mgt.core.application.mgt.core.exception.UnexpectedServerErrorException; import io.entgra.device.mgt.core.device.mgt.extensions.logger.spi.EntgraLogger; import io.entgra.device.mgt.core.notification.logger.AppInstallLogContext; import io.entgra.device.mgt.core.notification.logger.impl.EntgraAppInstallLoggerImpl; -import org.apache.commons.httpclient.HttpClient; import org.apache.commons.lang.StringUtils; import org.apache.http.HttpResponse; @@ -45,15 +56,6 @@ import org.json.JSONObject; import io.entgra.device.mgt.core.apimgt.application.extension.dto.ApiApplicationKey; import io.entgra.device.mgt.core.apimgt.application.extension.exception.APIManagerException; import org.wso2.carbon.context.PrivilegedCarbonContext; -import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstallResponse; -import io.entgra.device.mgt.core.application.mgt.common.ApplicationSubscriptionInfo; -import io.entgra.device.mgt.core.application.mgt.common.ApplicationType; -import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscriptionData; -import io.entgra.device.mgt.core.application.mgt.common.DeviceTypes; -import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus; -import io.entgra.device.mgt.core.application.mgt.common.SubAction; -import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType; -import io.entgra.device.mgt.core.application.mgt.common.SubscribingDeviceIdHolder; import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationPolicyDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO; @@ -1505,16 +1507,19 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } @Override - public PaginationResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, - String action, String installedVersion) throws ApplicationManagementException { + public CategorizedSubscriptionResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, + String action, String installedVersion) throws ApplicationManagementException { int limitValue = request.getRowCount(); int offsetValue = request.getStartIndex(); int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); - DeviceManagementProviderService deviceManagementProviderService = HelperUtil - .getDeviceManagementProviderService(); + DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); + List installedDevices = new ArrayList<>(); + List pendingDevices = new ArrayList<>(); + List errorDevices = new ArrayList<>(); + if (offsetValue < 0 || limitValue <= 0) { - String msg = "Found incompatible values for offset and limit. Hence please check the request and resend. " - + "Offset " + offsetValue + " limit " + limitValue; + String msg = "Found incompatible values for offset and limit. Hence please check the request and resend. " + + "Offset " + offsetValue + " limit " + limitValue; log.error(msg); throw new BadRequestException(msg); } @@ -1532,31 +1537,25 @@ public class SubscriptionManagerImpl implements SubscriptionManager { List deviceSubscriptionDTOS = subscriptionDAO .getDeviceSubscriptions(applicationReleaseId, tenantId, actionStatus, action); if (deviceSubscriptionDTOS.isEmpty()) { - PaginationResult paginationResult = new PaginationResult(); - paginationResult.setData(new ArrayList<>()); - paginationResult.setRecordsFiltered(0); - paginationResult.setRecordsTotal(0); - return paginationResult; + return new CategorizedSubscriptionResult(new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); } List deviceIdList = deviceSubscriptionDTOS.stream().map(DeviceSubscriptionDTO::getDeviceId) .collect(Collectors.toList()); - Map currentVersionsMap = subscriptionDAO.getCurrentInstalledAppVersion(applicationDTO.getId(),deviceIdList, installedVersion); + Map currentVersionsMap = subscriptionDAO.getCurrentInstalledAppVersion(applicationDTO.getId(), deviceIdList, installedVersion); try { - //pass the device id list to device manager service method - PaginationResult paginationResult = deviceManagementProviderService.getAppSubscribedDevices - (request, deviceIdList); - List deviceSubscriptionDataList = new ArrayList<>(); + // Pass the device id list to device manager service method + PaginationResult paginationResult = deviceManagementProviderService.getAppSubscribedDevices(request, deviceIdList); if (!paginationResult.getData().isEmpty()) { List devices = (List) paginationResult.getData(); for (Device device : devices) { - if(installedVersion != null && !installedVersion.isEmpty() && !currentVersionsMap.containsKey(device.getId())){ + if (installedVersion != null && !installedVersion.isEmpty() && !currentVersionsMap.containsKey(device.getId())) { continue; } DeviceSubscriptionData deviceSubscriptionData = new DeviceSubscriptionData(); - if(currentVersionsMap.containsKey(device.getId())){ + if (currentVersionsMap.containsKey(device.getId())) { deviceSubscriptionData.setCurrentInstalledVersion(currentVersionsMap.get(device.getId())); - }else{ + } else { deviceSubscriptionData.setCurrentInstalledVersion("-"); } for (DeviceSubscriptionDTO subscription : deviceSubscriptionDTOS) { @@ -1565,39 +1564,51 @@ public class SubscriptionManagerImpl implements SubscriptionManager { if (subscription.isUnsubscribed()) { deviceSubscriptionData.setAction(Constants.UNSUBSCRIBED); deviceSubscriptionData.setActionTriggeredBy(subscription.getUnsubscribedBy()); - deviceSubscriptionData - .setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp().getTime() / 1000); + deviceSubscriptionData.setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp().getTime() / 1000); } else { deviceSubscriptionData.setAction(Constants.SUBSCRIBED); deviceSubscriptionData.setActionTriggeredBy(subscription.getSubscribedBy()); - deviceSubscriptionData - .setActionTriggeredTimestamp(subscription.getSubscribedTimestamp().getTime() / 1000); + deviceSubscriptionData.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp().getTime() / 1000); } deviceSubscriptionData.setActionType(subscription.getActionTriggeredFrom()); deviceSubscriptionData.setStatus(subscription.getStatus()); deviceSubscriptionData.setSubId(subscription.getId()); - deviceSubscriptionDataList.add(deviceSubscriptionData); + + // Categorize the subscription data based on its status + switch (subscription.getStatus()) { + case "COMPLETED": + installedDevices.add(deviceSubscriptionData); + break; + case "ERROR": + case "INVALID": + case "UNAUTHORIZED": + errorDevices.add(deviceSubscriptionData); + break; + case "IN_PROGRESS": + case "PENDING": + case "REPEATED": + pendingDevices.add(deviceSubscriptionData); + break; + } break; } } } } - paginationResult.setData(deviceSubscriptionDataList); - return paginationResult; + return new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices); } catch (DeviceManagementException e) { - String msg = "service error occurred while getting device data from the device management service. " - + "Device ids " + deviceIdList; + String msg = "Service error occurred while getting device data from the device management service. " + + "Device ids " + deviceIdList; log.error(msg, e); throw new ApplicationManagementException(msg, e); } } catch (ApplicationManagementDAOException e) { - String msg = - "Error occurred when getting application release data for application release UUID: " + appUUID; + String msg = "Error occurred when getting application release data for application release UUID: " + appUUID; log.error(msg, e); throw new ApplicationManagementException(msg, e); } catch (DBConnectionException e) { - String msg = "DB Connection error occurred while trying to get subscription data of application which has " - + "application release UUID " + appUUID; + String msg = "DB Connection error occurred while trying to get subscription data of application which has " + + "application release UUID " + appUUID; log.error(msg, e); throw new ApplicationManagementException(msg, e); } finally { From e3da56f793ba9ae36331baa790ffad497769a1ec Mon Sep 17 00:00:00 2001 From: nipuni Date: Mon, 27 May 2024 10:27:16 +0530 Subject: [PATCH 6/6] Feature to manage subscription type base subscriptions and Installation Percentage Calculation based on groups, users and roles --- .../common/CategorizedSubscriptionResult.java | 40 ++ .../mgt/common/DeviceSubscriptionData.java | 36 +- .../mgt/common/dto/DeviceOperationDTO.java | 115 +++++ .../mgt/common/dto/GroupSubscriptionDTO.java | 18 + .../dto/GroupSubscriptionDetailDTO.java | 136 ++++++ .../mgt/common/dto/RoleSubscriptionDTO.java | 98 +++- .../common/dto/SubscriptionResponseDTO.java | 52 ++ .../mgt/common/dto/UserSubscriptionDTO.java | 102 +++- .../common/services/SubscriptionManager.java | 48 +- .../mgt/core/dao/SubscriptionDAO.java | 64 ++- .../GenericSubscriptionDAOImpl.java | 258 ++++++++++ .../core/impl/SubscriptionManagerImpl.java | 460 +++++++++++++++++- .../device/mgt/core/dao/EnrollmentDAO.java | 12 +- .../core/device/mgt/core/dao/GroupDAO.java | 12 +- .../dao/impl/AbstractEnrollmentDAOImpl.java | 35 +- .../core/dao/impl/AbstractGroupDAOImpl.java | 40 ++ .../device/mgt/core/dto/GroupDetailsDTO.java | 70 +++ .../device/mgt/core/dto/OperationDTO.java | 118 +++++ .../mgt/core/dto/OwnerWithDeviceDTO.java | 52 ++ .../core/operation/mgt/dao/OperationDAO.java | 4 + .../mgt/dao/impl/GenericOperationDAOImpl.java | 52 +- .../mgt/dao/util/OperationDAOUtil.java | 43 ++ .../DeviceManagementProviderService.java | 20 + .../DeviceManagementProviderServiceImpl.java | 55 +++ .../GroupManagementProviderService.java | 11 + .../GroupManagementProviderServiceImpl.java | 36 +- 26 files changed, 1938 insertions(+), 49 deletions(-) create mode 100644 components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/DeviceOperationDTO.java create mode 100644 components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDetailDTO.java create mode 100644 components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/SubscriptionResponseDTO.java create mode 100644 components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/GroupDetailsDTO.java create mode 100644 components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OperationDTO.java create mode 100644 components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OwnerWithDeviceDTO.java diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java index 8e59f287a3..60531ac8aa 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.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 io.entgra.device.mgt.core.application.mgt.common; import java.util.List; @@ -6,13 +24,27 @@ public class CategorizedSubscriptionResult { private List installedDevices; private List pendingDevices; private List errorDevices; + private List newDevices; + // without newDevices public CategorizedSubscriptionResult(List installedDevices, List pendingDevices, List errorDevices) { this.installedDevices = installedDevices; this.pendingDevices = pendingDevices; this.errorDevices = errorDevices; + this.newDevices = null; + } + + // with newDevices + public CategorizedSubscriptionResult(List installedDevices, + List pendingDevices, + List errorDevices, + List newDevices) { + this.installedDevices = installedDevices; + this.pendingDevices = pendingDevices; + this.errorDevices = errorDevices; + this.newDevices = newDevices; } public List getInstalledDevices() { @@ -38,4 +70,12 @@ public class CategorizedSubscriptionResult { public void setErrorDevices(List errorDevices) { this.errorDevices = errorDevices; } + + public List getNewDevices() { + return newDevices; + } + + public void setNewDevices(List newDevices) { + this.newDevices = newDevices; + } } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/DeviceSubscriptionData.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/DeviceSubscriptionData.java index 55f2ec9edc..5ea565af90 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/DeviceSubscriptionData.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/DeviceSubscriptionData.java @@ -26,12 +26,14 @@ public class DeviceSubscriptionData { private int subId; private String action; - private long actionTriggeredTimestamp; + private Timestamp actionTriggeredTimestamp; + private String actionTriggeredFrom; private String actionTriggeredBy; private String actionType; private String status; private Device device; private String currentInstalledVersion; + private int deviceId; public String getAction() { return action; @@ -41,14 +43,6 @@ public class DeviceSubscriptionData { this.action = action; } - public long getActionTriggeredTimestamp() { - return actionTriggeredTimestamp; - } - - public void setActionTriggeredTimestamp(long actionTriggeredTimestamp) { - this.actionTriggeredTimestamp = actionTriggeredTimestamp; - } - public String getActionTriggeredBy() { return actionTriggeredBy; } @@ -92,4 +86,28 @@ public class DeviceSubscriptionData { public void setSubId(int subId) { this.subId = subId; } + + public int getDeviceId() { + return deviceId; + } + + public void setDeviceId(int deviceId) { + this.deviceId = deviceId; + } + + public String getActionTriggeredFrom() { + return actionTriggeredFrom; + } + + public void setActionTriggeredFrom(String actionTriggeredFrom) { + this.actionTriggeredFrom = actionTriggeredFrom; + } + + public Timestamp getActionTriggeredTimestamp() { + return actionTriggeredTimestamp; + } + + public void setActionTriggeredTimestamp(Timestamp actionTriggeredTimestamp) { + this.actionTriggeredTimestamp = actionTriggeredTimestamp; + } } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/DeviceOperationDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/DeviceOperationDTO.java new file mode 100644 index 0000000000..bca7e8b002 --- /dev/null +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/DeviceOperationDTO.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.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 io.entgra.device.mgt.core.application.mgt.common.dto; + +import java.sql.Timestamp; + +public class DeviceOperationDTO { + private int deviceId; + private String uuid; + private String status; + private int operationId; + private String actionTriggeredFrom; + private Timestamp actionTriggeredAt; + private int appReleaseId; + private String operationCode; + private Object operationDetails; + private Object operationProperties; + + + public int getDeviceId() { + return deviceId; + } + + public void setDeviceId(int deviceId) { + this.deviceId = deviceId; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public int getOperationId() { + return operationId; + } + + public void setOperationId(int operationId) { + this.operationId = operationId; + } + + public String getActionTriggeredFrom() { + return actionTriggeredFrom; + } + + public void setActionTriggeredFrom(String actionTriggeredFrom) { + this.actionTriggeredFrom = actionTriggeredFrom; + } + + public Timestamp getActionTriggeredAt() { + return actionTriggeredAt; + } + + public void setActionTriggeredAt(Timestamp actionTriggeredAt) { + this.actionTriggeredAt = actionTriggeredAt; + } + + public int getAppReleaseId() { + return appReleaseId; + } + + public void setAppReleaseId(int appReleaseId) { + this.appReleaseId = appReleaseId; + } + + public String getOperationCode() { + return operationCode; + } + + public void setOperationCode(String operationCode) { + this.operationCode = operationCode; + } + + public Object getOperationDetails() { + return operationDetails; + } + + public void setOperationDetails(Object operationDetails) { + this.operationDetails = operationDetails; + } + + public Object getOperationProperties() { + return operationProperties; + } + + public void setOperationProperties(Object operationProperties) { + this.operationProperties = operationProperties; + } +} diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDTO.java index 3d9e6dfd2c..76a7b39d2d 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDTO.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDTO.java @@ -22,6 +22,7 @@ import java.sql.Timestamp; public class GroupSubscriptionDTO { private int id; + private String groupName; private String subscribedBy; private Timestamp subscribedTimestamp; private boolean isUnsubscribed; @@ -29,6 +30,7 @@ public class GroupSubscriptionDTO { private Timestamp unsubscribedTimestamp; private String subscribedFrom; private int groupdId; + private int appReleaseId; public int getId() { return id; } @@ -61,4 +63,20 @@ public class GroupSubscriptionDTO { public int getGroupdId() { return groupdId; } public void setGroupdId(int groupdId) { this.groupdId = groupdId; } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public int getAppReleaseId() { + return appReleaseId; + } + + public void setAppReleaseId(int appReleaseId) { + this.appReleaseId = appReleaseId; + } } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDetailDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDetailDTO.java new file mode 100644 index 0000000000..442d82faed --- /dev/null +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDetailDTO.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.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 io.entgra.device.mgt.core.application.mgt.common.dto; + +import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; + +import java.sql.Timestamp; +import java.util.Map; + +public class GroupSubscriptionDetailDTO { + private int groupId; + private String groupName; + private String groupOwner; + private String subscribedBy; + private Timestamp subscribedTimestamp; + private boolean isUnsubscribed; + private String unsubscribedBy; + private Timestamp unsubscribedTimestamp; + private int appReleaseId; + private int deviceCount; + private CategorizedSubscriptionResult devices; + private Map statusPercentages; + + // Getters and Setters + public int getGroupId() { + return groupId; + } + + public void setGroupId(int groupId) { + this.groupId = groupId; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public String getGroupOwner() { + return groupOwner; + } + + public void setGroupOwner(String groupOwner) { + this.groupOwner = groupOwner; + } + + public String getSubscribedBy() { + return subscribedBy; + } + + public void setSubscribedBy(String subscribedBy) { + this.subscribedBy = subscribedBy; + } + + public Timestamp getSubscribedTimestamp() { + return subscribedTimestamp; + } + + public void setSubscribedTimestamp(Timestamp subscribedTimestamp) { + this.subscribedTimestamp = subscribedTimestamp; + } + + public boolean isUnsubscribed() { + return isUnsubscribed; + } + + public void setUnsubscribed(boolean unsubscribed) { + isUnsubscribed = unsubscribed; + } + + public String getUnsubscribedBy() { + return unsubscribedBy; + } + + public void setUnsubscribedBy(String unsubscribedBy) { + this.unsubscribedBy = unsubscribedBy; + } + + public Timestamp getUnsubscribedTimestamp() { + return unsubscribedTimestamp; + } + + public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) { + this.unsubscribedTimestamp = unsubscribedTimestamp; + } + + public int getAppReleaseId() { + return appReleaseId; + } + + public void setAppReleaseId(int appReleaseId) { + this.appReleaseId = appReleaseId; + } + + public int getDeviceCount() { + return deviceCount; + } + + public void setDeviceCount(int deviceCount) { + this.deviceCount = deviceCount; + } + + public CategorizedSubscriptionResult getDevices() { + return devices; + } + + public void setDevices(CategorizedSubscriptionResult devices) { + this.devices = devices; + } + + public Map getStatusPercentages() { + return statusPercentages; + } + + public void setStatusPercentages(Map statusPercentages) { + this.statusPercentages = statusPercentages; + } +} diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/RoleSubscriptionDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/RoleSubscriptionDTO.java index 869ed1fd6d..b8139181de 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/RoleSubscriptionDTO.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/RoleSubscriptionDTO.java @@ -18,51 +18,115 @@ package io.entgra.device.mgt.core.application.mgt.common.dto; +import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; + import java.sql.Timestamp; +import java.util.Map; public class RoleSubscriptionDTO { - private int id; private String subscribedBy; private Timestamp subscribedTimestamp; private boolean isUnsubscribed; + private boolean unsubscribed; private String unsubscribedBy; private Timestamp unsubscribedTimestamp; private String subscribedFrom; private String roleName; + private int appReleaseId; + private int deviceCount; + private Map statusPercentages; + private CategorizedSubscriptionResult devices; - public int getId() { return id; } - - public void setId(int id) { this.id = id; } - - public String getSubscribedBy() { return subscribedBy; } + public String getSubscribedBy() { + return subscribedBy; + } - public void setSubscribedBy(String subscribedBy) { this.subscribedBy = subscribedBy; } + public void setSubscribedBy(String subscribedBy) { + this.subscribedBy = subscribedBy; + } - public Timestamp getSubscribedTimestamp() { return subscribedTimestamp; } + public Timestamp getSubscribedTimestamp() { + return subscribedTimestamp; + } public void setSubscribedTimestamp(Timestamp subscribedTimestamp) { this.subscribedTimestamp = subscribedTimestamp; } - public boolean isUnsubscribed() { return isUnsubscribed; } + public boolean getUnsubscribed() { + return unsubscribed; + } - public void setUnsubscribed(boolean unsubscribed) { isUnsubscribed = unsubscribed; } + public void setUnsubscribed(boolean unsubscribed) { + this.unsubscribed = unsubscribed; + } - public String getUnsubscribedBy() { return unsubscribedBy; } + public boolean isUnsubscribed() { + return isUnsubscribed; + } - public void setUnsubscribedBy(String unsubscribedBy) { this.unsubscribedBy = unsubscribedBy; } + public String getUnsubscribedBy() { + return unsubscribedBy; + } + + public void setUnsubscribedBy(String unsubscribedBy) { + this.unsubscribedBy = unsubscribedBy; + } - public Timestamp getUnsubscribedTimestamp() { return unsubscribedTimestamp; } + public Timestamp getUnsubscribedTimestamp() { + return unsubscribedTimestamp; + } public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) { this.unsubscribedTimestamp = unsubscribedTimestamp; } - public String getSubscribedFrom() { return subscribedFrom; } + public String getSubscribedFrom() { + return subscribedFrom; + } + + public void setSubscribedFrom(String subscribedFrom) { + this.subscribedFrom = subscribedFrom; + } + + public String getRoleName() { + return roleName; + } - public void setSubscribedFrom(String subscribedFrom) { this.subscribedFrom = subscribedFrom; } + public void setRoleName(String roleName) { + this.roleName = roleName; + } - public String getRoleName() { return roleName; } + public int getAppReleaseId() { + return appReleaseId; + } + + public void setAppReleaseId(int appReleaseId) { + this.appReleaseId = appReleaseId; + } + + public int getDeviceCount() { + return deviceCount; + } + + public void setDeviceCount(int deviceCount) { + this.deviceCount = deviceCount; + } + + public Map getStatusPercentages() { + return statusPercentages; + } + + public void setStatusPercentages(Map statusPercentages) { + this.statusPercentages = statusPercentages; + } + + public CategorizedSubscriptionResult getDevices() { + return devices; + } + + public void setDevices(CategorizedSubscriptionResult devices) { + this.devices = devices; + } - public void setRoleName(String roleName) { this.roleName = roleName; } } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/SubscriptionResponseDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/SubscriptionResponseDTO.java new file mode 100644 index 0000000000..aecee2460f --- /dev/null +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/SubscriptionResponseDTO.java @@ -0,0 +1,52 @@ +package io.entgra.device.mgt.core.application.mgt.common.dto; + +import java.util.List; + +public class SubscriptionResponseDTO { + + private String UUID; + private List GroupsSubscriptions; + private List UserSubscriptions; + private List RolesSubscriptions; + private List DevicesOperations; + + public String getUUID() { + return UUID; + } + + public void setUUID(String UUID) { + this.UUID = UUID; + } + + public List getGroupsSubscriptions() { + return GroupsSubscriptions; + } + + public void setGroupsSubscriptions(List groupsSubscriptions) { + GroupsSubscriptions = groupsSubscriptions; + } + + public List getUserSubscriptions() { + return UserSubscriptions; + } + + public void setUserSubscriptions(List userSubscriptions) { + UserSubscriptions = userSubscriptions; + } + + public List getRolesSubscriptions() { + return RolesSubscriptions; + } + + public void setRolesSubscriptions(List rolesSubscriptions) { + RolesSubscriptions = rolesSubscriptions; + } + + public List getDevicesOperations() { + return DevicesOperations; + } + + public void setDevicesOperations(List devicesOperations) { + DevicesOperations = devicesOperations; + } +} diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/UserSubscriptionDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/UserSubscriptionDTO.java index 4df7e4e64d..7238f7ebba 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/UserSubscriptionDTO.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/UserSubscriptionDTO.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.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 @@ -18,15 +18,107 @@ package io.entgra.device.mgt.core.application.mgt.common.dto; +import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; + import java.sql.Timestamp; +import java.util.Map; public class UserSubscriptionDTO { - private int id; + + private String userName; private String subscribedBy; private Timestamp subscribedTimestamp; - private boolean isUnsubscribed; + private boolean unsubscribed; private String unsubscribedBy; private Timestamp unsubscribedTimestamp; - private String subscribedFrom; - private String userName; + private int appReleaseId; + private int deviceCount; + private Map statusPercentages; + private CategorizedSubscriptionResult devices; + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getSubscribedBy() { + return subscribedBy; + } + + public void setSubscribedBy(String subscribedBy) { + this.subscribedBy = subscribedBy; + } + + public Timestamp getSubscribedTimestamp() { + return subscribedTimestamp; + } + + public void setSubscribedTimestamp(Timestamp subscribedTimestamp) { + this.subscribedTimestamp = subscribedTimestamp; + } + + public boolean isUnsubscribed() { + return unsubscribed; + } + + public boolean getUnsubscribed() { + return unsubscribed; + } + + public void setUnsubscribed(boolean unsubscribed) { + this.unsubscribed = unsubscribed; + } + + public String getUnsubscribedBy() { + return unsubscribedBy; + } + + public void setUnsubscribedBy(String unsubscribedBy) { + this.unsubscribedBy = unsubscribedBy; + } + + public Timestamp getUnsubscribedTimestamp() { + return unsubscribedTimestamp; + } + + public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) { + this.unsubscribedTimestamp = unsubscribedTimestamp; + } + + public int getAppReleaseId() { + return appReleaseId; + } + + public void setAppReleaseId(int appReleaseId) { + this.appReleaseId = appReleaseId; + } + + public int getDeviceCount() { + return deviceCount; + } + + public void setDeviceCount(int deviceCount) { + this.deviceCount = deviceCount; + } + + public Map getStatusPercentages() { + return statusPercentages; + } + + public void setStatusPercentages(Map statusPercentages) { + this.statusPercentages = statusPercentages; + } + + public CategorizedSubscriptionResult getDevices() { + return devices; + } + + public void setDevices(CategorizedSubscriptionResult devices) { + this.devices = devices; + } + } + diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java index c5b8ac8153..9fa1defa8b 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java @@ -20,10 +20,14 @@ package io.entgra.device.mgt.core.application.mgt.common.services; import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstallResponse; import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus; +import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType; +import io.entgra.device.mgt.core.application.mgt.common.dto.GroupSubscriptionDetailDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.UserSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.RoleSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceOperationDTO; import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException; import io.entgra.device.mgt.core.application.mgt.common.exception.SubscriptionManagementException; -import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType; import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier; import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.PaginationResult; @@ -31,6 +35,7 @@ import io.entgra.device.mgt.core.device.mgt.common.app.mgt.App; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity; import java.util.List; +import java.util.Map; import java.util.Properties; /** @@ -218,4 +223,45 @@ public interface SubscriptionManager { * @throws {@link SubscriptionManagementException} Exception of the subscription management */ Activity getOperationAppDetails(String id) throws SubscriptionManagementException; + + /** + * Retrieves the group details associated with a given app release UUID. + * + * @param uuid the UUID of the app release + * @return a list of maps containing group details and their associated devices + * @throws ApplicationManagementException if an error occurs while fetching the group details + */ + List getGroupsSubscriptionDetailsByUUID(String uuid, String subscriptionStatus) + throws ApplicationManagementException; + + /** + * Retrieves the user details associated with a given app release UUID. + * + * @param uuid the UUID of the app release + * @return a list of maps containing user details and their associated devices + * @throws ApplicationManagementException if an error occurs while fetching the group details + */ + List getUserSubscriptionsByUUID(String uuid, String subscriptionStatus) + throws ApplicationManagementException; + + /** + * Retrieves the Role details associated with a given app release UUID. + * + * @param uuid the UUID of the app release + * @return a list of maps containing role details and their associated devices + * @throws ApplicationManagementException if an error occurs while fetching the group details + */ + List getRoleSubscriptionsByUUID(String uuid, String subscriptionStatus) + throws ApplicationManagementException; + + /** + * This method is responsible for retrieving device subscription details related to the given UUID. + * + * @param uuid the UUID of the application release. + * @return List of device subscription details. + * @throws SubscriptionManagementException if there is an error while fetching the details. + */ + List getDeviceSubscriptionsOperationsByUUID(String uuid) + throws ApplicationManagementException; + } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/SubscriptionDAO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/SubscriptionDAO.java index 3213db3484..925bd9c231 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/SubscriptionDAO.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/SubscriptionDAO.java @@ -18,8 +18,12 @@ package io.entgra.device.mgt.core.application.mgt.core.dao; import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus; -import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.GroupSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.UserSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceOperationDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.RoleSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.exception.SubscriptionManagementException; import io.entgra.device.mgt.core.application.mgt.core.exception.ApplicationManagementDAOException; @@ -312,4 +316,62 @@ public interface SubscriptionDAO { * @throws ApplicationManagementDAOException thrown if an error occurs while deleting data */ void deleteScheduledSubscriptionByTenant(int tenantId) throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of groups related to a UUID. + * + * @param uuid the UUID of the application release. + * @param unsubscribe the Status of the subscription. + * @param tenantId id of the current tenant. + * @return groupDetails - list of group details related to the UUID. + * @throws ApplicationManagementDAOException if connection establishment fails. + */ + List getGroupsSubscriptionDetailsByUUID(String uuid, boolean unsubscribe, int tenantId) + throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of user subscriptions related to a UUID. + * + * @param uuid the UUID of the application release. + * @param unsubscribe the Status of the subscription. + * @param tenantId id of the current tenant. + * @return userSubscriptions - list of user subscription details related to the UUID. + * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. + */ + List getUserSubscriptionsByUUID(String uuid, boolean unsubscribe, int tenantId) + throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of role subscriptions related to a UUID. + * + * @param uuid the UUID of the application release. + * @param unsubscribe the Status of the subscription. + * @param tenantId id of the current tenant. + * @return roleSubscriptions - list of role subscription details related to the UUID. + * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. + */ + List getRoleSubscriptionsByUUID(String uuid, boolean unsubscribe, int tenantId) + throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of device subscriptions related to a UUID. + * + * @param uuid the UUID of the application release. + * @param tenantId id of the current tenant. + * @return deviceSubscriptions - list of device subscription details related to the UUID. + * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. + */ + List getDeviceSubscriptionsOperationsByUUID(String uuid, int tenantId) + throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of device subscriptions related to a UUID. + * + * @param appReleaseId the appReleaseId of the application release. + * @param tenantId id of the current tenant. + * @return deviceSubscriptions - list of device subscription details related to the UUID. + * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. + */ + List getDeviceSubscriptionsDetails(int appReleaseId, int tenantId) + throws ApplicationManagementDAOException; } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java index 79e7b76660..2dca5ac0a0 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java @@ -17,6 +17,10 @@ */ package io.entgra.device.mgt.core.application.mgt.core.dao.impl.subscription; +import io.entgra.device.mgt.core.application.mgt.common.dto.GroupSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceOperationDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.RoleSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.UserSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.core.dao.SubscriptionDAO; import io.entgra.device.mgt.core.application.mgt.core.dao.impl.AbstractDAOImpl; import io.entgra.device.mgt.core.application.mgt.core.exception.UnexpectedServerErrorException; @@ -1635,4 +1639,258 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc throw new ApplicationManagementDAOException(msg, e); } } + + @Override + public List getGroupsSubscriptionDetailsByUUID(String uuid, boolean unsubscribe, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get groups related to the given UUID."); + } + try { + Connection conn = this.getDBConnection(); + List groupDetails = new ArrayList<>(); + String sql = "SELECT GS.GROUP_NAME, GS.SUBSCRIBED_BY, GS.SUBSCRIBED_TIMESTAMP, GS.UNSUBSCRIBED, " + + "GS.UNSUBSCRIBED_BY, GS.UNSUBSCRIBED_TIMESTAMP, GS.AP_APP_RELEASE_ID " + + "FROM AP_GROUP_SUBSCRIPTION GS " + + "JOIN AP_APP_RELEASE AR ON GS.AP_APP_RELEASE_ID = AR.ID " + + "WHERE AR.UUID = ? AND GS.UNSUBSCRIBED = ? AND AR.TENANT_ID = ?"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, uuid); + ps.setBoolean(2, unsubscribe); + ps.setInt(3, tenantId); + try (ResultSet rs = ps.executeQuery()) { + GroupSubscriptionDTO groupDetail; + while (rs.next()) { + groupDetail = new GroupSubscriptionDTO(); + groupDetail.setGroupName(rs.getString("GROUP_NAME")); + groupDetail.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); + groupDetail.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_TIMESTAMP")); + groupDetail.setUnsubscribed(rs.getBoolean("UNSUBSCRIBED")); + groupDetail.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY")); + groupDetail.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_TIMESTAMP")); + groupDetail.setAppReleaseId(rs.getInt("AP_APP_RELEASE_ID")); + + groupDetails.add(groupDetail); + } + } + return groupDetails; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get groups for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting groups for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getUserSubscriptionsByUUID(String uuid, boolean unsubscribe, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get user subscriptions related to the given UUID."); + } + try { + Connection conn = this.getDBConnection(); + List userSubscriptions = new ArrayList<>(); + String sql = "SELECT US.USER_NAME, US.SUBSCRIBED_BY, US.SUBSCRIBED_TIMESTAMP, US.UNSUBSCRIBED, " + + "US.UNSUBSCRIBED_BY, US.UNSUBSCRIBED_TIMESTAMP, US.AP_APP_RELEASE_ID, AR.UUID " + + "FROM AP_USER_SUBSCRIPTION US " + + "JOIN AP_APP_RELEASE AR ON US.AP_APP_RELEASE_ID = AR.ID " + + "WHERE AR.UUID = ? AND US.UNSUBSCRIBED = ? AND AR.TENANT_ID = ?"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, uuid); + ps.setBoolean(2, unsubscribe); + ps.setInt(3, tenantId); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + UserSubscriptionDTO userSubscription; + userSubscription = new UserSubscriptionDTO(); + userSubscription.setUserName(rs.getString("USER_NAME")); + userSubscription.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); + userSubscription.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_TIMESTAMP")); + userSubscription.setUnsubscribed(rs.getBoolean("UNSUBSCRIBED")); + userSubscription.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY")); + userSubscription.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_TIMESTAMP")); + userSubscription.setAppReleaseId(rs.getInt("AP_APP_RELEASE_ID")); + + userSubscriptions.add(userSubscription); + } + } + return userSubscriptions; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get user subscriptions for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting user subscriptions for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getRoleSubscriptionsByUUID(String uuid, boolean unsubscribe, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get role subscriptions related to the given UUID."); + } + try { + Connection conn = this.getDBConnection(); + List roleSubscriptions = new ArrayList<>(); + String sql = "SELECT ARS.ROLE_NAME, ARS.SUBSCRIBED_BY, ARS.SUBSCRIBED_TIMESTAMP, ARS.UNSUBSCRIBED, " + + "ARS.UNSUBSCRIBED_BY, ARS.UNSUBSCRIBED_TIMESTAMP, ARS.AP_APP_RELEASE_ID " + + "FROM AP_ROLE_SUBSCRIPTION ARS " + + "JOIN AP_APP_RELEASE AAR ON ARS.AP_APP_RELEASE_ID = AAR.ID " + + "WHERE AAR.UUID = ? AND ARS.UNSUBSCRIBED = ? AND AAR.TENANT_ID = ?"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, uuid); + ps.setBoolean(2, unsubscribe); + ps.setInt(3, tenantId); + try (ResultSet rs = ps.executeQuery()) { + RoleSubscriptionDTO roleSubscription; + while (rs.next()) { + roleSubscription = new RoleSubscriptionDTO(); + roleSubscription.setRoleName(rs.getString("ROLE_NAME")); + roleSubscription.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); + roleSubscription.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_TIMESTAMP")); + roleSubscription.setUnsubscribed(rs.getBoolean("UNSUBSCRIBED")); + roleSubscription.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY")); + roleSubscription.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_TIMESTAMP")); + roleSubscription.setAppReleaseId(rs.getInt("AP_APP_RELEASE_ID")); + + roleSubscriptions.add(roleSubscription); + } + } + return roleSubscriptions; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get role subscriptions for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting role subscriptions for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getDeviceSubscriptionsOperationsByUUID(String uuid, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get device subscriptions related to the given UUID."); + } + try { + Connection conn = this.getDBConnection(); + List deviceSubscriptions = new ArrayList<>(); + String sql = "SELECT " + + " aar.UUID, " + + " ads.DM_DEVICE_ID, " + + " aasom.OPERATION_ID, " + + " ads.STATUS, " + + " ads.ACTION_TRIGGERED_FROM, " + + " ads.SUBSCRIBED_TIMESTAMP AS ACTION_TRIGGERED_AT, " + + " ads.AP_APP_RELEASE_ID " + + "FROM AP_APP_SUB_OP_MAPPING aasom " + + "JOIN AP_DEVICE_SUBSCRIPTION ads ON aasom.AP_DEVICE_SUBSCRIPTION_ID = ads.ID " + + "JOIN AP_APP_RELEASE aar ON ads.AP_APP_RELEASE_ID = aar.ID " + + "WHERE aar.UUID = ? AND aar.TENANT_ID = ?"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, uuid); + ps.setInt(2, tenantId); + try (ResultSet rs = ps.executeQuery()) { + DeviceOperationDTO deviceSubscription; + while (rs.next()) { + deviceSubscription = new DeviceOperationDTO(); + deviceSubscription.setDeviceId(rs.getInt("DM_DEVICE_ID")); + deviceSubscription.setUuid(rs.getString("UUID")); + deviceSubscription.setStatus(rs.getString("STATUS")); + deviceSubscription.setOperationId(rs.getInt("OPERATION_ID")); + deviceSubscription.setActionTriggeredFrom(rs.getString("ACTION_TRIGGERED_FROM")); + deviceSubscription.setActionTriggeredAt(rs.getTimestamp("ACTION_TRIGGERED_AT")); + deviceSubscription.setAppReleaseId(rs.getInt("AP_APP_RELEASE_ID")); + + deviceSubscriptions.add(deviceSubscription); + } + } + } + return deviceSubscriptions; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get device subscriptions for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting device subscriptions for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getDeviceSubscriptionsDetails(int appReleaseId, int tenantId) throws + ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting device subscriptions for the application release id " + appReleaseId + + " from the database"); + } + String sql = "SELECT " + + "DS.ID AS ID, " + + "DS.SUBSCRIBED_BY AS SUBSCRIBED_BY, " + + "DS.SUBSCRIBED_TIMESTAMP AS SUBSCRIBED_AT, " + + "DS.UNSUBSCRIBED AS IS_UNSUBSCRIBED, " + + "DS.UNSUBSCRIBED_BY AS UNSUBSCRIBED_BY, " + + "DS.UNSUBSCRIBED_TIMESTAMP AS UNSUBSCRIBED_AT, " + + "DS.ACTION_TRIGGERED_FROM AS ACTION_TRIGGERED_FROM, " + + "DS.STATUS AS STATUS," + + "DS.DM_DEVICE_ID AS DEVICE_ID " + + "FROM AP_DEVICE_SUBSCRIPTION DS " + + "WHERE DS.AP_APP_RELEASE_ID = ? AND DS.TENANT_ID=?"; + + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + try (ResultSet rs = ps.executeQuery()) { + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved device subscriptions for application release id " + + appReleaseId); + } + List deviceSubscriptions = new ArrayList<>(); + + DeviceSubscriptionDTO subscription; + while (rs.next()) { + subscription = new DeviceSubscriptionDTO(); + subscription.setId(rs.getInt("ID")); + subscription.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); + subscription.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_AT")); + subscription.setUnsubscribed(rs.getBoolean("IS_UNSUBSCRIBED")); + subscription.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY")); + subscription.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_AT")); + subscription.setActionTriggeredFrom(rs.getString("ACTION_TRIGGERED_FROM")); + subscription.setStatus(rs.getString("STATUS")); + subscription.setDeviceId(rs.getInt("DEVICE_ID")); + + deviceSubscriptions.add(subscription); + } + return deviceSubscriptions; + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection for getting device subscription for " + + "application Id: " + appReleaseId + "."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while while running SQL to get device subscription data for application ID: " + appReleaseId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java index ddfd1cfe46..35f74f9c43 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java @@ -24,11 +24,21 @@ import io.entgra.device.mgt.core.application.mgt.common.ApplicationSubscriptionI import io.entgra.device.mgt.core.application.mgt.common.ApplicationType; import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscriptionData; +import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.GroupSubscriptionDetailDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.UserSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.RoleSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceOperationDTO; import io.entgra.device.mgt.core.application.mgt.common.DeviceTypes; import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus; import io.entgra.device.mgt.core.application.mgt.common.SubAction; import io.entgra.device.mgt.core.application.mgt.common.SubscribingDeviceIdHolder; import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType; +import io.entgra.device.mgt.core.application.mgt.common.dto.GroupSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationPolicyDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.VppAssetDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.VppUserDTO; import io.entgra.device.mgt.core.application.mgt.common.services.VPPApplicationManager; @@ -36,8 +46,12 @@ import io.entgra.device.mgt.core.application.mgt.core.dao.VppApplicationDAO; import io.entgra.device.mgt.core.application.mgt.core.exception.BadRequestException; import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.PaginationResult; +import io.entgra.device.mgt.core.device.mgt.core.dto.GroupDetailsDTO; import io.entgra.device.mgt.core.device.mgt.core.DeviceManagementConstants; import io.entgra.device.mgt.core.application.mgt.core.exception.UnexpectedServerErrorException; +import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOException; +import io.entgra.device.mgt.core.device.mgt.core.dto.OperationDTO; +import io.entgra.device.mgt.core.device.mgt.core.dto.OwnerWithDeviceDTO; import io.entgra.device.mgt.core.device.mgt.extensions.logger.spi.EntgraLogger; import io.entgra.device.mgt.core.notification.logger.AppInstallLogContext; import io.entgra.device.mgt.core.notification.logger.impl.EntgraAppInstallLoggerImpl; @@ -56,11 +70,6 @@ import org.json.JSONObject; import io.entgra.device.mgt.core.apimgt.application.extension.dto.ApiApplicationKey; import io.entgra.device.mgt.core.apimgt.application.extension.exception.APIManagerException; import org.wso2.carbon.context.PrivilegedCarbonContext; -import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationPolicyDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException; import io.entgra.device.mgt.core.application.mgt.common.exception.DBConnectionException; import io.entgra.device.mgt.core.application.mgt.common.exception.LifecycleManagementException; @@ -101,6 +110,7 @@ import io.entgra.device.mgt.core.device.mgt.core.util.MDMIOSOperationUtil; import io.entgra.device.mgt.core.device.mgt.core.util.MDMWindowsOperationUtil; import io.entgra.device.mgt.core.identity.jwt.client.extension.dto.AccessTokenInfo; import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; import javax.ws.rs.core.MediaType; import java.io.BufferedReader; @@ -1564,11 +1574,11 @@ public class SubscriptionManagerImpl implements SubscriptionManager { if (subscription.isUnsubscribed()) { deviceSubscriptionData.setAction(Constants.UNSUBSCRIBED); deviceSubscriptionData.setActionTriggeredBy(subscription.getUnsubscribedBy()); - deviceSubscriptionData.setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp().getTime() / 1000); + deviceSubscriptionData.setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp()); } else { deviceSubscriptionData.setAction(Constants.SUBSCRIBED); deviceSubscriptionData.setActionTriggeredBy(subscription.getSubscribedBy()); - deviceSubscriptionData.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp().getTime() / 1000); + deviceSubscriptionData.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); } deviceSubscriptionData.setActionType(subscription.getActionTriggeredFrom()); deviceSubscriptionData.setStatus(subscription.getStatus()); @@ -1686,4 +1696,440 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } } + @Override + public List getGroupsSubscriptionDetailsByUUID(String uuid, String subscriptionStatus) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); + String groupName; + String status; + + try { + ConnectionManagerUtil.openDBConnection(); + List groupDetailsWithDevices = new ArrayList<>(); + + List groupDetails = subscriptionDAO.getGroupsSubscriptionDetailsByUUID(uuid, unsubscribe, tenantId); + if (groupDetails == null) { + throw new ApplicationManagementException("Group details not found for UUID: " + uuid); + } + + GroupManagementProviderService groupManagementProviderService = HelperUtil.getGroupManagementProviderService(); + + for (GroupSubscriptionDTO groupDetail : groupDetails) { + groupName = groupDetail.getGroupName(); + + // Retrieve group details and device IDs for the group using the service layer + GroupDetailsDTO groupDetailWithDevices = groupManagementProviderService.getGroupDetailsWithDeviceIds(groupName); + + GroupSubscriptionDetailDTO groupDetailDTO = new GroupSubscriptionDetailDTO(); + groupDetailDTO.setGroupId(groupDetailWithDevices.getGroupId()); + groupDetailDTO.setGroupName(groupDetail.getGroupName()); + groupDetailDTO.setGroupOwner(groupDetailWithDevices.getGroupOwner()); + groupDetailDTO.setSubscribedBy(groupDetail.getSubscribedBy()); + groupDetailDTO.setSubscribedTimestamp(groupDetail.getSubscribedTimestamp()); + groupDetailDTO.setUnsubscribed(groupDetail.isUnsubscribed()); + groupDetailDTO.setUnsubscribedBy(groupDetail.getUnsubscribedBy()); + groupDetailDTO.setUnsubscribedTimestamp(groupDetail.getUnsubscribedTimestamp()); + groupDetailDTO.setAppReleaseId(groupDetail.getAppReleaseId()); + groupDetailDTO.setDeviceCount(groupDetailWithDevices.getDeviceCount()); + + // Fetch device subscriptions for each device ID in the group + List pendingDevices = new ArrayList<>(); + List installedDevices = new ArrayList<>(); + List errorDevices = new ArrayList<>(); + List newDevices = new ArrayList<>(); + + List deviceIds = groupDetailWithDevices.getDeviceIds(); + Map statusCounts = new HashMap<>(); + statusCounts.put("PENDING", 0); + statusCounts.put("COMPLETED", 0); + statusCounts.put("ERROR", 0); + statusCounts.put("NEW", 0); + + for (Integer deviceId : deviceIds) { + List deviceSubscriptions = subscriptionDAO.getDeviceSubscriptionsDetails( + groupDetail.getAppReleaseId(), tenantId); + boolean isNewDevice = true; + for (DeviceSubscriptionDTO subscription : deviceSubscriptions) { + if (subscription.getDeviceId() == deviceId) { + DeviceSubscriptionData deviceDetail = new DeviceSubscriptionData(); + deviceDetail.setDeviceId(subscription.getDeviceId()); + deviceDetail.setStatus(subscription.getStatus()); + deviceDetail.setActionType(subscription.getActionTriggeredFrom()); + deviceDetail.setSubId(subscription.getId()); + deviceDetail.setActionTriggeredBy(subscription.getSubscribedBy()); + deviceDetail.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); + + status = subscription.getStatus(); + switch (status) { + case "COMPLETED": + installedDevices.add(deviceDetail); + statusCounts.put("COMPLETED", statusCounts.get("COMPLETED") + 1); + break; + case "ERROR": + case "INVALID": + case "UNAUTHORIZED": + errorDevices.add(deviceDetail); + statusCounts.put("ERROR", statusCounts.get("ERROR") + 1); + break; + case "IN_PROGRESS": + case "PENDING": + case "REPEATED": + pendingDevices.add(deviceDetail); + statusCounts.put("PENDING", statusCounts.get("PENDING") + 1); + break; + } + isNewDevice = false; + } + } + if (isNewDevice) { + DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); + newDeviceDetail.setDeviceId(deviceId); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } + } + + int totalDevices = deviceIds.size(); + Map statusPercentages = new HashMap<>(); + for (Map.Entry entry : statusCounts.entrySet()) { + double percentage = ((double) entry.getValue() / totalDevices) * 100; + statusPercentages.put(entry.getKey(), percentage); + } + + CategorizedSubscriptionResult categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + groupDetailDTO.setDevices(categorizedSubscriptionResult); + groupDetailDTO.setStatusPercentages(statusPercentages); + + groupDetailsWithDevices.add(groupDetailDTO); + } + + return groupDetailsWithDevices; + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while fetching groups and devices for UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "DB Connection error occurred while fetching groups and devices for UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (GroupManagementException e) { + String msg = "Error occurred while fetching group details and device IDs: " + e.getMessage(); + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public List getUserSubscriptionsByUUID(String uuid, String subscriptionStatus) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); + String userName; + String status; + + try { + ConnectionManagerUtil.openDBConnection(); + List userSubscriptionsWithDevices = new ArrayList<>(); + + List userSubscriptions = subscriptionDAO.getUserSubscriptionsByUUID(uuid, unsubscribe, tenantId); + if (userSubscriptions == null) { + throw new ApplicationManagementException("User details not found for UUID: " + uuid); + } + + DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); + + for (UserSubscriptionDTO userSubscription : userSubscriptions) { + userName = userSubscription.getUserName(); + + // Retrieve owner details and device IDs for the user using the service layer + OwnerWithDeviceDTO ownerDetailsWithDevices = deviceManagementProviderService.getOwnersWithDeviceIds(userName); + + UserSubscriptionDTO userSubscriptionDTO = new UserSubscriptionDTO(); + userSubscriptionDTO.setUserName(userSubscription.getUserName()); + userSubscriptionDTO.setSubscribedBy(userSubscription.getSubscribedBy()); + userSubscriptionDTO.setSubscribedTimestamp(userSubscription.getSubscribedTimestamp()); + userSubscriptionDTO.setUnsubscribed(userSubscription.getUnsubscribed()); + userSubscriptionDTO.setUnsubscribedBy(userSubscription.getUnsubscribedBy()); + userSubscriptionDTO.setUnsubscribedTimestamp(userSubscription.getUnsubscribedTimestamp()); + userSubscriptionDTO.setAppReleaseId(userSubscription.getAppReleaseId()); + + userSubscriptionDTO.setDeviceCount(ownerDetailsWithDevices.getDeviceCount()); + + // Fetch device subscriptions for each device ID associated with the user + List pendingDevices = new ArrayList<>(); + List installedDevices = new ArrayList<>(); + List errorDevices = new ArrayList<>(); + List newDevices = new ArrayList<>(); + + List deviceIds = ownerDetailsWithDevices.getDeviceIds(); + Map statusCounts = new HashMap<>(); + statusCounts.put("PENDING", 0); + statusCounts.put("COMPLETED", 0); + statusCounts.put("ERROR", 0); + statusCounts.put("NEW", 0); + + for (Integer deviceId : deviceIds) { + List deviceSubscriptions = subscriptionDAO.getDeviceSubscriptionsDetails( + userSubscription.getAppReleaseId(), tenantId); + boolean isNewDevice = true; + for (DeviceSubscriptionDTO subscription : deviceSubscriptions) { + if (subscription.getDeviceId() == deviceId) { + DeviceSubscriptionData deviceDetail = new DeviceSubscriptionData(); + deviceDetail.setDeviceId(subscription.getDeviceId()); + deviceDetail.setActionType(subscription.getActionTriggeredFrom()); + deviceDetail.setStatus(subscription.getStatus()); + deviceDetail.setActionType(subscription.getActionTriggeredFrom()); + deviceDetail.setActionTriggeredBy(subscription.getSubscribedBy()); + deviceDetail.setSubId(subscription.getId()); + deviceDetail.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); + + status = subscription.getStatus(); + switch (status) { + case "COMPLETED": + installedDevices.add(deviceDetail); + statusCounts.put("COMPLETED", statusCounts.get("COMPLETED") + 1); + break; + case "ERROR": + case "INVALID": + case "UNAUTHORIZED": + errorDevices.add(deviceDetail); + statusCounts.put("ERROR", statusCounts.get("ERROR") + 1); + break; + case "IN_PROGRESS": + case "PENDING": + case "REPEATED": + pendingDevices.add(deviceDetail); + statusCounts.put("PENDING", statusCounts.get("PENDING") + 1); + break; + } + isNewDevice = false; + } + } + if (isNewDevice) { + DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); + newDeviceDetail.setDeviceId(deviceId); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } + } + + int totalDevices = deviceIds.size(); + Map statusPercentages = new HashMap<>(); + for (Map.Entry entry : statusCounts.entrySet()) { + double percentage = ((double) entry.getValue() / totalDevices) * 100; + statusPercentages.put(entry.getKey(), percentage); + } + + CategorizedSubscriptionResult categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + userSubscriptionDTO.setDevices(categorizedSubscriptionResult); + userSubscriptionDTO.setStatusPercentages(statusPercentages); + + userSubscriptionsWithDevices.add(userSubscriptionDTO); + } + + return userSubscriptionsWithDevices; + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while getting user subscriptions for the application release UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "DB Connection error occurred while getting user subscriptions for UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DeviceManagementDAOException e) { + throw new RuntimeException(e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public List getRoleSubscriptionsByUUID(String uuid, String subscriptionStatus) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); + String roleName; + String status; + + try { + ConnectionManagerUtil.openDBConnection(); + List roleSubscriptionsWithDevices = new ArrayList<>(); + + List roleSubscriptions = subscriptionDAO.getRoleSubscriptionsByUUID(uuid, unsubscribe, tenantId); + if (roleSubscriptions == null) { + throw new ApplicationManagementException("Role details not found for UUID: " + uuid); + } + + DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); + + for (RoleSubscriptionDTO roleSubscription : roleSubscriptions) { + roleName = roleSubscription.getRoleName(); + + RoleSubscriptionDTO roleSubscriptionDTO = new RoleSubscriptionDTO(); + roleSubscriptionDTO.setRoleName(roleSubscription.getRoleName()); + roleSubscriptionDTO.setSubscribedBy(roleSubscription.getSubscribedBy()); + roleSubscriptionDTO.setSubscribedTimestamp(roleSubscription.getSubscribedTimestamp()); + roleSubscriptionDTO.setUnsubscribed(roleSubscription.getUnsubscribed()); + roleSubscriptionDTO.setUnsubscribedBy(roleSubscription.getUnsubscribedBy()); + roleSubscriptionDTO.setUnsubscribedTimestamp(roleSubscription.getUnsubscribedTimestamp()); + roleSubscriptionDTO.setAppReleaseId(roleSubscription.getAppReleaseId()); + + List pendingDevices = new ArrayList<>(); + List installedDevices = new ArrayList<>(); + List errorDevices = new ArrayList<>(); + List newDevices = new ArrayList<>(); + + Map statusCounts = new HashMap<>(); + statusCounts.put("PENDING", 0); + statusCounts.put("COMPLETED", 0); + statusCounts.put("ERROR", 0); + statusCounts.put("NEW", 0); + + List users = this.getUsersForRole(roleName); + + for (String user : users) { + OwnerWithDeviceDTO ownerDetailsWithDevices; + try { + ownerDetailsWithDevices = deviceManagementProviderService.getOwnersWithDeviceIds(user); + } catch (DeviceManagementDAOException e) { + throw new ApplicationManagementException("Error retrieving owner details with devices for user: " + user, e); + } + + List deviceIds = ownerDetailsWithDevices.getDeviceIds(); + for (Integer deviceId : deviceIds) { + List deviceSubscriptions; + try { + deviceSubscriptions = subscriptionDAO.getDeviceSubscriptionsDetails( + roleSubscription.getAppReleaseId(), tenantId); + } catch (ApplicationManagementDAOException e) { + throw new ApplicationManagementException("Error retrieving device subscriptions", e); + } + + boolean isNewDevice = true; + for (DeviceSubscriptionDTO deviceSubscription : deviceSubscriptions) { + if (deviceSubscription.getDeviceId() == deviceId) { + DeviceSubscriptionData deviceDetail = new DeviceSubscriptionData(); + deviceDetail.setDeviceId(deviceSubscription.getDeviceId()); + deviceDetail.setActionType(deviceSubscription.getActionTriggeredFrom()); + deviceDetail.setStatus(deviceSubscription.getStatus()); + deviceDetail.setActionType(deviceSubscription.getActionTriggeredFrom()); + deviceDetail.setActionTriggeredBy(deviceSubscription.getSubscribedBy()); + deviceDetail.setSubId(deviceSubscription.getId()); + deviceDetail.setActionTriggeredTimestamp(deviceSubscription.getSubscribedTimestamp()); + + status = deviceSubscription.getStatus(); + switch (status) { + case "COMPLETED": + installedDevices.add(deviceDetail); + statusCounts.put("COMPLETED", statusCounts.get("COMPLETED") + 1); + break; + case "ERROR": + case "INVALID": + case "UNAUTHORIZED": + errorDevices.add(deviceDetail); + statusCounts.put("ERROR", statusCounts.get("ERROR") + 1); + break; + case "IN_PROGRESS": + case "PENDING": + case "REPEATED": + pendingDevices.add(deviceDetail); + statusCounts.put("PENDING", statusCounts.get("PENDING") + 1); + break; + } + isNewDevice = false; + } + } + if (isNewDevice) { + DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); + newDeviceDetail.setDeviceId(deviceId); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } + } + } + + int totalDevices = pendingDevices.size() + installedDevices.size() + errorDevices.size() + newDevices.size(); + Map statusPercentages = new HashMap<>(); + for (Map.Entry entry : statusCounts.entrySet()) { + double percentage = totalDevices == 0 ? 0.0 : ((double) entry.getValue() / totalDevices) * 100; + statusPercentages.put(entry.getKey(), percentage); + } + + CategorizedSubscriptionResult categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + roleSubscriptionDTO.setDevices(categorizedSubscriptionResult); + roleSubscriptionDTO.setStatusPercentages(statusPercentages); + roleSubscriptionDTO.setDeviceCount(totalDevices); + + roleSubscriptionsWithDevices.add(roleSubscriptionDTO); + } + + return roleSubscriptionsWithDevices; + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred in retrieving role subscriptions with devices"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while retrieving the database connection"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (UserStoreException e) { + String msg = "Error occurred while retrieving users for role"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + // Get user list for each role + public List getUsersForRole(String roleName) throws UserStoreException { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + int tenantId = ctx.getTenantId(); + UserStoreManager userStoreManager = DataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId).getUserStoreManager(); + String[] users = userStoreManager.getUserListOfRole(roleName); + return Arrays.asList(users); + } + + @Override + public List getDeviceSubscriptionsOperationsByUUID(String uuid) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + if (uuid == null || uuid.isEmpty()) { + throw new IllegalArgumentException("UUID cannot be null or empty."); + } + try { + ConnectionManagerUtil.openDBConnection(); + DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); + List deviceSubscriptions = subscriptionDAO.getDeviceSubscriptionsOperationsByUUID(uuid, tenantId); + for (DeviceOperationDTO deviceSubscription : deviceSubscriptions) { + Integer operationId = deviceSubscription.getOperationId(); + if (operationId != null) { + OperationDTO operationDetails = deviceManagementProviderService.getOperationDetailsById(operationId); + if (operationDetails != null) { + deviceSubscription.setOperationCode(operationDetails.getOperationCode()); + deviceSubscription.setOperationDetails(operationDetails.getOperationDetails()); + deviceSubscription.setOperationProperties(operationDetails.getOperationProperties()); + } + } + } + return deviceSubscriptions; + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while retrieving device subscriptions for UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while retrieving the database connection"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (OperationManagementException e) { + throw new RuntimeException(e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } } 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/EnrollmentDAO.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/EnrollmentDAO.java index e42d5c1524..5b2b35a29e 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/EnrollmentDAO.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/EnrollmentDAO.java @@ -21,9 +21,11 @@ import io.entgra.device.mgt.core.device.mgt.common.Device; import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier; import io.entgra.device.mgt.core.device.mgt.common.EnrolmentInfo; import io.entgra.device.mgt.core.device.mgt.common.EnrolmentInfo.Status; +import io.entgra.device.mgt.core.device.mgt.core.dto.OwnerWithDeviceDTO; import java.sql.Timestamp; import java.util.List; +import java.util.Map; public interface EnrollmentDAO { @@ -94,5 +96,13 @@ public interface EnrollmentDAO { */ boolean addDeviceStatus(int enrolmentId, EnrolmentInfo.Status status) throws DeviceManagementDAOException; - + /** + * Retrieves owners and the list of device IDs related to an owner. + * + * @param owner the owner whose device IDs need to be retrieved + * @param tenantId the ID of the tenant + * @return a map containing owner details, device IDs, and device count + * @throws DeviceManagementDAOException if an error occurs while fetching the data + */ + OwnerWithDeviceDTO getOwnersWithDeviceIds(String owner, int tenantId) throws DeviceManagementDAOException; } 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/GroupDAO.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/GroupDAO.java index b3c4321df3..34dc3213df 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/GroupDAO.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/GroupDAO.java @@ -21,9 +21,9 @@ package io.entgra.device.mgt.core.device.mgt.core.dao; import io.entgra.device.mgt.core.device.mgt.common.Device; import io.entgra.device.mgt.core.device.mgt.common.GroupPaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; -import io.entgra.device.mgt.core.device.mgt.common.exceptions.ReportManagementException; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper; +import io.entgra.device.mgt.core.device.mgt.core.dto.GroupDetailsDTO; import java.util.List; import java.util.Map; @@ -469,4 +469,14 @@ public interface GroupDAO { List groupNames) throws GroupManagementDAOException; + /** + * Get group details and list of device IDs related to the group. + * + * @param groupName Group name + * @param tenantId Tenant ID + * @return A map containing group details and a list of device IDs + * @throws GroupManagementDAOException if an error occurs while retrieving the group details and devices + */ + GroupDetailsDTO getGroupDetailsWithDeviceIds(String groupName, int tenantId) throws GroupManagementDAOException; + } \ No newline at end of file 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/AbstractEnrollmentDAOImpl.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/AbstractEnrollmentDAOImpl.java index 8bde335227..4bc6627b3f 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/AbstractEnrollmentDAOImpl.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/AbstractEnrollmentDAOImpl.java @@ -26,6 +26,7 @@ import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOExceptio import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.core.dao.EnrollmentDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.util.DeviceManagementDAOUtil; +import io.entgra.device.mgt.core.device.mgt.core.dto.OwnerWithDeviceDTO; import java.sql.Connection; import java.sql.PreparedStatement; @@ -33,9 +34,9 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; -import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.ArrayList; public abstract class AbstractEnrollmentDAOImpl implements EnrollmentDAO { @@ -557,4 +558,36 @@ public abstract class AbstractEnrollmentDAOImpl implements EnrollmentDAO { return enrolmentInfo; } + @Override + public OwnerWithDeviceDTO getOwnersWithDeviceIds(String owner, int tenantId) throws DeviceManagementDAOException { + + OwnerWithDeviceDTO ownerDetails = new OwnerWithDeviceDTO(); + List deviceIds = new ArrayList<>(); + int deviceCount = 0; + + String sql = "SELECT DEVICE_ID, OWNER FROM DM_ENROLMENT WHERE OWNER = ? AND TENANT_ID = ?"; + + try (Connection conn = this.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, owner); + stmt.setInt(2, tenantId); + + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + if (ownerDetails.getUserName() == null) { + ownerDetails.setUserName(rs.getString("OWNER")); + } + deviceIds.add(rs.getInt("DEVICE_ID")); + deviceCount++; + } + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving owners and device IDs for owner: " + owner, e); + } + + ownerDetails.setDeviceIds(deviceIds); + ownerDetails.setDeviceCount(deviceCount); + return ownerDetails; + } + } 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/AbstractGroupDAOImpl.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/AbstractGroupDAOImpl.java index c65692870d..476b447f1a 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/AbstractGroupDAOImpl.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/AbstractGroupDAOImpl.java @@ -26,6 +26,7 @@ import io.entgra.device.mgt.core.device.mgt.common.Device; import io.entgra.device.mgt.core.device.mgt.common.GroupPaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup; +import io.entgra.device.mgt.core.device.mgt.core.dto.GroupDetailsDTO; import io.entgra.device.mgt.core.device.mgt.core.dao.GroupDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.GroupManagementDAOException; import io.entgra.device.mgt.core.device.mgt.core.dao.GroupManagementDAOFactory; @@ -1437,4 +1438,43 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { } return groupUnassignedDeviceList; } + + @Override + public GroupDetailsDTO getGroupDetailsWithDeviceIds(String groupName, int tenantId) throws GroupManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get group details and device IDs for group: " + groupName); + } + + GroupDetailsDTO groupDetails = new GroupDetailsDTO(); + List deviceIds = new ArrayList<>(); + + String sql = "SELECT g.ID AS GROUP_ID, g.GROUP_NAME, g.OWNER, dgm.DEVICE_ID " + + "FROM DM_GROUP g " + + "JOIN DM_DEVICE_GROUP_MAP dgm ON g.ID = dgm.GROUP_ID " + + "WHERE g.GROUP_NAME = ? AND g.TENANT_ID = ?"; + + try (Connection conn = GroupManagementDAOFactory.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, groupName); + stmt.setInt(2, tenantId); + + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + if (groupDetails.getGroupId() == 0) { + groupDetails.setGroupId(rs.getInt("GROUP_ID")); + groupDetails.setGroupName(rs.getString("GROUP_NAME")); + groupDetails.setGroupOwner(rs.getString("OWNER")); + } + deviceIds.add(rs.getInt("DEVICE_ID")); + } + } + } catch (SQLException e) { + throw new GroupManagementDAOException("Error occurred while retrieving group details and device IDs for group: " + + groupName, e); + } + + groupDetails.setDeviceIds(deviceIds); + groupDetails.setDeviceCount(deviceIds.size()); + return groupDetails; + } } 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/dto/GroupDetailsDTO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/GroupDetailsDTO.java new file mode 100644 index 0000000000..333999aeeb --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/GroupDetailsDTO.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.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 io.entgra.device.mgt.core.device.mgt.core.dto; + +import java.util.List; + +public class GroupDetailsDTO { + private int groupId; + private String groupName; + private String groupOwner; + private List deviceIds; + private int deviceCount; + + public int getGroupId() { + return groupId; + } + + public void setGroupId(int groupId) { + this.groupId = groupId; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public String getGroupOwner() { + return groupOwner; + } + + public void setGroupOwner(String groupOwner) { + this.groupOwner = groupOwner; + } + + public List getDeviceIds() { + return deviceIds; + } + + public void setDeviceIds(List deviceIds) { + this.deviceIds = deviceIds; + } + + public int getDeviceCount() { + return deviceCount; + } + + public void setDeviceCount(int deviceCount) { + this.deviceCount = deviceCount; + } + +} 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/dto/OperationDTO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OperationDTO.java new file mode 100644 index 0000000000..b6ac94fc3c --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OperationDTO.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.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 io.entgra.device.mgt.core.device.mgt.core.dto; + +import org.json.JSONObject; + +import java.sql.Timestamp; + +public class OperationDTO { + private int deviceId; + private String uuid; + private String status; + private int operationId; + private String actionTriggeredFrom; + private Timestamp actionTriggeredAt; + private int appReleaseId; + private String operationCode; + private JSONObject operationDetails; + private JSONObject operationProperties; + + // Getters and Setters + + public int getDeviceId() { + return deviceId; + } + + public void setDeviceId(int deviceId) { + this.deviceId = deviceId; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public int getOperationId() { + return operationId; + } + + public void setOperationId(int operationId) { + this.operationId = operationId; + } + + public String getActionTriggeredFrom() { + return actionTriggeredFrom; + } + + public void setActionTriggeredFrom(String actionTriggeredFrom) { + this.actionTriggeredFrom = actionTriggeredFrom; + } + + public Timestamp getActionTriggeredAt() { + return actionTriggeredAt; + } + + public void setActionTriggeredAt(Timestamp actionTriggeredAt) { + this.actionTriggeredAt = actionTriggeredAt; + } + + public int getAppReleaseId() { + return appReleaseId; + } + + public void setAppReleaseId(int appReleaseId) { + this.appReleaseId = appReleaseId; + } + + public String getOperationCode() { + return operationCode; + } + + public void setOperationCode(String operationCode) { + this.operationCode = operationCode; + } + + public JSONObject getOperationDetails() { + return operationDetails; + } + + public void setOperationDetails(JSONObject operationDetails) { + this.operationDetails = operationDetails; + } + + public JSONObject getOperationProperties() { + return operationProperties; + } + + public void setOperationProperties(JSONObject operationProperties) { + this.operationProperties = operationProperties; + } +} 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/dto/OwnerWithDeviceDTO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OwnerWithDeviceDTO.java new file mode 100644 index 0000000000..cd3e26bfbc --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OwnerWithDeviceDTO.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.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 io.entgra.device.mgt.core.device.mgt.core.dto; + +import java.util.List; + +public class OwnerWithDeviceDTO { + + private String userName; + private List deviceIds; + private int deviceCount; + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public List getDeviceIds() { + return deviceIds; + } + + public void setDeviceIds(List deviceIds) { + this.deviceIds = deviceIds; + } + + public int getDeviceCount() { + return deviceCount; + } + + public void setDeviceCount(int deviceCount) { + this.deviceCount = deviceCount; + } +} 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/OperationDAO.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/OperationDAO.java index 4abaf40022..5171b03b95 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/OperationDAO.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/OperationDAO.java @@ -23,6 +23,8 @@ import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.OperationResponse; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.DeviceActivity; +import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOException; +import io.entgra.device.mgt.core.device.mgt.core.dto.OperationDTO; import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.Operation; import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.OperationResponseMeta; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.OperationMapping; @@ -124,4 +126,6 @@ public interface OperationDAO { int getDeviceActivitiesCount(ActivityPaginationRequest activityPaginationRequest) throws OperationManagementDAOException; + + OperationDTO getOperationDetailsById(int operationId, int tenantId) throws OperationManagementDAOException; } 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 8322905a5e..15751c3d89 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 @@ -17,32 +17,35 @@ */ package io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.impl; -import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.ProfileOperation; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.context.PrivilegedCarbonContext; import io.entgra.device.mgt.core.device.mgt.common.ActivityPaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier; import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity; -import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.DeviceActivity; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.ActivityHolder; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.ActivityStatus; +import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.DeviceActivity; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.OperationResponse; import io.entgra.device.mgt.core.device.mgt.core.DeviceManagementConstants; import io.entgra.device.mgt.core.device.mgt.core.dao.util.DeviceManagementDAOUtil; +import io.entgra.device.mgt.core.device.mgt.core.dto.OperationDTO; import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.Operation; import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.OperationResponseMeta; +import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.ProfileOperation; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.OperationMapping; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationDAO; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOException; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOUtil; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.util.OperationDAOUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.JSONObject; +import org.wso2.carbon.context.PrivilegedCarbonContext; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; +import java.sql.Blob; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -2774,4 +2777,43 @@ public class GenericOperationDAOImpl implements OperationDAO { } return 0; } + + @Override + public OperationDTO getOperationDetailsById(int operationId, int tenantId) throws OperationManagementDAOException { + OperationDTO operationDetails = new OperationDTO(); + + String sql = "SELECT ID, OPERATION_CODE, OPERATION_DETAILS, OPERATION_PROPERTIES " + + "FROM DM_OPERATION " + + "WHERE ID = ? AND TENANT_ID = ?"; + + try (Connection conn = OperationManagementDAOFactory.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, operationId); + stmt.setInt(2, tenantId); + + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + operationDetails.setOperationId(rs.getInt("ID")); + operationDetails.setOperationCode(rs.getString("OPERATION_CODE")); + + Blob detailsBlob = rs.getBlob("OPERATION_DETAILS"); + if (detailsBlob != null) { + JSONObject operationDetailsJson = OperationDAOUtil.convertBlobToJsonObject(detailsBlob); + operationDetails.setOperationDetails(operationDetailsJson); + } + + Blob propertiesBlob = rs.getBlob("OPERATION_PROPERTIES"); + if (propertiesBlob != null) { + JSONObject operationPropertiesJson = OperationDAOUtil.convertBlobToJsonObject(propertiesBlob); + operationDetails.setOperationProperties(operationPropertiesJson); + } + } + } + } catch (SQLException e) { + throw new OperationManagementDAOException("Error occurred while retrieving operation details for operation ID: " + + operationId, e); + } + + return operationDetails; + } } 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 6561868060..3d5dd193ca 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 @@ -33,10 +33,14 @@ import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.Operation; import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.PolicyOperation; import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.ProfileOperation; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOException; +import org.json.JSONObject; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.ObjectInputStream; +import java.sql.Blob; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; @@ -387,4 +391,43 @@ public class OperationDAOUtil { return operation; } + public static JSONObject convertBlobToJsonObject(Blob blob) throws SQLException { + String jsonString; + try (InputStream inputStream = blob.getBinaryStream(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { + int bytesRead; + byte[] buffer = new byte[4096]; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + byte[] blobBytes = outputStream.toByteArray(); + + // Check if the blob data is a serialized Java object + if (blobBytes.length > 2 && (blobBytes[0] & 0xFF) == 0xAC && (blobBytes[1] & 0xFF) == 0xED) { + // Deserialize the object + try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(blobBytes))) { + Object obj = ois.readObject(); + if (obj instanceof String) { + jsonString = (String) obj; + } else { + jsonString = new JSONObject(obj).toString(); + } + } catch (ClassNotFoundException e) { + throw new SQLException("Failed to deserialize object from BLOB", e); + } + } else { + // If not serialized, treat it as plain JSON string + jsonString = new String(blobBytes, "UTF-8"); + } + } catch (IOException e) { + throw new SQLException("Failed to convert BLOB to JSON string", e); + } + + // Convert JSON string to JSONObject + if (jsonString == null || jsonString.isEmpty()) { + throw new SQLException("Converted JSON string is null or empty"); + } + return new JSONObject(jsonString); + } + } 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/service/DeviceManagementProviderService.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderService.java index 689fc1b243..8e112addd3 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderService.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderService.java @@ -19,6 +19,8 @@ package io.entgra.device.mgt.core.device.mgt.core.service; import io.entgra.device.mgt.core.device.mgt.common.app.mgt.Application; +import io.entgra.device.mgt.core.device.mgt.core.dto.OperationDTO; +import io.entgra.device.mgt.core.device.mgt.core.dto.OwnerWithDeviceDTO; import org.apache.commons.collections.map.SingletonMap; import io.entgra.device.mgt.core.device.mgt.common.*; import io.entgra.device.mgt.core.device.mgt.common.app.mgt.ApplicationManagementException; @@ -1073,4 +1075,22 @@ public interface DeviceManagementProviderService { List getEnrolledDevicesSince(Date since) throws DeviceManagementException; List getEnrolledDevicesPriorTo(Date before) throws DeviceManagementException; void deleteDeviceDataByTenantDomain(String tenantDomain) throws DeviceManagementException; + + /** + * Get owner details and device IDs for a given owner and tenant. + * + * @param owner the name of the owner. + * @return a map containing owner details (Owner, DeviceIds, DeviceCount). + * @throws DeviceManagementException if an error occurs while fetching owner details. + */ + OwnerWithDeviceDTO getOwnersWithDeviceIds(String owner) throws DeviceManagementDAOException; + + /** + * Get operation details by operation code. + * + * @param operationId the id of the operation. + * @return Map containing operation ID, operation code, operation details, and operation properties. + * @throws OperationManagementException if an error occurs while fetching the operation details. + */ + OperationDTO getOperationDetailsById(int operationId) throws OperationManagementException; } 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/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index 75f3836a34..3df333cbf2 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderServiceImpl.java @@ -22,6 +22,10 @@ import com.google.common.reflect.TypeToken; import com.google.gson.Gson; import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.DeviceStatusManagementService; import io.entgra.device.mgt.core.device.mgt.core.dao.TenantDAO; +import io.entgra.device.mgt.core.device.mgt.core.dto.OwnerWithDeviceDTO; +import io.entgra.device.mgt.core.device.mgt.core.dto.OperationDTO; +import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOException; +import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.extensions.logger.spi.EntgraLogger; import io.entgra.device.mgt.core.notification.logger.DeviceEnrolmentLogContext; import io.entgra.device.mgt.core.notification.logger.impl.EntgraDeviceEnrolmentLoggerImpl; @@ -120,6 +124,7 @@ import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceStatusDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceTypeDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.EnrollmentDAO; +import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.util.DeviceManagementDAOUtil; 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; @@ -173,6 +178,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv private final DeviceDAO deviceDAO; private final DeviceTypeDAO deviceTypeDAO; private final EnrollmentDAO enrollmentDAO; + private final OperationDAO operationDAO; private final ApplicationDAO applicationDAO; private MetadataDAO metadataDAO; private final DeviceStatusDAO deviceStatusDAO; @@ -185,6 +191,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv this.applicationDAO = DeviceManagementDAOFactory.getApplicationDAO(); this.deviceTypeDAO = DeviceManagementDAOFactory.getDeviceTypeDAO(); this.enrollmentDAO = DeviceManagementDAOFactory.getEnrollmentDAO(); + this.operationDAO = OperationManagementDAOFactory.getOperationDAO(); this.metadataDAO = MetadataManagementDAOFactory.getMetadataDAO(); this.deviceStatusDAO = DeviceManagementDAOFactory.getDeviceStatusDAO(); this.tenantDao = DeviceManagementDAOFactory.getTenantDAO(); @@ -5339,4 +5346,52 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv DeviceManagementDAOFactory.closeConnection(); } } + + @Override + public OwnerWithDeviceDTO getOwnersWithDeviceIds(String owner) throws DeviceManagementDAOException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + OwnerWithDeviceDTO ownerWithDeviceDTO; + + try { + DeviceManagementDAOFactory.openConnection(); + ownerWithDeviceDTO = this.enrollmentDAO.getOwnersWithDeviceIds(owner, tenantId); + } catch (DeviceManagementDAOException | SQLException e) { + String msg = "Error occurred while retrieving device IDs for owner: " + owner; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + + // Add device count to the DTO + if (ownerWithDeviceDTO != null) { + List deviceIds = ownerWithDeviceDTO.getDeviceIds(); + if (deviceIds != null) { + ownerWithDeviceDTO.setDeviceCount(deviceIds.size()); + } else { + ownerWithDeviceDTO.setDeviceCount(0); + } + } + + return ownerWithDeviceDTO; + } + + @Override + public OperationDTO getOperationDetailsById(int operationId) throws OperationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + OperationDTO operationDetails; + try { + OperationManagementDAOFactory.openConnection(); + operationDetails = this.operationDAO.getOperationDetailsById(operationId, tenantId); + } catch (SQLException | OperationManagementDAOException e) { + String msg = "Error occurred while retrieving operation details for operation ID: " + operationId; + log.error(msg, e); + throw new OperationManagementException(msg, e); + } finally { + OperationManagementDAOFactory.closeConnection(); + } + + return operationDetails; + } + } 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/service/GroupManagementProviderService.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderService.java index 2c741730bd..6c262ccf2d 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderService.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderService.java @@ -30,6 +30,7 @@ import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupAlreadyExistEx import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupManagementException; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupNotExistException; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.RoleDoesNotExistException; +import io.entgra.device.mgt.core.device.mgt.core.dto.GroupDetailsDTO; import org.wso2.carbon.user.api.AuthorizationManager; import org.wso2.carbon.user.api.UserStoreManager; @@ -371,4 +372,14 @@ public interface GroupManagementProviderService { DeviceTypesOfGroups getDeviceTypesOfGroups(List identifiers) throws GroupManagementException; DeviceGroup getUserOwnGroup(int groupId, boolean requireGroupProps, int depth) throws GroupManagementException; + + /** + * Get group details and device IDs for a given group name. + * + * @param groupName the name of the group. + * @return a map containing group details and device IDs. + * @throws GroupManagementException if an error occurs while fetching group details. + */ + GroupDetailsDTO getGroupDetailsWithDeviceIds(String groupName) throws GroupManagementException; + } 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/service/GroupManagementProviderServiceImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderServiceImpl.java index 88aad71dcd..43e2a8eecc 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderServiceImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderServiceImpl.java @@ -26,13 +26,13 @@ import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupAlreadyExistEx import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupManagementException; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupNotExistException; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.RoleDoesNotExistException; +import io.entgra.device.mgt.core.device.mgt.core.dto.GroupDetailsDTO; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOException; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.core.dao.GroupDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.GroupManagementDAOException; import io.entgra.device.mgt.core.device.mgt.core.dao.GroupManagementDAOFactory; -import io.entgra.device.mgt.core.device.mgt.core.permission.mgt.PermissionManagerServiceImpl; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -1629,6 +1629,7 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid createGroupWithChildren(nextParentGroup, childrenGroups, requireGroupProps, tenantId, depth, counter); } } + @Override public DeviceTypesOfGroups getDeviceTypesOfGroups(List identifiers) throws GroupManagementException { DeviceTypesOfGroups deviceTypesOfGroups = new DeviceTypesOfGroups(); @@ -1685,4 +1686,37 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid return deviceTypesOfGroups; } + + @Override + public GroupDetailsDTO getGroupDetailsWithDeviceIds(String groupName) throws GroupManagementException { + if (log.isDebugEnabled()) { + log.debug("Retrieving group details and device IDs for group: " + groupName); + } + int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId(); + GroupDetailsDTO groupDetailsWithDevices; + + try { + GroupManagementDAOFactory.openConnection(); + groupDetailsWithDevices = this.groupDAO.getGroupDetailsWithDeviceIds(groupName, tenantId); + } catch (GroupManagementDAOException | SQLException e) { + String msg = "Error occurred while retrieving group details and device IDs for group: " + groupName; + log.error(msg, e); + throw new GroupManagementException(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); + } + + // Add device count + if (groupDetailsWithDevices != null) { + List deviceIds = (List) groupDetailsWithDevices.getDeviceIds(); + if (deviceIds != null) { + groupDetailsWithDevices.setDeviceCount(deviceIds.size()); + } else { + groupDetailsWithDevices.setDeviceCount(0); + } + } + + return groupDetailsWithDevices; + } + }