From 8b6eee0a97f1173d09c31e795002af48fc6bcd3c Mon Sep 17 00:00:00 2001 From: Oshani Silva Date: Wed, 17 Jul 2024 05:42:24 +0000 Subject: [PATCH] Add fix for group subscription table Co-authored-by: Oshani Silva Co-committed-by: Oshani Silva --- .../common/CategorizedSubscriptionResult.java | 87 +++++++++++++++++++ .../mgt/core/dao/SubscriptionDAO.java | 12 +++ .../GenericSubscriptionDAOImpl.java | 46 +++++++++- .../core/impl/SubscriptionManagerImpl.java | 48 +++++++++- .../core/dao/impl/AbstractGroupDAOImpl.java | 12 ++- 5 files changed, 194 insertions(+), 11 deletions(-) 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 18da5a7736..e685284b77 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 @@ -23,10 +23,15 @@ import java.util.List; public class CategorizedSubscriptionResult { private List installedDevices; + private int installedDevicesCount; private List pendingDevices; + private int pendingDevicesCount; private List errorDevices; + private int errorDevicesCount; private List newDevices; + private int newDevicesCount; private List subscribedDevices; + private int subscribedDevicesCount; public CategorizedSubscriptionResult(List installedDevices, List pendingDevices, @@ -61,6 +66,48 @@ public class CategorizedSubscriptionResult { this.subscribedDevices = subscribedDevices; } + public CategorizedSubscriptionResult(List installedDevices, + List pendingDevices, + List errorDevices, + List newDevices, + int installedDevicesCount, + int pendingDevicesCount, + int errorDevicesCount, + int newDevicesCount + ) { + this.installedDevices = installedDevices; + this.pendingDevices = pendingDevices; + this.errorDevices = errorDevices; + this.newDevices = newDevices; + this.subscribedDevices = null; + this.installedDevicesCount = installedDevicesCount; + this.pendingDevicesCount = pendingDevicesCount; + this.errorDevicesCount = errorDevicesCount; + this.newDevicesCount = newDevicesCount; + this.subscribedDevicesCount = 0; + } + + public CategorizedSubscriptionResult(List installedDevices, + List pendingDevices, + List errorDevices, + List newDevices, + List subscribedDevices, int installedDevicesCount, + int pendingDevicesCount, + int errorDevicesCount, + int newDevicesCount, + int subscribedDevicesCount) { + this.installedDevices = installedDevices; + this.pendingDevices = pendingDevices; + this.errorDevices = errorDevices; + this.newDevices = newDevices; + this.subscribedDevices = subscribedDevices; + this.installedDevicesCount = installedDevicesCount; + this.pendingDevicesCount = pendingDevicesCount; + this.errorDevicesCount = errorDevicesCount; + this.newDevicesCount = newDevicesCount; + this.subscribedDevicesCount = subscribedDevicesCount; + } + public CategorizedSubscriptionResult(List devices, String tabActionStatus) { switch (tabActionStatus) { case "COMPLETED": @@ -127,4 +174,44 @@ public class CategorizedSubscriptionResult { public void setSubscribedDevices(List subscribedDevices) { this.subscribedDevices = subscribedDevices; } + + public int getInstalledDevicesCount() { + return installedDevicesCount; + } + + public void setInstalledDevicesCount(int installedDevicesCount) { + this.installedDevicesCount = installedDevicesCount; + } + + public int getPendingDevicesCount() { + return pendingDevicesCount; + } + + public void setPendingDevicesCount(int pendingDevicesCount) { + this.pendingDevicesCount = pendingDevicesCount; + } + + public int getErrorDevicesCount() { + return errorDevicesCount; + } + + public void setErrorDevicesCount(int errorDevicesCount) { + this.errorDevicesCount = errorDevicesCount; + } + + public int getNewDevicesCount() { + return newDevicesCount; + } + + public void setNewDevicesCount(int newDevicesCount) { + this.newDevicesCount = newDevicesCount; + } + + public int getSubscribedDevicesCount() { + return subscribedDevicesCount; + } + + public void setSubscribedDevicesCount(int subscribedDevicesCount) { + this.subscribedDevicesCount = subscribedDevicesCount; + } } 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 ec3717391a..498221eb68 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 @@ -517,4 +517,16 @@ public interface SubscriptionDAO { * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ int getUserUnsubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; + + /** + * This method is used to get the counts of devices related to a UUID. + * + * @param appReleaseId the UUID of the application release. + * @param tenantId id of the current tenant. + * @param actionStatus categorized status. + * @param actionTriggeredFrom type of the action. + * @return {@link int} which contains the count of the subscription type + * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. + */ + int countSubscriptionsByStatus(int appReleaseId, int tenantId, String actionStatus, String actionTriggeredFrom) 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 8ffb95f039..2241a0b989 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 @@ -1655,14 +1655,22 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc "GS.UNSUBSCRIBED_BY, GS.UNSUBSCRIBED_TIMESTAMP, GS.AP_APP_RELEASE_ID " + "FROM AP_GROUP_SUBSCRIPTION GS " + "WHERE GS.AP_APP_RELEASE_ID = ? AND GS.UNSUBSCRIBED = ? AND GS.TENANT_ID = ? " + - "ORDER BY " + subscriptionStatusTime + " DESC " + - "LIMIT ? OFFSET ?"; + "ORDER BY " + subscriptionStatusTime + " DESC "; + + // Append limit and offset only if limit is not -1 + if (limit != -1) { + sql = sql + " LIMIT ? OFFSET ?"; + } try (PreparedStatement ps = conn.prepareStatement(sql)) { ps.setInt(1, appReleaseId); ps.setBoolean(2, unsubscribe); ps.setInt(3, tenantId); - ps.setInt(4, limit); - ps.setInt(5, offset); + + // Set limit and offset parameters only if limit is not -1 + if (limit != -1) { + ps.setInt(4, limit); + ps.setInt(5, offset); + } try (ResultSet rs = ps.executeQuery()) { GroupSubscriptionDTO groupDetail; @@ -2487,4 +2495,34 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc throw new ApplicationManagementDAOException(msg, e); } } + + public int countSubscriptionsByStatus(int appReleaseId, int tenantId, String actionStatus, String actionTriggeredFrom) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to count device subscriptions by status and actionTriggeredFrom for the given AppReleaseID."); + } + try { + Connection conn = this.getDBConnection(); + String sql = "SELECT COUNT(*) FROM AP_DEVICE_SUBSCRIPTION WHERE AP_APP_RELEASE_ID = ? AND TENANT_ID = ? AND STATUS = ? AND ACTION_TRIGGERED_FROM = ?"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + ps.setString(3, actionStatus); + ps.setString(4, actionTriggeredFrom); + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + return rs.getInt(1); + } + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to count device subscriptions by status and action trigger."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while counting device subscriptions by status and action trigger."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + return 0; + } } 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 065c9576bd..b7dc62a0fc 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 @@ -1725,7 +1725,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { List groupDetailsWithDevices = new ArrayList<>(); List groupDetails = - subscriptionDAO.getGroupsSubscriptionDetailsByAppReleaseID(appReleaseId, unsubscribe, tenantId, offset, limit); + subscriptionDAO.getGroupsSubscriptionDetailsByAppReleaseID(appReleaseId, unsubscribe, tenantId, offset, -1); if (groupDetails == null) { throw new ApplicationManagementException("Group details not found for appReleaseId: " + appReleaseId); } @@ -1744,7 +1744,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { GroupDetailsDTO groupDetailWithDevices = groupManagementProviderService.getGroupDetailsWithDevices( groupName, applicationDTO.getDeviceTypeId(), request.getOwner(), - request.getDeviceName(), request.getDeviceStatus(), offset, limit); + request.getDeviceName(), request.getDeviceStatus(), offset, -1); SubscriptionsDTO groupDetailDTO = new SubscriptionsDTO(); groupDetailDTO.setId(groupDetailWithDevices.getGroupId()); @@ -1878,33 +1878,73 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } List requestedDevices = new ArrayList<>(); + int installedCount; + int pendingCount; + int errorCount; + int newCount; + int subscribedCount; + int totalDeviceCount = + groupManagementProviderService.getDeviceCount(groupDetailWithDevices.getGroupId()); + if (StringUtils.isNotBlank(request.getTabActionStatus())) { switch (request.getTabActionStatus()) { case "COMPLETED": requestedDevices = installedDevices; + installedCount = subscriptionDAO.countSubscriptionsByStatus(appReleaseId, tenantId, request.getTabActionStatus(), request.getActionType()); break; case "PENDING": requestedDevices = pendingDevices; + pendingCount = subscriptionDAO.countSubscriptionsByStatus(appReleaseId, tenantId, request.getTabActionStatus(), request.getActionType()); break; case "ERROR": requestedDevices = errorDevices; + errorCount = subscriptionDAO.countSubscriptionsByStatus(appReleaseId, tenantId, request.getTabActionStatus(), request.getActionType()); break; case "NEW": requestedDevices = newDevices; break; case "SUBSCRIBED": requestedDevices = subscribedDevices; + subscribedCount = subscriptionDAO.countSubscriptionsByStatus(appReleaseId, tenantId, request.getTabActionStatus(), request.getActionType()); break; } groupDetailDTO.setDevices(new CategorizedSubscriptionResult(requestedDevices, request.getTabActionStatus())); } else { CategorizedSubscriptionResult categorizedSubscriptionResult; + + installedCount = subscriptionDAO.countSubscriptionsByStatus(appReleaseId, tenantId, "COMPLETED", request.getActionType()); + pendingCount = subscriptionDAO.countSubscriptionsByStatus(appReleaseId, tenantId, "PENDING", request.getActionType()); + errorCount = subscriptionDAO.countSubscriptionsByStatus(appReleaseId, tenantId, "ERROR", request.getActionType()); + subscribedCount = subscriptionDAO.countSubscriptionsByStatus(appReleaseId, tenantId, "SUBSCRIBED", request.getActionType()); + newCount = totalDeviceCount - (installedCount + pendingCount + errorCount + subscribedCount); + + List paginatedInstalledDevices = installedDevices.stream() + .skip(offset) + .limit(limit) + .collect(Collectors.toList()); + List paginatedPendingDevices = pendingDevices.stream() + .skip(offset) + .limit(limit) + .collect(Collectors.toList()); + List paginatedErrorDevices = errorDevices.stream() + .skip(offset) + .limit(limit) + .collect(Collectors.toList()); + List paginatedNewDevices = newDevices.stream() + .skip(offset) + .limit(limit) + .collect(Collectors.toList()); + List paginatedSubscribedDevices = subscribedDevices.stream() + .skip(offset) + .limit(limit) + .collect(Collectors.toList()); + if (subscribedDevices.isEmpty()) { categorizedSubscriptionResult = - new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + new CategorizedSubscriptionResult(paginatedInstalledDevices, paginatedPendingDevices, paginatedErrorDevices, paginatedNewDevices, installedCount, pendingCount, errorCount, newCount); } else { categorizedSubscriptionResult = - new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices, subscribedDevices); + new CategorizedSubscriptionResult(paginatedInstalledDevices, paginatedPendingDevices, paginatedErrorDevices, paginatedNewDevices, paginatedSubscribedDevices, installedCount, pendingCount, errorCount, newCount, subscribedCount); } groupDetailDTO.setDevices(categorizedSubscriptionResult); } 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 1eba6c1a7e..cfa706b0e0 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 @@ -1495,7 +1495,10 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { sql.append(" AND e.STATUS = ?"); } - sql.append(" LIMIT ? OFFSET ?"); + // Append limit and offset only if limit is not -1 + if (limit != -1) { + sql.append(" LIMIT ? OFFSET ?"); + } Connection conn = null; try { @@ -1519,8 +1522,11 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { stmt.setString(index++, deviceStatus); } - stmt.setInt(index++, limit); - stmt.setInt(index++, offset); + // Set limit and offset parameters only if limit is not -1 + if (limit != -1) { + stmt.setInt(index++, limit); + stmt.setInt(index++, offset); + } try (ResultSet rs = stmt.executeQuery()) { while (rs.next()) {