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 60531ac8aa..28cc436115 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 @@ -25,8 +25,8 @@ public class CategorizedSubscriptionResult { private List pendingDevices; private List errorDevices; private List newDevices; + private List subscribedDevices; - // without newDevices public CategorizedSubscriptionResult(List installedDevices, List pendingDevices, List errorDevices) { @@ -34,9 +34,9 @@ public class CategorizedSubscriptionResult { this.pendingDevices = pendingDevices; this.errorDevices = errorDevices; this.newDevices = null; + this.subscribedDevices = null; } - // with newDevices public CategorizedSubscriptionResult(List installedDevices, List pendingDevices, List errorDevices, @@ -45,6 +45,19 @@ public class CategorizedSubscriptionResult { this.pendingDevices = pendingDevices; this.errorDevices = errorDevices; this.newDevices = newDevices; + this.subscribedDevices = null; + } + + public CategorizedSubscriptionResult(List installedDevices, + List pendingDevices, + List errorDevices, + List newDevices, + List subscribedDevices) { + this.installedDevices = installedDevices; + this.pendingDevices = pendingDevices; + this.errorDevices = errorDevices; + this.newDevices = newDevices; + this.subscribedDevices = subscribedDevices; } public List getInstalledDevices() { @@ -78,4 +91,13 @@ public class CategorizedSubscriptionResult { public void setNewDevices(List newDevices) { this.newDevices = newDevices; } + + public List getSubscribedDevices() { + return subscribedDevices; + } + + public void setSubscribedDevices(List subscribedDevices) { + this.subscribedDevices = subscribedDevices; + } } + 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 633b54ce73..aadbfaca6a 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 @@ -34,6 +34,11 @@ public class DeviceSubscriptionData { private Device device; private String currentInstalledVersion; private int deviceId; + private String deviceOwner; + private String deviceStatus; + private boolean unsubscribed; + private String unsubscribedBy; + private Timestamp unsubscribedTimestamp; public String getAction() { return action; @@ -114,4 +119,44 @@ public class DeviceSubscriptionData { public void setActionTriggeredTimestamp(Timestamp actionTriggeredTimestamp) { this.actionTriggeredTimestamp = actionTriggeredTimestamp; } + + public String getDeviceOwner() { + return deviceOwner; + } + + public void setDeviceOwner(String deviceOwner) { + this.deviceOwner = deviceOwner; + } + + public String getDeviceStatus() { + return deviceStatus; + } + + public void setDeviceStatus(String deviceStatus) { + this.deviceStatus = deviceStatus; + } + + public boolean isUnsubscribed() { + 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; + } } 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/DeviceSubscriptionResponseDTO.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/DeviceSubscriptionResponseDTO.java new file mode 100644 index 0000000000..ded2032521 --- /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/DeviceSubscriptionResponseDTO.java @@ -0,0 +1,42 @@ +package io.entgra.device.mgt.core.application.mgt.common.dto; + +import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; + +import java.util.Map; + +public class DeviceSubscriptionResponseDTO { + private int deviceCount; + private Map statusPercentages; + private CategorizedSubscriptionResult devices; + + public DeviceSubscriptionResponseDTO(int deviceCount, Map statusPercentages, + CategorizedSubscriptionResult devices) { + this.deviceCount = deviceCount; + this.statusPercentages = statusPercentages; + this.devices = devices; + } + + 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/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 index 442d82faed..bc215b1e30 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/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 @@ -34,6 +34,8 @@ public class GroupSubscriptionDetailDTO { private Timestamp unsubscribedTimestamp; private int appReleaseId; private int deviceCount; + private String deviceOwner; + private String deviceStatus; private CategorizedSubscriptionResult devices; private Map statusPercentages; @@ -133,4 +135,20 @@ public class GroupSubscriptionDetailDTO { public void setStatusPercentages(Map statusPercentages) { this.statusPercentages = statusPercentages; } + + public String getDeviceOwner() { + return deviceOwner; + } + + public void setDeviceOwner(String deviceOwner) { + this.deviceOwner = deviceOwner; + } + + public String getDeviceStatus() { + return deviceStatus; + } + + public void setDeviceStatus(String deviceStatus) { + this.deviceStatus = deviceStatus; + } } 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 7238f7ebba..d3fd89f004 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 @@ -33,6 +33,7 @@ public class UserSubscriptionDTO { private Timestamp unsubscribedTimestamp; private int appReleaseId; private int deviceCount; + private String deviceStatus; private Map statusPercentages; private CategorizedSubscriptionResult devices; @@ -120,5 +121,12 @@ public class UserSubscriptionDTO { this.devices = devices; } + public String getDeviceStatus() { + return deviceStatus; + } + + public void setDeviceStatus(String deviceStatus) { + this.deviceStatus = deviceStatus; + } } 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 90c7099519..fc0463add2 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 @@ -27,6 +27,7 @@ import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptio 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.dto.DeviceSubscriptionResponseDTO; 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.device.mgt.common.DeviceIdentifier; @@ -228,40 +229,77 @@ public interface SubscriptionManager { * 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 + * @param subscriptionStatus the status of the subscription (subscribed or unsubscribed) + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link GroupSubscriptionDetailDTO} which contains the details of group subscriptions. * @throws ApplicationManagementException if an error occurs while fetching the group details */ - List getGroupsSubscriptionDetailsByUUID(String uuid, String subscriptionStatus) + List getGroupsSubscriptionDetailsByUUID(String uuid, String subscriptionStatus, int offset, int limit) 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 + * @param subscriptionStatus the status of the subscription (subscribed or unsubscribed) + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link UserSubscriptionDTO} which contains the details of user subscriptions. + * @throws ApplicationManagementException if an error occurs while fetching the user details */ - List getUserSubscriptionsByUUID(String uuid, String subscriptionStatus) + List getUserSubscriptionsByUUID(String uuid, String subscriptionStatus, int offset, int limit) 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 + * @param subscriptionStatus the status of the subscription (subscribed or unsubscribed) + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link RoleSubscriptionDTO} which contains the details of role subscriptions. + * @throws ApplicationManagementException if an error occurs while fetching the role details + */ + List getRoleSubscriptionsByUUID(String uuid, String subscriptionStatus, int offset, int limit) + throws ApplicationManagementException; + + /** + * Retrieves the Device Subscription details associated with a given app release UUID. + * + * @param uuid the UUID of the app release + * @param subscriptionStatus the status of the subscription (subscribed or unsubscribed) + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link DeviceSubscriptionResponseDTO} which contains the details of device subscriptions. + * @throws ApplicationManagementException if an error occurs while fetching the device subscription details + */ + DeviceSubscriptionResponseDTO getDeviceSubscriptionsDetailsByUUID(String uuid, String subscriptionStatus, int offset, int limit) + throws ApplicationManagementException; + + /** + * Retrieves the All Device details associated with a given app release UUID. + * + * @param uuid the UUID of the app release + * @param subscriptionStatus the status of the subscription (subscribed or unsubscribed) + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link DeviceSubscriptionResponseDTO} which contains the details of device subscriptions. + * @throws ApplicationManagementException if an error occurs while fetching the subscription details */ - List getRoleSubscriptionsByUUID(String uuid, String subscriptionStatus) + DeviceSubscriptionResponseDTO getAllSubscriptionDetailsByUUID(String uuid, String subscriptionStatus, int offset, int limit) 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. + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link DeviceOperationDTO} which contains the details of device subscriptions. * @throws SubscriptionManagementException if there is an error while fetching the details. */ - List getDeviceSubscriptionsOperationsByUUID(String uuid) + List getDeviceSubscriptionsOperationsByUUID(String uuid, int offset, int limit) 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 a9b90375db..a91d13eb06 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 @@ -318,61 +318,99 @@ public interface SubscriptionDAO { void deleteScheduledSubscriptionByTenant(int tenantId) throws ApplicationManagementDAOException; /** - * This method is used to get the details of groups related to a UUID. + * This method is used to get the details of group subscriptions related to a appReleaseId. * - * @param uuid the UUID of the application release. + * @param appReleaseId the appReleaseId 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. + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link GroupSubscriptionDTO} which contains the details of group subscriptions. * @throws ApplicationManagementDAOException if connection establishment fails. */ - List getGroupsSubscriptionDetailsByUUID(String uuid, boolean unsubscribe, int tenantId) + List getGroupsSubscriptionDetailsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, int limit) throws ApplicationManagementDAOException; /** - * This method is used to get the details of user subscriptions related to a UUID. + * This method is used to get the details of user subscriptions related to a appReleaseId. * - * @param uuid the UUID of the application release. + * @param appReleaseId the appReleaseId 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. + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link UserSubscriptionDTO} which contains the details of user subscriptions. * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - List getUserSubscriptionsByUUID(String uuid, boolean unsubscribe, int tenantId) + List getUserSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, + int offset, int limit) throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of role subscriptions related to a appReleaseId. + * + * @param appReleaseId the appReleaseId of the application release. + * @param unsubscribe the Status of the subscription. + * @param tenantId id of the current tenant. + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link RoleSubscriptionDTO} which contains the details of role subscriptions. + * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. + */ + List getRoleSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, int limit) throws ApplicationManagementDAOException; /** - * This method is used to get the details of role subscriptions related to a UUID. + * This method is used to get the details of device subscriptions related to a appReleaseId. * - * @param uuid the UUID of the application release. + * @param appReleaseId the appReleaseId 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. + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link DeviceSubscriptionDTO} which contains the details of device subscriptions. * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - List getRoleSubscriptionsByUUID(String uuid, boolean unsubscribe, int tenantId) + List getDeviceSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, int limit) 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 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. + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link DeviceOperationDTO} which contains the details of device subscriptions. * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - List getDeviceSubscriptionsOperationsByUUID(String uuid, int tenantId) + List getDeviceSubscriptionsOperationsByAppReleaseID(int appReleaseId, int tenantId, int offset, int limit) 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 unsubscribe the Status of the subscription. * @param tenantId id of the current tenant. - * @return deviceSubscriptions - list of device subscription details related to the UUID. + * @param deviceIds deviceIds deviceIds to retrieve data. + * @return {@link DeviceOperationDTO} which contains the details of device subscriptions. * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - List getDeviceSubscriptionsDetails(int appReleaseId, int tenantId) + List getSubscriptionDetailsByDeviceIds(int appReleaseId, boolean unsubscribe, int tenantId, List deviceIds) + 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 unsubscribe the Status of the subscription. + * @param tenantId id of the current tenant. + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link DeviceOperationDTO} which contains the details of device subscriptions. + * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. + */ + List getAllSubscriptionsDetails(int appReleaseId, boolean unsubscribe, int tenantId, int offset, int limit) throws ApplicationManagementDAOException; /** @@ -383,8 +421,7 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getAllSubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getAllSubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /** * This method is used to get the counts of all unsubscription types related to a UUID. @@ -394,8 +431,7 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getAllUnsubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getAllUnsubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /** * This method is used to get the counts of device subscriptions related to a UUID. @@ -405,8 +441,7 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getDeviceSubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getDeviceSubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /** * This method is used to get the counts of device unsubscription related to a UUID. @@ -416,8 +451,7 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getDeviceUnsubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getDeviceUnsubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /** * This method is used to get the counts of group subscriptions related to a UUID. @@ -427,8 +461,7 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getGroupSubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getGroupSubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /** * This method is used to get the counts of group unsubscription related to a UUID. @@ -438,8 +471,7 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getGroupUnsubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getGroupUnsubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /** * This method is used to get the counts of role subscriptions related to a UUID. @@ -449,8 +481,7 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getRoleSubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getRoleSubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /** * This method is used to get the counts of role unsubscription related to a UUID. @@ -460,8 +491,7 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getRoleUnsubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getRoleUnsubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /** * This method is used to get the counts of user subscriptions related to a UUID. @@ -471,8 +501,7 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getUserSubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getUserSubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /** * This method is used to get the counts of user unsubscription related to a UUID. @@ -482,6 +511,5 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getUserUnsubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getUserUnsubscriptionCount(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 c005100fd9..bf25c9c2b5 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 @@ -48,6 +48,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.StringJoiner; +import java.util.stream.Collectors; public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements SubscriptionDAO { private static final Log log = LogFactory.getLog(GenericSubscriptionDAOImpl.class); @@ -1641,23 +1642,29 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } @Override - public List getGroupsSubscriptionDetailsByUUID(String uuid, boolean unsubscribe, int tenantId) + public List getGroupsSubscriptionDetailsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, int limit) throws ApplicationManagementDAOException { if (log.isDebugEnabled()) { - log.debug("Request received in DAO Layer to get groups related to the given UUID."); + log.debug("Request received in DAO Layer to get groups related to the given AppReleaseID."); } try { Connection conn = this.getDBConnection(); List groupDetails = new ArrayList<>(); + + String subscriptionStatusTime = unsubscribe ? "GS.UNSUBSCRIBED_TIMESTAMP" : "GS.SUBSCRIBED_TIMESTAMP"; 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 = ?"; + "WHERE GS.AP_APP_RELEASE_ID = ? AND GS.UNSUBSCRIBED = ? AND GS.TENANT_ID = ? " + + "ORDER BY " + subscriptionStatusTime + " DESC " + + "LIMIT ? OFFSET ?"; try (PreparedStatement ps = conn.prepareStatement(sql)) { - ps.setString(1, uuid); + ps.setInt(1, appReleaseId); ps.setBoolean(2, unsubscribe); ps.setInt(3, tenantId); + ps.setInt(4, limit); + ps.setInt(5, offset); + try (ResultSet rs = ps.executeQuery()) { GroupSubscriptionDTO groupDetail; while (rs.next()) { @@ -1687,23 +1694,28 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } @Override - public List getUserSubscriptionsByUUID(String uuid, boolean unsubscribe, int tenantId) - throws ApplicationManagementDAOException { + public List getUserSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, + int offset, int limit) 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 subscriptionStatusTime = unsubscribe ? "US.UNSUBSCRIBED_TIMESTAMP" : "US.SUBSCRIBED_TIMESTAMP"; 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 " + + "US.UNSUBSCRIBED_BY, US.UNSUBSCRIBED_TIMESTAMP, US.AP_APP_RELEASE_ID " + "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 = ?"; + "WHERE US.AP_APP_RELEASE_ID = ? AND US.UNSUBSCRIBED = ? AND US.TENANT_ID = ? " + + "ORDER BY " + subscriptionStatusTime + " DESC " + + "LIMIT ? OFFSET ?"; try (PreparedStatement ps = conn.prepareStatement(sql)) { - ps.setString(1, uuid); + ps.setInt(1, appReleaseId); ps.setBoolean(2, unsubscribe); ps.setInt(3, tenantId); + ps.setInt(4, limit); + ps.setInt(5, offset); try (ResultSet rs = ps.executeQuery()) { while (rs.next()) { UserSubscriptionDTO userSubscription; @@ -1733,23 +1745,28 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } @Override - public List getRoleSubscriptionsByUUID(String uuid, boolean unsubscribe, int tenantId) - throws ApplicationManagementDAOException { + public List getRoleSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, + int limit) throws ApplicationManagementDAOException { if (log.isDebugEnabled()) { - log.debug("Request received in DAO Layer to get role subscriptions related to the given UUID."); + log.debug("Request received in DAO Layer to get role subscriptions related to the given AppReleaseID."); } try { Connection conn = this.getDBConnection(); List roleSubscriptions = new ArrayList<>(); + + String subscriptionStatusTime = unsubscribe ? "ARS.UNSUBSCRIBED_TIMESTAMP" : "ARS.SUBSCRIBED_TIMESTAMP"; 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 = ?"; + "WHERE ARS.AP_APP_RELEASE_ID = ? AND ARS.UNSUBSCRIBED = ? AND ARS.TENANT_ID = ? " + + "ORDER BY " + subscriptionStatusTime + " DESC " + + "LIMIT ? OFFSET ?"; try (PreparedStatement ps = conn.prepareStatement(sql)) { - ps.setString(1, uuid); + ps.setInt(1, appReleaseId); ps.setBoolean(2, unsubscribe); ps.setInt(3, tenantId); + ps.setInt(4, limit); + ps.setInt(5, offset); try (ResultSet rs = ps.executeQuery()) { RoleSubscriptionDTO roleSubscription; while (rs.next()) { @@ -1779,16 +1796,76 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } @Override - public List getDeviceSubscriptionsOperationsByUUID(String uuid, int tenantId) + public List getDeviceSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, int limit) throws ApplicationManagementDAOException { if (log.isDebugEnabled()) { - log.debug("Request received in DAO Layer to get device subscriptions related to the given UUID."); + log.debug("Request received in DAO Layer to get device subscriptions related to the given AppReleaseID."); + } + try { + Connection conn = this.getDBConnection(); + List deviceSubscriptions = new ArrayList<>(); + + String subscriptionStatusTime = unsubscribe ? "DS.UNSUBSCRIBED_TIMESTAMP" : "DS.SUBSCRIBED_TIMESTAMP"; + String sql = "SELECT DS.DM_DEVICE_ID, " + + "DS.SUBSCRIBED_BY, " + + "DS.SUBSCRIBED_TIMESTAMP, " + + "DS.STATUS, " + + "DS.UNSUBSCRIBED, " + + "DS.UNSUBSCRIBED_BY, " + + "DS.UNSUBSCRIBED_TIMESTAMP, " + + "DS.AP_APP_RELEASE_ID " + + "FROM AP_DEVICE_SUBSCRIPTION DS " + + "WHERE DS.AP_APP_RELEASE_ID = ? " + + "AND DS.UNSUBSCRIBED = ? " + + "AND DS.TENANT_ID = ? " + + "AND DS.ACTION_TRIGGERED_FROM = 'DEVICE' " + + "ORDER BY " + subscriptionStatusTime + " DESC " + + "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); + try (ResultSet rs = ps.executeQuery()) { + DeviceSubscriptionDTO deviceSubscription; + while (rs.next()) { + deviceSubscription = new DeviceSubscriptionDTO(); + deviceSubscription.setDeviceId(rs.getInt("DM_DEVICE_ID")); + deviceSubscription.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); + deviceSubscription.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_TIMESTAMP")); + deviceSubscription.setStatus(rs.getString("STATUS")); + deviceSubscription.setUnsubscribed(rs.getBoolean("UNSUBSCRIBED")); + deviceSubscription.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY")); + deviceSubscription.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_TIMESTAMP")); + 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 getDeviceSubscriptionsOperationsByAppReleaseID( + int appReleaseId, int tenantId, int offset, int limit) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get device subscriptions related to the given AppReleaseID."); } try { Connection conn = this.getDBConnection(); List deviceSubscriptions = new ArrayList<>(); String sql = "SELECT " + - " aar.UUID, " + " ads.DM_DEVICE_ID, " + " aasom.OPERATION_ID, " + " ads.STATUS, " + @@ -1797,17 +1874,18 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc " 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 = ?"; + "WHERE ads.AP_APP_RELEASE_ID = ? AND ads.TENANT_ID = ? " + + "LIMIT ? OFFSET ?"; try (PreparedStatement ps = conn.prepareStatement(sql)) { - ps.setString(1, uuid); + ps.setInt(1, appReleaseId); ps.setInt(2, tenantId); + ps.setInt(3, limit); + ps.setInt(4, offset); 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")); @@ -1831,12 +1909,82 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } @Override - public List getDeviceSubscriptionsDetails(int appReleaseId, int tenantId) throws - ApplicationManagementDAOException { + public List getSubscriptionDetailsByDeviceIds(int appReleaseId, boolean unsubscribe, int tenantId, List deviceIds) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting device subscriptions for the application release id " + appReleaseId + + " and device ids " + deviceIds + " from the database"); + } + try { + Connection conn = this.getDBConnection(); + String subscriptionStatusTime = unsubscribe ? "DS.UNSUBSCRIBED_TIMESTAMP" : "DS.SUBSCRIBED_TIMESTAMP"; + 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.UNSUBSCRIBED = ? AND DS.TENANT_ID = ? AND DS.DM_DEVICE_ID IN (" + + deviceIds.stream().map(id -> "?").collect(Collectors.joining(",")) + ") " + + "ORDER BY " + subscriptionStatusTime + " DESC"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setBoolean(2, unsubscribe); + ps.setInt(3, tenantId); + for (int i = 0; i < deviceIds.size(); i++) { + ps.setInt(4 + i, deviceIds.get(i)); + } + try (ResultSet rs = ps.executeQuery()) { + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved device subscriptions for application release id " + + appReleaseId + " and device ids " + deviceIds); + } + List subscriptions = new ArrayList<>(); + while (rs.next()) { + DeviceSubscriptionDTO 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")); + subscriptions.add(subscription); + } + return subscriptions; + } + } catch (SQLException e) { + String msg = "Error occurred while running SQL to get device subscription data for application ID: " + appReleaseId + + " and device ids: " + deviceIds + "."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection for getting device subscriptions for " + + "application Id: " + appReleaseId + " and device ids: " + deviceIds + "."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + + } + + @Override + public List getAllSubscriptionsDetails(int appReleaseId, boolean unsubscribe, int tenantId, + int offset, int limit) throws ApplicationManagementDAOException { if (log.isDebugEnabled()) { log.debug("Getting device subscriptions for the application release id " + appReleaseId + " from the database"); } + + String subscriptionStatusTime = unsubscribe ? "DS.UNSUBSCRIBED_TIMESTAMP" : "DS.SUBSCRIBED_TIMESTAMP"; String sql = "SELECT " + "DS.ID AS ID, " + "DS.SUBSCRIBED_BY AS SUBSCRIBED_BY, " @@ -1848,13 +1996,18 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc + "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=?"; + + "WHERE DS.AP_APP_RELEASE_ID = ? AND DS.UNSUBSCRIBED = ? AND DS.TENANT_ID=? " + + "ORDER BY " + subscriptionStatusTime + " DESC " + + "LIMIT ? OFFSET ?"; try { Connection conn = this.getDBConnection(); try (PreparedStatement ps = conn.prepareStatement(sql)) { ps.setInt(1, appReleaseId); - ps.setInt(2, tenantId); + ps.setBoolean(2, unsubscribe); + ps.setInt(3, tenantId); + ps.setInt(4, limit); + ps.setInt(5, offset); try (ResultSet rs = ps.executeQuery()) { if (log.isDebugEnabled()) { log.debug("Successfully retrieved device subscriptions for application release id " @@ -1862,9 +2015,8 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } List deviceSubscriptions = new ArrayList<>(); - DeviceSubscriptionDTO subscription; while (rs.next()) { - subscription = new DeviceSubscriptionDTO(); + DeviceSubscriptionDTO subscription = new DeviceSubscriptionDTO(); subscription.setId(rs.getInt("ID")); subscription.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); subscription.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_AT")); 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 79c257319b..401534e1d9 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 @@ -30,6 +30,7 @@ import io.entgra.device.mgt.core.application.mgt.common.dto.GroupSubscriptionDet 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.dto.DeviceSubscriptionResponseDTO; 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; @@ -48,6 +49,7 @@ 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.DeviceDetailsDTO; 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; @@ -127,6 +129,7 @@ import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -134,6 +137,7 @@ import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; import java.util.stream.Collectors; /** @@ -1555,7 +1559,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } 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); @@ -1701,8 +1706,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } @Override - public List getGroupsSubscriptionDetailsByUUID(String uuid, String subscriptionStatus) - throws ApplicationManagementException { + public List getGroupsSubscriptionDetailsByUUID(String uuid, String subscriptionStatus, int offset, + int limit) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); String groupName; @@ -1710,11 +1715,21 @@ public class SubscriptionManagerImpl implements SubscriptionManager { try { ConnectionManagerUtil.openDBConnection(); + + ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId); + if (applicationReleaseDTO == null) { + String msg = "Couldn't find an application release for application release UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + int appReleaseId = applicationReleaseDTO.getId(); + List groupDetailsWithDevices = new ArrayList<>(); - List groupDetails = subscriptionDAO.getGroupsSubscriptionDetailsByUUID(uuid, unsubscribe, tenantId); + List groupDetails = + subscriptionDAO.getGroupsSubscriptionDetailsByAppReleaseID(appReleaseId, unsubscribe, tenantId, offset, limit); if (groupDetails == null) { - throw new ApplicationManagementException("Group details not found for UUID: " + uuid); + throw new ApplicationManagementException("Group details not found for appReleaseId: " + appReleaseId); } GroupManagementProviderService groupManagementProviderService = HelperUtil.getGroupManagementProviderService(); @@ -1723,7 +1738,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager { groupName = groupDetail.getGroupName(); // Retrieve group details and device IDs for the group using the service layer - GroupDetailsDTO groupDetailWithDevices = groupManagementProviderService.getGroupDetailsWithDeviceIds(groupName); + GroupDetailsDTO groupDetailWithDevices = + groupManagementProviderService.getGroupDetailsWithDevices(groupName, offset, limit); GroupSubscriptionDetailDTO groupDetailDTO = new GroupSubscriptionDetailDTO(); groupDetailDTO.setGroupId(groupDetailWithDevices.getGroupId()); @@ -1742,6 +1758,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { List installedDevices = new ArrayList<>(); List errorDevices = new ArrayList<>(); List newDevices = new ArrayList<>(); + List subscribedDevices = new ArrayList<>(); List deviceIds = groupDetailWithDevices.getDeviceIds(); Map statusCounts = new HashMap<>(); @@ -1749,10 +1766,18 @@ public class SubscriptionManagerImpl implements SubscriptionManager { statusCounts.put("COMPLETED", 0); statusCounts.put("ERROR", 0); statusCounts.put("NEW", 0); + statusCounts.put("SUBSCRIBED", 0); + + // Get subscribed devices if unsubscribed devices are requested + List subscribedDeviceSubscriptions = new ArrayList<>(); + if (unsubscribe) { + subscribedDeviceSubscriptions = subscriptionDAO.getSubscriptionDetailsByDeviceIds( + appReleaseId, !unsubscribe, tenantId, deviceIds); + } for (Integer deviceId : deviceIds) { - List deviceSubscriptions = subscriptionDAO.getDeviceSubscriptionsDetails( - groupDetail.getAppReleaseId(), tenantId); + List deviceSubscriptions = subscriptionDAO.getSubscriptionDetailsByDeviceIds( + groupDetail.getAppReleaseId(), unsubscribe, tenantId, deviceIds); boolean isNewDevice = true; for (DeviceSubscriptionDTO subscription : deviceSubscriptions) { if (subscription.getDeviceId() == deviceId) { @@ -1760,9 +1785,14 @@ public class SubscriptionManagerImpl implements SubscriptionManager { deviceDetail.setDeviceId(subscription.getDeviceId()); deviceDetail.setStatus(subscription.getStatus()); deviceDetail.setActionType(subscription.getActionTriggeredFrom()); + deviceDetail.setDeviceOwner(groupDetailWithDevices.getDeviceOwners().get(deviceId)); + deviceDetail.setDeviceStatus(groupDetailWithDevices.getDeviceStatuses().get(deviceId)); deviceDetail.setSubId(subscription.getId()); deviceDetail.setActionTriggeredBy(subscription.getSubscribedBy()); deviceDetail.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); + deviceDetail.setUnsubscribed(subscription.isUnsubscribed()); + deviceDetail.setUnsubscribedBy(subscription.getUnsubscribedBy()); + deviceDetail.setUnsubscribedTimestamp(subscription.getUnsubscribedTimestamp()); status = subscription.getStatus(); switch (status) { @@ -1787,10 +1817,32 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } } if (isNewDevice) { - DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); - newDeviceDetail.setDeviceId(deviceId); - newDevices.add(newDeviceDetail); - statusCounts.put("NEW", statusCounts.get("NEW") + 1); + boolean isSubscribedDevice = false; + for (DeviceSubscriptionDTO subscribedDevice : subscribedDeviceSubscriptions) { + if (subscribedDevice.getDeviceId() == deviceId) { + DeviceSubscriptionData subscribedDeviceDetail = new DeviceSubscriptionData(); + subscribedDeviceDetail.setDeviceId(subscribedDevice.getDeviceId()); + subscribedDeviceDetail.setDeviceOwner(groupDetailWithDevices.getDeviceOwners().get(deviceId)); + subscribedDeviceDetail.setDeviceStatus(groupDetailWithDevices.getDeviceStatuses().get(deviceId)); + subscribedDeviceDetail.setSubId(subscribedDevice.getId()); + subscribedDeviceDetail.setActionTriggeredBy(subscribedDevice.getSubscribedBy()); + subscribedDeviceDetail.setActionTriggeredTimestamp(subscribedDevice.getSubscribedTimestamp()); + subscribedDeviceDetail.setActionType(subscribedDevice.getActionTriggeredFrom()); + subscribedDeviceDetail.setStatus(subscribedDevice.getStatus()); + subscribedDevices.add(subscribedDeviceDetail); + statusCounts.put("SUBSCRIBED", statusCounts.get("SUBSCRIBED") + 1); + isSubscribedDevice = true; + break; + } + } + if (!isSubscribedDevice) { + DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); + newDeviceDetail.setDeviceId(deviceId); + newDeviceDetail.setDeviceOwner(groupDetailWithDevices.getDeviceOwners().get(deviceId)); + newDeviceDetail.setDeviceStatus(groupDetailWithDevices.getDeviceStatuses().get(deviceId)); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } } } @@ -1801,8 +1853,14 @@ public class SubscriptionManagerImpl implements SubscriptionManager { statusPercentages.put(entry.getKey(), percentage); } - CategorizedSubscriptionResult categorizedSubscriptionResult = - new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + CategorizedSubscriptionResult categorizedSubscriptionResult; + if (subscribedDevices.isEmpty()) { + categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + } else { + categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices, subscribedDevices); + } groupDetailDTO.setDevices(categorizedSubscriptionResult); groupDetailDTO.setStatusPercentages(statusPercentages); @@ -1828,7 +1886,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } @Override - public List getUserSubscriptionsByUUID(String uuid, String subscriptionStatus) + public List getUserSubscriptionsByUUID(String uuid, String subscriptionStatus, int offset, int limit) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); @@ -1837,11 +1895,21 @@ public class SubscriptionManagerImpl implements SubscriptionManager { try { ConnectionManagerUtil.openDBConnection(); + + ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId); + if (applicationReleaseDTO == null) { + String msg = "Couldn't find an application release for application release UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + int appReleaseId = applicationReleaseDTO.getId(); + List userSubscriptionsWithDevices = new ArrayList<>(); - List userSubscriptions = subscriptionDAO.getUserSubscriptionsByUUID(uuid, unsubscribe, tenantId); + List userSubscriptions = + subscriptionDAO.getUserSubscriptionsByAppReleaseID(appReleaseId, unsubscribe, tenantId, offset, limit); if (userSubscriptions == null) { - throw new ApplicationManagementException("User details not found for UUID: " + uuid); + throw new ApplicationManagementException("User details not found for appReleaseId: " + appReleaseId); } DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); @@ -1850,7 +1918,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager { userName = userSubscription.getUserName(); // Retrieve owner details and device IDs for the user using the service layer - OwnerWithDeviceDTO ownerDetailsWithDevices = deviceManagementProviderService.getOwnersWithDeviceIds(userName); + OwnerWithDeviceDTO ownerDetailsWithDevices = + deviceManagementProviderService.getOwnersWithDeviceIds(userName); UserSubscriptionDTO userSubscriptionDTO = new UserSubscriptionDTO(); userSubscriptionDTO.setUserName(userSubscription.getUserName()); @@ -1868,6 +1937,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { List installedDevices = new ArrayList<>(); List errorDevices = new ArrayList<>(); List newDevices = new ArrayList<>(); + List subscribedDevices = new ArrayList<>(); List deviceIds = ownerDetailsWithDevices.getDeviceIds(); Map statusCounts = new HashMap<>(); @@ -1875,21 +1945,33 @@ public class SubscriptionManagerImpl implements SubscriptionManager { statusCounts.put("COMPLETED", 0); statusCounts.put("ERROR", 0); statusCounts.put("NEW", 0); + statusCounts.put("SUBSCRIBED", 0); + + List subscribedDeviceSubscriptions = new ArrayList<>(); + if (unsubscribe) { + subscribedDeviceSubscriptions = subscriptionDAO.getSubscriptionDetailsByDeviceIds( + appReleaseId, !unsubscribe, tenantId, deviceIds); + } for (Integer deviceId : deviceIds) { - List deviceSubscriptions = subscriptionDAO.getDeviceSubscriptionsDetails( - userSubscription.getAppReleaseId(), tenantId); + List deviceSubscriptions = subscriptionDAO.getSubscriptionDetailsByDeviceIds( + userSubscription.getAppReleaseId(), unsubscribe, tenantId, deviceIds); boolean isNewDevice = true; for (DeviceSubscriptionDTO subscription : deviceSubscriptions) { if (subscription.getDeviceId() == deviceId) { DeviceSubscriptionData deviceDetail = new DeviceSubscriptionData(); deviceDetail.setDeviceId(subscription.getDeviceId()); + deviceDetail.setSubId(subscription.getId()); + deviceDetail.setDeviceOwner(ownerDetailsWithDevices.getUserName()); + deviceDetail.setDeviceStatus(ownerDetailsWithDevices.getDeviceStatus()); deviceDetail.setActionType(subscription.getActionTriggeredFrom()); deviceDetail.setStatus(subscription.getStatus()); deviceDetail.setActionType(subscription.getActionTriggeredFrom()); deviceDetail.setActionTriggeredBy(subscription.getSubscribedBy()); - deviceDetail.setSubId(subscription.getId()); deviceDetail.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); + deviceDetail.setUnsubscribed(subscription.isUnsubscribed()); + deviceDetail.setUnsubscribedBy(subscription.getUnsubscribedBy()); + deviceDetail.setUnsubscribedTimestamp(subscription.getUnsubscribedTimestamp()); status = subscription.getStatus(); switch (status) { @@ -1914,10 +1996,32 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } } if (isNewDevice) { - DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); - newDeviceDetail.setDeviceId(deviceId); - newDevices.add(newDeviceDetail); - statusCounts.put("NEW", statusCounts.get("NEW") + 1); + boolean isSubscribedDevice = false; + for (DeviceSubscriptionDTO subscribedDevice : subscribedDeviceSubscriptions) { + if (subscribedDevice.getDeviceId() == deviceId) { + DeviceSubscriptionData subscribedDeviceDetail = new DeviceSubscriptionData(); + subscribedDeviceDetail.setDeviceId(subscribedDevice.getDeviceId()); + subscribedDeviceDetail.setDeviceOwner(ownerDetailsWithDevices.getUserName()); + subscribedDeviceDetail.setDeviceStatus(ownerDetailsWithDevices.getDeviceStatus()); + subscribedDeviceDetail.setSubId(subscribedDevice.getId()); + subscribedDeviceDetail.setActionTriggeredBy(subscribedDevice.getSubscribedBy()); + subscribedDeviceDetail.setActionTriggeredTimestamp(subscribedDevice.getSubscribedTimestamp()); + subscribedDeviceDetail.setActionType(subscribedDevice.getActionTriggeredFrom()); + subscribedDeviceDetail.setStatus(subscribedDevice.getStatus()); + subscribedDevices.add(subscribedDeviceDetail); + statusCounts.put("SUBSCRIBED", statusCounts.get("SUBSCRIBED") + 1); + isSubscribedDevice = true; + break; + } + } + if (!isSubscribedDevice) { + DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); + newDeviceDetail.setDeviceId(deviceId); + newDeviceDetail.setDeviceOwner(ownerDetailsWithDevices.getUserName()); + newDeviceDetail.setDeviceStatus(ownerDetailsWithDevices.getDeviceStatus()); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } } } @@ -1928,8 +2032,14 @@ public class SubscriptionManagerImpl implements SubscriptionManager { statusPercentages.put(entry.getKey(), percentage); } - CategorizedSubscriptionResult categorizedSubscriptionResult = - new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + CategorizedSubscriptionResult categorizedSubscriptionResult; + if (subscribedDevices.isEmpty()) { + categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + } else { + categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices, subscribedDevices); + } userSubscriptionDTO.setDevices(categorizedSubscriptionResult); userSubscriptionDTO.setStatusPercentages(statusPercentages); @@ -1953,7 +2063,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } @Override - public List getRoleSubscriptionsByUUID(String uuid, String subscriptionStatus) + public List getRoleSubscriptionsByUUID(String uuid, String subscriptionStatus, int offset, int limit) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); @@ -1962,11 +2072,21 @@ public class SubscriptionManagerImpl implements SubscriptionManager { try { ConnectionManagerUtil.openDBConnection(); + + ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId); + if (applicationReleaseDTO == null) { + String msg = "Couldn't find an application release for application release UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + int appReleaseId = applicationReleaseDTO.getId(); + List roleSubscriptionsWithDevices = new ArrayList<>(); - List roleSubscriptions = subscriptionDAO.getRoleSubscriptionsByUUID(uuid, unsubscribe, tenantId); + List roleSubscriptions = + subscriptionDAO.getRoleSubscriptionsByAppReleaseID(appReleaseId, unsubscribe, tenantId, offset, limit); if (roleSubscriptions == null) { - throw new ApplicationManagementException("Role details not found for UUID: " + uuid); + throw new ApplicationManagementException("Role details not found for appReleaseId: " + appReleaseId); } DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); @@ -1987,12 +2107,14 @@ public class SubscriptionManagerImpl implements SubscriptionManager { List installedDevices = new ArrayList<>(); List errorDevices = new ArrayList<>(); List newDevices = new ArrayList<>(); + List subscribedDevices = new ArrayList<>(); Map statusCounts = new HashMap<>(); statusCounts.put("PENDING", 0); statusCounts.put("COMPLETED", 0); statusCounts.put("ERROR", 0); statusCounts.put("NEW", 0); + statusCounts.put("SUBSCRIBED", 0); List users = this.getUsersForRole(roleName); @@ -2006,10 +2128,17 @@ public class SubscriptionManagerImpl implements SubscriptionManager { List deviceIds = ownerDetailsWithDevices.getDeviceIds(); for (Integer deviceId : deviceIds) { + + List subscribedDeviceSubscriptions = new ArrayList<>(); + if (unsubscribe) { + subscribedDeviceSubscriptions = subscriptionDAO.getSubscriptionDetailsByDeviceIds( + appReleaseId, !unsubscribe, tenantId, deviceIds); + } + List deviceSubscriptions; try { - deviceSubscriptions = subscriptionDAO.getDeviceSubscriptionsDetails( - roleSubscription.getAppReleaseId(), tenantId); + deviceSubscriptions = subscriptionDAO.getSubscriptionDetailsByDeviceIds( + roleSubscription.getAppReleaseId(), unsubscribe, tenantId, deviceIds); } catch (ApplicationManagementDAOException e) { throw new ApplicationManagementException("Error retrieving device subscriptions", e); } @@ -2019,12 +2148,17 @@ public class SubscriptionManagerImpl implements SubscriptionManager { if (deviceSubscription.getDeviceId() == deviceId) { DeviceSubscriptionData deviceDetail = new DeviceSubscriptionData(); deviceDetail.setDeviceId(deviceSubscription.getDeviceId()); + deviceDetail.setDeviceOwner(ownerDetailsWithDevices.getUserName()); + deviceDetail.setDeviceStatus(ownerDetailsWithDevices.getDeviceStatus()); deviceDetail.setActionType(deviceSubscription.getActionTriggeredFrom()); deviceDetail.setStatus(deviceSubscription.getStatus()); deviceDetail.setActionType(deviceSubscription.getActionTriggeredFrom()); deviceDetail.setActionTriggeredBy(deviceSubscription.getSubscribedBy()); deviceDetail.setSubId(deviceSubscription.getId()); deviceDetail.setActionTriggeredTimestamp(deviceSubscription.getSubscribedTimestamp()); + deviceDetail.setUnsubscribed(deviceSubscription.isUnsubscribed()); + deviceDetail.setUnsubscribedBy(deviceSubscription.getUnsubscribedBy()); + deviceDetail.setUnsubscribedTimestamp(deviceSubscription.getUnsubscribedTimestamp()); status = deviceSubscription.getStatus(); switch (status) { @@ -2049,23 +2183,52 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } } if (isNewDevice) { - DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); - newDeviceDetail.setDeviceId(deviceId); - newDevices.add(newDeviceDetail); - statusCounts.put("NEW", statusCounts.get("NEW") + 1); + boolean isSubscribedDevice = false; + for (DeviceSubscriptionDTO subscribedDevice : subscribedDeviceSubscriptions) { + if (subscribedDevice.getDeviceId() == deviceId) { + DeviceSubscriptionData subscribedDeviceDetail = new DeviceSubscriptionData(); + subscribedDeviceDetail.setDeviceId(subscribedDevice.getDeviceId()); + subscribedDeviceDetail.setDeviceOwner(ownerDetailsWithDevices.getUserName()); + subscribedDeviceDetail.setDeviceStatus(ownerDetailsWithDevices.getDeviceStatus()); + subscribedDeviceDetail.setSubId(subscribedDevice.getId()); + subscribedDeviceDetail.setActionTriggeredBy(subscribedDevice.getSubscribedBy()); + subscribedDeviceDetail.setActionTriggeredTimestamp(subscribedDevice.getSubscribedTimestamp()); + subscribedDeviceDetail.setActionType(subscribedDevice.getActionTriggeredFrom()); + subscribedDeviceDetail.setStatus(subscribedDevice.getStatus()); + subscribedDevices.add(subscribedDeviceDetail); + statusCounts.put("SUBSCRIBED", statusCounts.get("SUBSCRIBED") + 1); + isSubscribedDevice = true; + break; + } + } + if (!isSubscribedDevice) { + DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); + newDeviceDetail.setDeviceId(deviceId); + newDeviceDetail.setDeviceOwner(ownerDetailsWithDevices.getUserName()); + newDeviceDetail.setDeviceStatus(ownerDetailsWithDevices.getDeviceStatus()); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } } } } - int totalDevices = pendingDevices.size() + installedDevices.size() + errorDevices.size() + newDevices.size(); + int totalDevices = + pendingDevices.size() + installedDevices.size() + errorDevices.size() + newDevices.size() + subscribedDevices.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); + CategorizedSubscriptionResult categorizedSubscriptionResult; + if (subscribedDevices.isEmpty()) { + categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + } else { + categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices, subscribedDevices); + } roleSubscriptionDTO.setDevices(categorizedSubscriptionResult); roleSubscriptionDTO.setStatusPercentages(statusPercentages); roleSubscriptionDTO.setDeviceCount(totalDevices); @@ -2101,15 +2264,327 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } @Override - public List getDeviceSubscriptionsOperationsByUUID(String uuid) throws ApplicationManagementException { + public DeviceSubscriptionResponseDTO getDeviceSubscriptionsDetailsByUUID(String uuid, String subscriptionStatus, int offset, + int limit) throws ApplicationManagementException { + + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); + + try { + ConnectionManagerUtil.openDBConnection(); + + ApplicationReleaseDTO applicationReleaseDTO = applicationReleaseDAO.getReleaseByUUID(uuid, tenantId); + if (applicationReleaseDTO == null) { + String msg = "Couldn't find an application release for application release UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + int appReleaseId = applicationReleaseDTO.getId(); + + DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); + List deviceSubscriptions = + subscriptionDAO.getDeviceSubscriptionsByAppReleaseID(appReleaseId, unsubscribe, tenantId, offset, limit); + + // empty response for no device subscriptions + if (deviceSubscriptions.isEmpty()) { + return new DeviceSubscriptionResponseDTO(0, Collections.emptyMap(), + new CategorizedSubscriptionResult(Collections.emptyList(), + Collections.emptyList(), Collections.emptyList(), Collections.emptyList())); + } + + List allDevices = + deviceManagementProviderService.getDevicesByTenantId(tenantId); + + List deviceIds = allDevices.stream() + .map(DeviceDetailsDTO::getDeviceId) + .collect(Collectors.toList()); + + Map statusCounts = new HashMap<>(); + statusCounts.put("PENDING", 0); + statusCounts.put("COMPLETED", 0); + statusCounts.put("ERROR", 0); + statusCounts.put("NEW", 0); + statusCounts.put("SUBSCRIBED", 0); + + List installedDevices = new ArrayList<>(); + List pendingDevices = new ArrayList<>(); + List errorDevices = new ArrayList<>(); + List newDevices = new ArrayList<>(); + List subscribedDevices = new ArrayList<>(); + + Map deviceSubscriptionMap = deviceSubscriptions.stream() + .collect(Collectors.toMap(DeviceSubscriptionDTO::getDeviceId, Function.identity())); + Map allDevicesMap = allDevices.stream() + .collect(Collectors.toMap(DeviceDetailsDTO::getDeviceId, Function.identity())); + + List allSubscriptionsForUnSubscribed = + subscriptionDAO.getSubscriptionDetailsByDeviceIds(appReleaseId, !unsubscribe, tenantId, deviceIds); + List allSubscriptionsForSubscribed = + subscriptionDAO.getSubscriptionDetailsByDeviceIds(appReleaseId, unsubscribe, tenantId, deviceIds); + Map allSubscriptionForUnSubscribedMap = allSubscriptionsForUnSubscribed.stream() + .collect(Collectors.toMap(DeviceSubscriptionDTO::getDeviceId, Function.identity())); + Map allSubscriptionForSubscribedMap = allSubscriptionsForSubscribed.stream() + .collect(Collectors.toMap(DeviceSubscriptionDTO::getDeviceId, Function.identity())); + + for (DeviceDetailsDTO device : allDevices) { + Integer deviceId = device.getDeviceId(); + OwnerWithDeviceDTO ownerWithDevice = + deviceManagementProviderService.getOwnerWithDeviceByDeviceId(deviceId); + if (ownerWithDevice == null) { + continue; + } + + if (deviceSubscriptionMap.containsKey(deviceId)) { + DeviceSubscriptionDTO subscription = deviceSubscriptionMap.get(deviceId); + DeviceSubscriptionData deviceDetail = new DeviceSubscriptionData(); + deviceDetail.setDeviceId(subscription.getDeviceId()); + deviceDetail.setSubId(subscription.getId()); + deviceDetail.setDeviceOwner(ownerWithDevice.getUserName()); + deviceDetail.setDeviceStatus(ownerWithDevice.getDeviceStatus()); + deviceDetail.setActionType(subscription.getActionTriggeredFrom()); + deviceDetail.setStatus(subscription.getStatus()); + deviceDetail.setActionTriggeredBy(subscription.getSubscribedBy()); + deviceDetail.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); + deviceDetail.setUnsubscribed(subscription.isUnsubscribed()); + deviceDetail.setUnsubscribedBy(subscription.getUnsubscribedBy()); + deviceDetail.setUnsubscribedTimestamp(subscription.getUnsubscribedTimestamp()); + + String 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; + } + } else if (unsubscribe && allSubscriptionForUnSubscribedMap.containsKey(deviceId) && !deviceSubscriptionMap.containsKey(deviceId)) { + // Check if the device subscription has unsubscribed status set to false + DeviceSubscriptionDTO allSubscription = allSubscriptionForUnSubscribedMap.get(deviceId); + if (!allSubscription.isUnsubscribed()) { + DeviceSubscriptionData subscribedDeviceDetail = new DeviceSubscriptionData(); + subscribedDeviceDetail.setDeviceId(allSubscription.getDeviceId()); + subscribedDeviceDetail.setDeviceOwner(ownerWithDevice.getUserName()); + subscribedDeviceDetail.setDeviceStatus(ownerWithDevice.getDeviceStatus()); + subscribedDeviceDetail.setSubId(allSubscription.getId()); + subscribedDeviceDetail.setActionTriggeredBy(allSubscription.getSubscribedBy()); + subscribedDeviceDetail.setActionTriggeredTimestamp(allSubscription.getSubscribedTimestamp()); + subscribedDeviceDetail.setActionType(allSubscription.getActionTriggeredFrom()); + subscribedDeviceDetail.setStatus(allSubscription.getStatus()); + subscribedDevices.add(subscribedDeviceDetail); + statusCounts.put("SUBSCRIBED", statusCounts.get("SUBSCRIBED") + 1); + } + } else if (unsubscribe && !allSubscriptionForUnSubscribedMap.containsKey(deviceId) && !deviceSubscriptionMap.containsKey(deviceId) + && (allDevicesMap.containsKey(deviceId))) { + DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); + newDeviceDetail.setDeviceId(deviceId); + newDeviceDetail.setDeviceOwner(ownerWithDevice.getUserName()); + newDeviceDetail.setDeviceStatus(ownerWithDevice.getDeviceStatus()); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } else if (!unsubscribe && !allSubscriptionForSubscribedMap.containsKey(deviceId) && !deviceSubscriptionMap.containsKey(deviceId) + && (allDevicesMap.containsKey(deviceId))) { + DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); + newDeviceDetail.setDeviceId(deviceId); + newDeviceDetail.setDeviceOwner(ownerWithDevice.getUserName()); + newDeviceDetail.setDeviceStatus(ownerWithDevice.getDeviceStatus()); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } + } + + int totalDevices = allDevices.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; + if (subscribedDevices.isEmpty()) { + categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + } else { + categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices, subscribedDevices); + } + DeviceSubscriptionResponseDTO deviceSubscriptionResponse = + new DeviceSubscriptionResponseDTO(totalDevices, statusPercentages, categorizedSubscriptionResult); + + return deviceSubscriptionResponse; + + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while getting device 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 device 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 DeviceSubscriptionResponseDTO getAllSubscriptionDetailsByUUID(String uuid, String subscriptionStatus, int offset, int limit) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); + + try { + ConnectionManagerUtil.openDBConnection(); + + ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId); + if (applicationReleaseDTO == null) { + String msg = "Couldn't find an application release for application release UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + int appReleaseId = applicationReleaseDTO.getId(); + + List allSubscriptions = + subscriptionDAO.getAllSubscriptionsDetails(appReleaseId, unsubscribe, tenantId, offset, limit); + + // empty response for no subscriptions + if (allSubscriptions.isEmpty()) { + return new DeviceSubscriptionResponseDTO(0, Collections.emptyMap(), + new CategorizedSubscriptionResult(Collections.emptyList(), + Collections.emptyList(), Collections.emptyList(), Collections.emptyList())); + } + + DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); + + Map allSubscriptionMap = allSubscriptions.stream() + .collect(Collectors.toMap(DeviceSubscriptionDTO::getDeviceId, Function.identity())); + + 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 allDevices = + deviceManagementProviderService.getDevicesByTenantId(tenantId); + + for (DeviceDetailsDTO device : allDevices) { + Integer deviceId = device.getDeviceId(); + OwnerWithDeviceDTO ownerWithDevice = + deviceManagementProviderService.getOwnerWithDeviceByDeviceId(deviceId); + if (ownerWithDevice == null) { + continue; + } + + if (allSubscriptionMap.containsKey(deviceId)) { + DeviceSubscriptionDTO subscription = allSubscriptionMap.get(deviceId); + DeviceSubscriptionData deviceDetail = new DeviceSubscriptionData(); + deviceDetail.setDeviceId(subscription.getDeviceId()); + deviceDetail.setSubId(subscription.getId()); + deviceDetail.setDeviceOwner(ownerWithDevice.getUserName()); + deviceDetail.setDeviceStatus(ownerWithDevice.getDeviceStatus()); + deviceDetail.setActionType(subscription.getActionTriggeredFrom()); + deviceDetail.setStatus(subscription.getStatus()); + deviceDetail.setActionTriggeredBy(subscription.getSubscribedBy()); + deviceDetail.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); + deviceDetail.setUnsubscribed(subscription.isUnsubscribed()); + deviceDetail.setUnsubscribedBy(subscription.getUnsubscribedBy()); + deviceDetail.setUnsubscribedTimestamp(subscription.getUnsubscribedTimestamp()); + + String 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; + } + } else { + DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); + newDeviceDetail.setDeviceId(deviceId); + newDeviceDetail.setDeviceOwner(ownerWithDevice.getUserName()); + newDeviceDetail.setDeviceStatus(ownerWithDevice.getDeviceStatus()); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } + } + + int totalDevices = allDevices.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); + DeviceSubscriptionResponseDTO result = + new DeviceSubscriptionResponseDTO(totalDevices, statusPercentages, categorizedSubscriptionResult); + + return result; + } 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 getDeviceSubscriptionsOperationsByUUID(String uuid, int offset, int limit) + 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(); + + ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId); + if (applicationReleaseDTO == null) { + String msg = "Couldn't find an application release for application release UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + int appReleaseId = applicationReleaseDTO.getId(); + DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); - List deviceSubscriptions = subscriptionDAO.getDeviceSubscriptionsOperationsByUUID(uuid, tenantId); + List deviceSubscriptions = + subscriptionDAO.getDeviceSubscriptionsOperationsByAppReleaseID(appReleaseId, tenantId, offset, limit); for (DeviceOperationDTO deviceSubscription : deviceSubscriptions) { Integer operationId = deviceSubscription.getOperationId(); if (operationId != null) { 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 5b2b35a29e..93c456f929 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,6 +21,7 @@ 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.DeviceDetailsDTO; import io.entgra.device.mgt.core.device.mgt.core.dto.OwnerWithDeviceDTO; import java.sql.Timestamp; @@ -99,10 +100,30 @@ public interface EnrollmentDAO { /** * Retrieves owners and the list of device IDs related to an owner. * - * @param owner the owner whose device IDs need to be retrieved + * @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 + * @return {@link OwnerWithDeviceDTO} which contains a list of devices related to a user * @throws DeviceManagementDAOException if an error occurs while fetching the data */ - OwnerWithDeviceDTO getOwnersWithDeviceIds(String owner, int tenantId) throws DeviceManagementDAOException; + OwnerWithDeviceDTO getOwnersWithDevices(String owner, int tenantId) throws DeviceManagementDAOException; + + /** + * Retrieves a list of device IDs with owners and device status. + * + * @param deviceId the deviceId of the device which user need to be retrieved + * @param tenantId the ID of the tenant + * @return {@link OwnerWithDeviceDTO} which contains a list of devices + * @throws DeviceManagementDAOException if an error occurs while fetching the data + */ + OwnerWithDeviceDTO getOwnerWithDeviceByDeviceId(int deviceId, int tenantId) + throws DeviceManagementDAOException; + + /** + * Retrieves owners and the list of device IDs with device status. + * + * @param tenantId the ID of the tenant + * @return {@link OwnerWithDeviceDTO} which contains a list of devices related to a user + * @throws DeviceManagementDAOException if an error occurs while fetching the data + */ + List getDevicesByTenantId(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 34dc3213df..5071f7a400 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 @@ -474,9 +474,12 @@ public interface GroupDAO { * * @param groupName Group name * @param tenantId Tenant ID - * @return A map containing group details and a list of device IDs + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link GroupDetailsDTO} which 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; + GroupDetailsDTO getGroupDetailsWithDevices(String groupName, int tenantId, int offset, int limit) + 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 4bc6627b3f..7f43707259 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 @@ -27,6 +27,7 @@ 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 io.entgra.device.mgt.core.device.mgt.core.dto.DeviceDetailsDTO; import java.sql.Connection; import java.sql.PreparedStatement; @@ -559,13 +560,16 @@ public abstract class AbstractEnrollmentDAOImpl implements EnrollmentDAO { } @Override - public OwnerWithDeviceDTO getOwnersWithDeviceIds(String owner, int tenantId) throws DeviceManagementDAOException { + public OwnerWithDeviceDTO getOwnersWithDevices(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 = ?"; + String sql = "SELECT DEVICE_ID, OWNER, STATUS AS DEVICE_STATUS " + + "FROM DM_ENROLMENT " + + "WHERE OWNER = ? AND TENANT_ID = ?"; try (Connection conn = this.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { @@ -586,8 +590,69 @@ public abstract class AbstractEnrollmentDAOImpl implements EnrollmentDAO { } ownerDetails.setDeviceIds(deviceIds); + ownerDetails.setDeviceStatus("DEVICE_STATUS"); ownerDetails.setDeviceCount(deviceCount); return ownerDetails; } + @Override + public OwnerWithDeviceDTO getOwnerWithDeviceByDeviceId(int deviceId, int tenantId) + throws DeviceManagementDAOException { + OwnerWithDeviceDTO deviceOwnerWithStatus = new OwnerWithDeviceDTO(); + + String sql = "SELECT DEVICE_ID, OWNER, STATUS AS DEVICE_STATUS " + + "FROM DM_ENROLMENT " + + "WHERE DEVICE_ID = ? AND TENANT_ID = ?"; + + try (Connection conn = this.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, deviceId); + stmt.setInt(2, tenantId); + + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + deviceOwnerWithStatus.setUserName(rs.getString("OWNER")); + deviceOwnerWithStatus.setDeviceStatus(rs.getString("DEVICE_STATUS")); + List deviceIds = new ArrayList<>(); + deviceIds.add(rs.getInt("DEVICE_ID")); + deviceOwnerWithStatus.setDeviceIds(deviceIds); + } + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving owner and status for device ID: " + + deviceId, e); + } + + return deviceOwnerWithStatus; + } + + @Override + public List getDevicesByTenantId(int tenantId) + throws DeviceManagementDAOException { + List devices = new ArrayList<>(); + String sql = "SELECT DEVICE_ID, OWNER, STATUS " + + "FROM DM_ENROLMENT " + + "WHERE TENANT_ID = ?"; + + try (Connection conn = this.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + + stmt.setInt(1, tenantId); + + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + DeviceDetailsDTO device = new DeviceDetailsDTO(); + device.setDeviceId(rs.getInt("DEVICE_ID")); + device.setOwner(rs.getString("OWNER")); + device.setStatus(rs.getString("STATUS")); + devices.add(device); + } + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving devices for tenant ID: " + + tenantId, e); + } + + return devices; + } } 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 476b447f1a..858df67b3c 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 @@ -1440,23 +1440,31 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { } @Override - public GroupDetailsDTO getGroupDetailsWithDeviceIds(String groupName, int tenantId) throws GroupManagementDAOException { + public GroupDetailsDTO getGroupDetailsWithDevices(String groupName, int tenantId, int offset, int limit) + 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<>(); + Map deviceOwners = new HashMap<>(); + Map deviceStatuses = new HashMap<>(); - 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 = ?"; + String sql = + "SELECT g.ID AS GROUP_ID, g.GROUP_NAME, g.OWNER, e.OWNER AS DEVICE_OWNER, e.STATUS AS DEVICE_STATUS, dgm.DEVICE_ID " + + "FROM DM_GROUP g " + + "JOIN DM_DEVICE_GROUP_MAP dgm ON g.ID = dgm.GROUP_ID " + + "JOIN DM_ENROLMENT e ON dgm.DEVICE_ID = e.DEVICE_ID " + + "WHERE g.GROUP_NAME = ? AND g.TENANT_ID = ? " + + "LIMIT ? OFFSET ?"; try (Connection conn = GroupManagementDAOFactory.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setString(1, groupName); stmt.setInt(2, tenantId); + stmt.setInt(3, limit); + stmt.setInt(4, offset); try (ResultSet rs = stmt.executeQuery()) { while (rs.next()) { @@ -1465,7 +1473,10 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { groupDetails.setGroupName(rs.getString("GROUP_NAME")); groupDetails.setGroupOwner(rs.getString("OWNER")); } - deviceIds.add(rs.getInt("DEVICE_ID")); + int deviceId = rs.getInt("DEVICE_ID"); + deviceIds.add(deviceId); + deviceOwners.put(deviceId, rs.getString("DEVICE_OWNER")); + deviceStatuses.put(deviceId, rs.getString("DEVICE_STATUS")); } } } catch (SQLException e) { @@ -1475,6 +1486,8 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { groupDetails.setDeviceIds(deviceIds); groupDetails.setDeviceCount(deviceIds.size()); + groupDetails.setDeviceOwners(deviceOwners); + groupDetails.setDeviceStatuses(deviceStatuses); 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/DeviceDetailsDTO.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/DeviceDetailsDTO.java new file mode 100644 index 0000000000..2cc5838571 --- /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/DeviceDetailsDTO.java @@ -0,0 +1,31 @@ +package io.entgra.device.mgt.core.device.mgt.core.dto; + +public class DeviceDetailsDTO { + private int deviceId; + private String owner; + private String status; + + public int getDeviceId() { + return deviceId; + } + + public void setDeviceId(int deviceId) { + this.deviceId = deviceId; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } +} 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 index 333999aeeb..4882bcbd3a 100644 --- 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 @@ -19,6 +19,7 @@ package io.entgra.device.mgt.core.device.mgt.core.dto; import java.util.List; +import java.util.Map; public class GroupDetailsDTO { private int groupId; @@ -26,6 +27,10 @@ public class GroupDetailsDTO { private String groupOwner; private List deviceIds; private int deviceCount; + private String deviceOwner; + private String deviceStatus; + private Map deviceOwners; + private Map deviceStatuses; public int getGroupId() { return groupId; @@ -67,4 +72,35 @@ public class GroupDetailsDTO { this.deviceCount = deviceCount; } + public String getDeviceOwner() { + return deviceOwner; + } + + public void setDeviceOwner(String deviceOwner) { + this.deviceOwner = deviceOwner; + } + + public String getDeviceStatus() { + return deviceStatus; + } + + public void setDeviceStatus(String deviceStatus) { + this.deviceStatus = deviceStatus; + } + + public Map getDeviceOwners() { + return deviceOwners; + } + + public void setDeviceOwners(Map deviceOwners) { + this.deviceOwners = deviceOwners; + } + + public Map getDeviceStatuses() { + return deviceStatuses; + } + + public void setDeviceStatuses(Map deviceStatuses) { + this.deviceStatuses = deviceStatuses; + } } 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 index cd3e26bfbc..5445069e8b 100644 --- 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 @@ -25,6 +25,7 @@ public class OwnerWithDeviceDTO { private String userName; private List deviceIds; private int deviceCount; + private String deviceStatus; public String getUserName() { return userName; @@ -49,4 +50,12 @@ public class OwnerWithDeviceDTO { public void setDeviceCount(int deviceCount) { this.deviceCount = deviceCount; } + + public String getDeviceStatus() { + return deviceStatus; + } + + public void setDeviceStatus(String deviceStatus) { + this.deviceStatus = deviceStatus; + } } 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 5171b03b95..c874283a76 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 @@ -127,5 +127,14 @@ public interface OperationDAO { int getDeviceActivitiesCount(ActivityPaginationRequest activityPaginationRequest) throws OperationManagementDAOException; - OperationDTO getOperationDetailsById(int operationId, int tenantId) throws OperationManagementDAOException; + /** + * This method is used to get the details of device subscriptions related to a UUID. + * + * @param operationId the operationId of the operation to be retrieved. + * @param tenantId id of the current tenant. + * @return {@link OperationDTO} which contains the details of device operations. + * @throws OperationManagementDAOException if connection establishment or SQL execution fails. + */ + 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 15751c3d89..b220cb8b77 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 @@ -2779,7 +2779,8 @@ public class GenericOperationDAOImpl implements OperationDAO { } @Override - public OperationDTO getOperationDetailsById(int operationId, int tenantId) throws OperationManagementDAOException { + public OperationDTO getOperationDetailsById(int operationId, int tenantId) + throws OperationManagementDAOException { OperationDTO operationDetails = new OperationDTO(); String sql = "SELECT ID, OPERATION_CODE, OPERATION_DETAILS, OPERATION_PROPERTIES " + 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 8e112addd3..f7b72f0275 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,7 @@ 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.DeviceDetailsDTO; 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; @@ -1080,16 +1081,33 @@ public interface DeviceManagementProviderService { * 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). + * @return {@link OwnerWithDeviceDTO} which contains a list of devices related to a user. * @throws DeviceManagementException if an error occurs while fetching owner details. */ OwnerWithDeviceDTO getOwnersWithDeviceIds(String owner) throws DeviceManagementDAOException; + /** + * Get owner details and device IDs for a given owner and tenant. + * + * @param deviceId the deviceId of the device. + * @return {@link OwnerWithDeviceDTO} which contains a list of devices related to a user. + * @throws DeviceManagementException if an error occurs while fetching owner details. + */ + OwnerWithDeviceDTO getOwnerWithDeviceByDeviceId(int deviceId) throws DeviceManagementDAOException; + + /** + * Get owner details and device IDs for a given owner and tenant. + * @param tenantId the tenant id which devices need to be retried + * @return {@link DeviceDetailsDTO} which contains devices details. + * @throws DeviceManagementException if an error occurs while fetching owner details. + */ + List getDevicesByTenantId(int tenantId) 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. + * @return {@link OperationDTO} which contains operation details. * @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 3df333cbf2..31be10ed8a 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,7 @@ 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.DeviceDetailsDTO; 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; @@ -5354,7 +5355,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv try { DeviceManagementDAOFactory.openConnection(); - ownerWithDeviceDTO = this.enrollmentDAO.getOwnersWithDeviceIds(owner, tenantId); + ownerWithDeviceDTO = this.enrollmentDAO.getOwnersWithDevices(owner, tenantId); } catch (DeviceManagementDAOException | SQLException e) { String msg = "Error occurred while retrieving device IDs for owner: " + owner; log.error(msg, e); @@ -5363,7 +5364,6 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv DeviceManagementDAOFactory.closeConnection(); } - // Add device count to the DTO if (ownerWithDeviceDTO != null) { List deviceIds = ownerWithDeviceDTO.getDeviceIds(); if (deviceIds != null) { @@ -5376,6 +5376,54 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv return ownerWithDeviceDTO; } + @Override + public OwnerWithDeviceDTO getOwnerWithDeviceByDeviceId(int deviceId) + throws DeviceManagementDAOException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + OwnerWithDeviceDTO deviceOwnerWithStatus; + + try { + DeviceManagementDAOFactory.openConnection(); + deviceOwnerWithStatus = enrollmentDAO.getOwnerWithDeviceByDeviceId(deviceId, tenantId); + } catch (DeviceManagementDAOException | SQLException e) { + String msg = "Error occurred while retrieving owner and status for device ID: " + deviceId; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + + if (deviceOwnerWithStatus != null) { + List deviceIds = deviceOwnerWithStatus.getDeviceIds(); + if (deviceIds != null) { + deviceOwnerWithStatus.setDeviceCount(deviceIds.size()); + } else { + deviceOwnerWithStatus.setDeviceCount(0); + } + } + + return deviceOwnerWithStatus; + } + + @Override + public List getDevicesByTenantId(int tenantId) + throws DeviceManagementDAOException { + List devices; + + try { + DeviceManagementDAOFactory.openConnection(); + devices = enrollmentDAO.getDevicesByTenantId(tenantId); + } catch (DeviceManagementDAOException | SQLException e) { + String msg = "Error occurred while retrieving devices for tenant ID: " + tenantId; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + + return devices; + } + @Override public OperationDTO getOperationDetailsById(int operationId) throws OperationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); 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 6c262ccf2d..fac06bfccf 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 @@ -377,9 +377,11 @@ public interface GroupManagementProviderService { * 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. + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link GroupDetailsDTO} which containing group details and a list of device IDs * @throws GroupManagementException if an error occurs while fetching group details. */ - GroupDetailsDTO getGroupDetailsWithDeviceIds(String groupName) throws GroupManagementException; + GroupDetailsDTO getGroupDetailsWithDevices(String groupName, int offset, int limit) 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 43e2a8eecc..c42feed9b8 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 @@ -1688,7 +1688,8 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid } @Override - public GroupDetailsDTO getGroupDetailsWithDeviceIds(String groupName) throws GroupManagementException { + public GroupDetailsDTO getGroupDetailsWithDevices(String groupName, int offset, int limit) + throws GroupManagementException { if (log.isDebugEnabled()) { log.debug("Retrieving group details and device IDs for group: " + groupName); } @@ -1697,7 +1698,7 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid try { GroupManagementDAOFactory.openConnection(); - groupDetailsWithDevices = this.groupDAO.getGroupDetailsWithDeviceIds(groupName, tenantId); + groupDetailsWithDevices = this.groupDAO.getGroupDetailsWithDevices(groupName, tenantId, offset, limit); } catch (GroupManagementDAOException | SQLException e) { String msg = "Error occurred while retrieving group details and device IDs for group: " + groupName; log.error(msg, e); @@ -1706,9 +1707,8 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid GroupManagementDAOFactory.closeConnection(); } - // Add device count if (groupDetailsWithDevices != null) { - List deviceIds = (List) groupDetailsWithDevices.getDeviceIds(); + List deviceIds = groupDetailsWithDevices.getDeviceIds(); if (deviceIds != null) { groupDetailsWithDevices.setDeviceCount(deviceIds.size()); } else {