From 6099c68d881412ff3dc1cb852bbacac516a00e6e Mon Sep 17 00:00:00 2001 From: Kavin Prathaban Date: Sun, 30 Jun 2024 16:06:00 +0000 Subject: [PATCH] Add application installation monitoring feature (#436) ## Purpose * Fixes https://roadmap.entgra.net/issues/11098 Co-authored-by: Kavin Prathaban Co-committed-by: Kavin Prathaban --- .../common/CategorizedSubscriptionResult.java | 103 ++ .../mgt/common/DeviceSubscriptionData.java | 98 +- .../dto/CategorizedSubscriptionCountsDTO.java | 55 + .../mgt/common/dto/DeviceOperationDTO.java | 126 ++ .../mgt/common/dto/DeviceSubscriptionDTO.java | 82 +- .../dto/DeviceSubscriptionResponseDTO.java | 60 + .../mgt/common/dto/GroupSubscriptionDTO.java | 18 + .../mgt/common/dto/RoleSubscriptionDTO.java | 98 +- .../common/dto/SubscriptionResponseDTO.java | 52 + .../mgt/common/dto/SubscriptionsDTO.java | 162 +++ .../common/services/SubscriptionManager.java | 99 +- .../mgt/core/dao/SubscriptionDAO.java | 202 ++- .../GenericSubscriptionDAOImpl.java | 803 ++++++++++++ .../core/impl/SubscriptionManagerImpl.java | 1104 ++++++++++++++++- .../application/mgt/core/BaseTestCase.java | 2 + .../device/mgt/core/dao/EnrollmentDAO.java | 31 + .../core/device/mgt/core/dao/GroupDAO.java | 15 +- .../dao/impl/AbstractEnrollmentDAOImpl.java | 113 +- .../core/dao/impl/AbstractGroupDAOImpl.java | 90 +- .../device/mgt/core/dto/DeviceDetailsDTO.java | 49 + .../device/mgt/core/dto/GroupDetailsDTO.java | 115 ++ .../device/mgt/core/dto/OperationDTO.java | 72 ++ .../mgt/core/dto/OperationResponseDTO.java} | 31 +- .../mgt/core/dto/OwnerWithDeviceDTO.java | 70 ++ .../core/operation/mgt/dao/OperationDAO.java | 13 + .../mgt/dao/impl/GenericOperationDAOImpl.java | 76 +- .../mgt/dao/util/OperationDAOUtil.java | 53 + .../DeviceManagementProviderService.java | 38 + .../DeviceManagementProviderServiceImpl.java | 110 ++ .../GroupManagementProviderService.java | 13 + .../GroupManagementProviderServiceImpl.java | 36 +- .../type/template/BaseExtensionsTest.java | 2 + 32 files changed, 3869 insertions(+), 122 deletions(-) create mode 100644 components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java create mode 100644 components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/CategorizedSubscriptionCountsDTO.java create mode 100644 components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/DeviceOperationDTO.java create mode 100644 components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/DeviceSubscriptionResponseDTO.java create mode 100644 components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/SubscriptionResponseDTO.java create mode 100644 components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/SubscriptionsDTO.java create mode 100644 components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/DeviceDetailsDTO.java create mode 100644 components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/GroupDetailsDTO.java create mode 100644 components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OperationDTO.java rename 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 => device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OperationResponseDTO.java} (55%) create mode 100644 components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OwnerWithDeviceDTO.java diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java new file mode 100644 index 0000000000..28cc436115 --- /dev/null +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.application.mgt.common; + +import java.util.List; + +public class CategorizedSubscriptionResult { + private List installedDevices; + private List pendingDevices; + private List errorDevices; + private List newDevices; + private List subscribedDevices; + + public CategorizedSubscriptionResult(List installedDevices, + List pendingDevices, + List errorDevices) { + this.installedDevices = installedDevices; + this.pendingDevices = pendingDevices; + this.errorDevices = errorDevices; + this.newDevices = null; + this.subscribedDevices = null; + } + + public CategorizedSubscriptionResult(List installedDevices, + List pendingDevices, + List errorDevices, + List newDevices) { + this.installedDevices = installedDevices; + 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() { + return installedDevices; + } + + public void setInstalledDevices(List installedDevices) { + this.installedDevices = installedDevices; + } + + public List getPendingDevices() { + return pendingDevices; + } + + public void setPendingDevices(List pendingDevices) { + this.pendingDevices = pendingDevices; + } + + public List getErrorDevices() { + return errorDevices; + } + + public void setErrorDevices(List errorDevices) { + this.errorDevices = errorDevices; + } + + public List getNewDevices() { + return newDevices; + } + + 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 55f2ec9edc..465db48c53 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/DeviceSubscriptionData.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/DeviceSubscriptionData.java @@ -26,12 +26,20 @@ public class DeviceSubscriptionData { private int subId; private String action; - private long actionTriggeredTimestamp; + private Timestamp actionTriggeredTimestamp; + private String actionTriggeredFrom; private String actionTriggeredBy; private String actionType; private String status; private Device device; private String currentInstalledVersion; + private int deviceId; + private String deviceOwner; + private String deviceStatus; + private boolean unsubscribed; + private String unsubscribedBy; + private Timestamp unsubscribedTimestamp; + private String deviceName; public String getAction() { return action; @@ -41,14 +49,6 @@ public class DeviceSubscriptionData { this.action = action; } - public long getActionTriggeredTimestamp() { - return actionTriggeredTimestamp; - } - - public void setActionTriggeredTimestamp(long actionTriggeredTimestamp) { - this.actionTriggeredTimestamp = actionTriggeredTimestamp; - } - public String getActionTriggeredBy() { return actionTriggeredBy; } @@ -81,9 +81,13 @@ public class DeviceSubscriptionData { this.device = device; } - public String getCurrentInstalledVersion() { return currentInstalledVersion; } + public String getCurrentInstalledVersion() { + return currentInstalledVersion; + } - public void setCurrentInstalledVersion(String currentInstalledVersion) { this.currentInstalledVersion = currentInstalledVersion; } + public void setCurrentInstalledVersion(String currentInstalledVersion) { + this.currentInstalledVersion = currentInstalledVersion; + } public int getSubId() { return subId; @@ -92,4 +96,76 @@ public class DeviceSubscriptionData { public void setSubId(int subId) { this.subId = subId; } + + public int getDeviceId() { + return deviceId; + } + + public void setDeviceId(int deviceId) { + this.deviceId = deviceId; + } + + public String getActionTriggeredFrom() { + return actionTriggeredFrom; + } + + public void setActionTriggeredFrom(String actionTriggeredFrom) { + this.actionTriggeredFrom = actionTriggeredFrom; + } + + public Timestamp getActionTriggeredTimestamp() { + return actionTriggeredTimestamp; + } + + public void setActionTriggeredTimestamp(Timestamp actionTriggeredTimestamp) { + this.actionTriggeredTimestamp = actionTriggeredTimestamp; + } + + 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; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } } 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/CategorizedSubscriptionCountsDTO.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/CategorizedSubscriptionCountsDTO.java new file mode 100644 index 0000000000..2ee5bb3cb0 --- /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/CategorizedSubscriptionCountsDTO.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.application.mgt.common.dto; + +public class CategorizedSubscriptionCountsDTO { + private String subscriptionType; + private int subscriptionCount; + private int unsubscriptionCount; + + public CategorizedSubscriptionCountsDTO(String subscriptionType, int subscriptionCount, int unsubscriptionCount) { + this.subscriptionType = subscriptionType; + this.subscriptionCount = subscriptionCount; + this.unsubscriptionCount = unsubscriptionCount; + } + + public String getSubscriptionType() { + return subscriptionType; + } + + public void setSubscriptionType(String subscriptionType) { + this.subscriptionType = subscriptionType; + } + + public int getSubscriptionCount() { + return subscriptionCount; + } + + public void setSubscriptionCount(int subscriptionCount) { + this.subscriptionCount = subscriptionCount; + } + + public int getUnsubscriptionCount() { + return unsubscriptionCount; + } + + public void setUnsubscriptionCount(int unsubscriptionCount) { + this.unsubscriptionCount = unsubscriptionCount; + } +} diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/DeviceOperationDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/DeviceOperationDTO.java new file mode 100644 index 0000000000..75699431a2 --- /dev/null +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/DeviceOperationDTO.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.application.mgt.common.dto; + +import io.entgra.device.mgt.core.device.mgt.core.dto.OperationResponseDTO; + +import java.sql.Timestamp; +import java.util.List; + +public class DeviceOperationDTO { + private int deviceId; + private String uuid; + private String status; + private int operationId; + private String actionTriggeredFrom; + private Timestamp actionTriggeredAt; + private int appReleaseId; + private String operationCode; + private Object operationDetails; + private Object operationProperties; + private List operationResponses; + + public int getDeviceId() { + return deviceId; + } + + public void setDeviceId(int deviceId) { + this.deviceId = deviceId; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public int getOperationId() { + return operationId; + } + + public void setOperationId(int operationId) { + this.operationId = operationId; + } + + public String getActionTriggeredFrom() { + return actionTriggeredFrom; + } + + public void setActionTriggeredFrom(String actionTriggeredFrom) { + this.actionTriggeredFrom = actionTriggeredFrom; + } + + public Timestamp getActionTriggeredAt() { + return actionTriggeredAt; + } + + public void setActionTriggeredAt(Timestamp actionTriggeredAt) { + this.actionTriggeredAt = actionTriggeredAt; + } + + public int getAppReleaseId() { + return appReleaseId; + } + + public void setAppReleaseId(int appReleaseId) { + this.appReleaseId = appReleaseId; + } + + public String getOperationCode() { + return operationCode; + } + + public void setOperationCode(String operationCode) { + this.operationCode = operationCode; + } + + public Object getOperationDetails() { + return operationDetails; + } + + public void setOperationDetails(Object operationDetails) { + this.operationDetails = operationDetails; + } + + public Object getOperationProperties() { + return operationProperties; + } + + public void setOperationProperties(Object operationProperties) { + this.operationProperties = operationProperties; + } + + public List getOperationResponses() { + return operationResponses; + } + + public void setOperationResponses(List operationResponses) { + this.operationResponses = operationResponses; + } +} 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/DeviceSubscriptionDTO.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/DeviceSubscriptionDTO.java index 9a30ec07c2..3306256b19 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/DeviceSubscriptionDTO.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/DeviceSubscriptionDTO.java @@ -31,44 +31,94 @@ public class DeviceSubscriptionDTO { private String actionTriggeredFrom; private String status; private int deviceId; + private int appReleaseId; + private String appUuid; - public int getId() { return id; } + public int getId() { + return id; + } - public void setId(int id) { this.id = id; } + public void setId(int id) { + this.id = id; + } - public String getSubscribedBy() { return subscribedBy; } + public String getSubscribedBy() { + return subscribedBy; + } - public void setSubscribedBy(String subscribedBy) { this.subscribedBy = subscribedBy; } + public void setSubscribedBy(String subscribedBy) { + this.subscribedBy = subscribedBy; + } - public Timestamp getSubscribedTimestamp() { return subscribedTimestamp; } + public Timestamp getSubscribedTimestamp() { + return subscribedTimestamp; + } public void setSubscribedTimestamp(Timestamp subscribedTimestamp) { this.subscribedTimestamp = subscribedTimestamp; } - public boolean isUnsubscribed() { return isUnsubscribed; } + public boolean isUnsubscribed() { + return isUnsubscribed; + } - public void setUnsubscribed(boolean unsubscribed) { isUnsubscribed = unsubscribed; } + public void setUnsubscribed(boolean unsubscribed) { + isUnsubscribed = unsubscribed; + } - public String getUnsubscribedBy() { return unsubscribedBy; } + public String getUnsubscribedBy() { + return unsubscribedBy; + } - public void setUnsubscribedBy(String unsubscribedBy) { this.unsubscribedBy = unsubscribedBy; } + public void setUnsubscribedBy(String unsubscribedBy) { + this.unsubscribedBy = unsubscribedBy; + } - public Timestamp getUnsubscribedTimestamp() { return unsubscribedTimestamp; } + public Timestamp getUnsubscribedTimestamp() { + return unsubscribedTimestamp; + } public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) { this.unsubscribedTimestamp = unsubscribedTimestamp; } - public String getActionTriggeredFrom() { return actionTriggeredFrom; } + public String getActionTriggeredFrom() { + return actionTriggeredFrom; + } + + public void setActionTriggeredFrom(String actionTriggeredFrom) { + this.actionTriggeredFrom = actionTriggeredFrom; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public int getDeviceId() { + return deviceId; + } - public void setActionTriggeredFrom(String actionTriggeredFrom) { this.actionTriggeredFrom = actionTriggeredFrom; } + public void setDeviceId(int deviceId) { + this.deviceId = deviceId; + } - public String getStatus() { return status; } + public int getAppReleaseId() { + return appReleaseId; + } - public void setStatus(String status) { this.status = status; } + public void setAppReleaseId(int appReleaseId) { + this.appReleaseId = appReleaseId; + } - public int getDeviceId() { return deviceId; } + public String getAppUuid() { + return appUuid; + } - public void setDeviceId(int deviceId) { this.deviceId = deviceId; } + public void setAppUuid(String appUuid) { + this.appUuid = appUuid; + } } 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..5d132bfd37 --- /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,60 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.application.mgt.common.dto; + +import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; + +import java.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/GroupSubscriptionDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDTO.java index 3d9e6dfd2c..76a7b39d2d 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDTO.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDTO.java @@ -22,6 +22,7 @@ import java.sql.Timestamp; public class GroupSubscriptionDTO { private int id; + private String groupName; private String subscribedBy; private Timestamp subscribedTimestamp; private boolean isUnsubscribed; @@ -29,6 +30,7 @@ public class GroupSubscriptionDTO { private Timestamp unsubscribedTimestamp; private String subscribedFrom; private int groupdId; + private int appReleaseId; public int getId() { return id; } @@ -61,4 +63,20 @@ public class GroupSubscriptionDTO { public int getGroupdId() { return groupdId; } public void setGroupdId(int groupdId) { this.groupdId = groupdId; } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public int getAppReleaseId() { + return appReleaseId; + } + + public void setAppReleaseId(int appReleaseId) { + this.appReleaseId = appReleaseId; + } } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/RoleSubscriptionDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/RoleSubscriptionDTO.java index 869ed1fd6d..b8139181de 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/RoleSubscriptionDTO.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/RoleSubscriptionDTO.java @@ -18,51 +18,115 @@ package io.entgra.device.mgt.core.application.mgt.common.dto; +import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; + import java.sql.Timestamp; +import java.util.Map; public class RoleSubscriptionDTO { - private int id; private String subscribedBy; private Timestamp subscribedTimestamp; private boolean isUnsubscribed; + private boolean unsubscribed; private String unsubscribedBy; private Timestamp unsubscribedTimestamp; private String subscribedFrom; private String roleName; + private int appReleaseId; + private int deviceCount; + private Map statusPercentages; + private CategorizedSubscriptionResult devices; - public int getId() { return id; } - - public void setId(int id) { this.id = id; } - - public String getSubscribedBy() { return subscribedBy; } + public String getSubscribedBy() { + return subscribedBy; + } - public void setSubscribedBy(String subscribedBy) { this.subscribedBy = subscribedBy; } + public void setSubscribedBy(String subscribedBy) { + this.subscribedBy = subscribedBy; + } - public Timestamp getSubscribedTimestamp() { return subscribedTimestamp; } + public Timestamp getSubscribedTimestamp() { + return subscribedTimestamp; + } public void setSubscribedTimestamp(Timestamp subscribedTimestamp) { this.subscribedTimestamp = subscribedTimestamp; } - public boolean isUnsubscribed() { return isUnsubscribed; } + public boolean getUnsubscribed() { + return unsubscribed; + } - public void setUnsubscribed(boolean unsubscribed) { isUnsubscribed = unsubscribed; } + public void setUnsubscribed(boolean unsubscribed) { + this.unsubscribed = unsubscribed; + } - public String getUnsubscribedBy() { return unsubscribedBy; } + public boolean isUnsubscribed() { + return isUnsubscribed; + } - public void setUnsubscribedBy(String unsubscribedBy) { this.unsubscribedBy = unsubscribedBy; } + public String getUnsubscribedBy() { + return unsubscribedBy; + } + + public void setUnsubscribedBy(String unsubscribedBy) { + this.unsubscribedBy = unsubscribedBy; + } - public Timestamp getUnsubscribedTimestamp() { return unsubscribedTimestamp; } + public Timestamp getUnsubscribedTimestamp() { + return unsubscribedTimestamp; + } public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) { this.unsubscribedTimestamp = unsubscribedTimestamp; } - public String getSubscribedFrom() { return subscribedFrom; } + public String getSubscribedFrom() { + return subscribedFrom; + } + + public void setSubscribedFrom(String subscribedFrom) { + this.subscribedFrom = subscribedFrom; + } + + public String getRoleName() { + return roleName; + } - public void setSubscribedFrom(String subscribedFrom) { this.subscribedFrom = subscribedFrom; } + public void setRoleName(String roleName) { + this.roleName = roleName; + } - public String getRoleName() { return roleName; } + public int getAppReleaseId() { + return appReleaseId; + } + + public void setAppReleaseId(int appReleaseId) { + this.appReleaseId = appReleaseId; + } + + public int getDeviceCount() { + return deviceCount; + } + + public void setDeviceCount(int deviceCount) { + this.deviceCount = deviceCount; + } + + public Map getStatusPercentages() { + return statusPercentages; + } + + public void setStatusPercentages(Map statusPercentages) { + this.statusPercentages = statusPercentages; + } + + public CategorizedSubscriptionResult getDevices() { + return devices; + } + + public void setDevices(CategorizedSubscriptionResult devices) { + this.devices = devices; + } - public void setRoleName(String roleName) { this.roleName = roleName; } } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/SubscriptionResponseDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/SubscriptionResponseDTO.java new file mode 100644 index 0000000000..03967ec94d --- /dev/null +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/SubscriptionResponseDTO.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.application.mgt.common.dto; + +import java.util.List; + +public class SubscriptionResponseDTO { + + private String UUID; + private List subscriptions; + private List DevicesOperations; + + public String getUUID() { + return UUID; + } + + public void setUUID(String UUID) { + this.UUID = UUID; + } + + public List getDevicesOperations() { + return DevicesOperations; + } + + public void setDevicesOperations(List devicesOperations) { + DevicesOperations = devicesOperations; + } + + public List getSubscriptions() { + return subscriptions; + } + + public void setSubscriptions(List subscriptions) { + this.subscriptions = subscriptions; + } +} 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/SubscriptionsDTO.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/SubscriptionsDTO.java new file mode 100644 index 0000000000..cb127696e3 --- /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/SubscriptionsDTO.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.application.mgt.common.dto; + +import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; + +import java.sql.Timestamp; +import java.util.Map; + +public class SubscriptionsDTO { + private int id; + private String owner; + private String name; + private String subscribedBy; + private Timestamp subscribedTimestamp; + private boolean unsubscribed; + private String unsubscribedBy; + private Timestamp unsubscribedTimestamp; + private String subscribedFrom; + private int appReleaseId; + private int deviceCount; + private String deviceOwner; + private String deviceStatus; + private Map statusPercentages; + private CategorizedSubscriptionResult devices; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSubscribedBy() { + return subscribedBy; + } + + public void setSubscribedBy(String subscribedBy) { + this.subscribedBy = subscribedBy; + } + + public Timestamp getSubscribedTimestamp() { + return subscribedTimestamp; + } + + public void setSubscribedTimestamp(Timestamp subscribedTimestamp) { + this.subscribedTimestamp = subscribedTimestamp; + } + + public String getUnsubscribedBy() { + return unsubscribedBy; + } + + public void setUnsubscribedBy(String unsubscribedBy) { + this.unsubscribedBy = unsubscribedBy; + } + + public Timestamp getUnsubscribedTimestamp() { + return unsubscribedTimestamp; + } + + public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) { + this.unsubscribedTimestamp = unsubscribedTimestamp; + } + + public String getSubscribedFrom() { + return subscribedFrom; + } + + public void setSubscribedFrom(String subscribedFrom) { + this.subscribedFrom = subscribedFrom; + } + + public int getAppReleaseId() { + return appReleaseId; + } + + public void setAppReleaseId(int appReleaseId) { + this.appReleaseId = appReleaseId; + } + + public int getDeviceCount() { + return deviceCount; + } + + public void setDeviceCount(int deviceCount) { + this.deviceCount = deviceCount; + } + + public 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 getStatusPercentages() { + return statusPercentages; + } + + public void setStatusPercentages(Map statusPercentages) { + this.statusPercentages = statusPercentages; + } + + public CategorizedSubscriptionResult getDevices() { + return devices; + } + + public void setDevices(CategorizedSubscriptionResult devices) { + this.devices = devices; + } + + public boolean getUnsubscribed() { + return unsubscribed; + } + + public void setUnsubscribed(boolean unsubscribed) { + this.unsubscribed = unsubscribed; + } +} diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java index e06a17cb9b..1cbeda5f08 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java @@ -18,11 +18,16 @@ package io.entgra.device.mgt.core.application.mgt.common.services; import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstallResponse; +import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus; +import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType; +import io.entgra.device.mgt.core.application.mgt.common.dto.CategorizedSubscriptionCountsDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.SubscriptionsDTO; +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.application.mgt.common.SubscriptionType; import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier; import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.PaginationResult; @@ -194,7 +199,7 @@ public interface SubscriptionManager { * application release for given UUID, if an error occurred while getting device details of subscribed device ids, * if an error occurred while getting subscription details of given application release UUID. */ - PaginationResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, String action, String installedVersion) + CategorizedSubscriptionResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, String action, String installedVersion) throws ApplicationManagementException; /*** @@ -217,4 +222,94 @@ public interface SubscriptionManager { * @throws {@link SubscriptionManagementException} Exception of the subscription management */ Activity getOperationAppDetails(String id) throws SubscriptionManagementException; + + /** + * Retrieves the group details associated with a given app release UUID. + * + * @param uuid the UUID of the app release + * @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 SubscriptionsDTO} which contains the details of subscriptions. + * @throws ApplicationManagementException if an error occurs while fetching the group details + */ + 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 + * @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 SubscriptionsDTO} which contains the details of subscriptions. + * @throws ApplicationManagementException if an error occurs while fetching the user details + */ + 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 + * @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 SubscriptionsDTO} which contains the details of 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 + */ + 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 deviceId the deviceId of the device that need to get operation details. + * @param uuid the UUID of the application release. + * @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 getSubscriptionOperationsByUUIDAndDeviceID(int deviceId, String uuid, int offset, int limit) + throws ApplicationManagementException; + + /** + * This method is responsible for retrieving device counts details related to the given UUID. + * + * @param uuid the UUID of the application release. + * @return {@link List} which contains counts of subscriptions + and unsubscription for each subscription type. + * @throws SubscriptionManagementException if there is an error while fetching the details. + */ + List getSubscriptionCountsByUUID(String uuid) + throws ApplicationManagementException; + } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/SubscriptionDAO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/SubscriptionDAO.java index 3213db3484..88465a4533 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/SubscriptionDAO.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/SubscriptionDAO.java @@ -18,8 +18,11 @@ package io.entgra.device.mgt.core.application.mgt.core.dao; import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus; -import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.GroupSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.SubscriptionsDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceOperationDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.exception.SubscriptionManagementException; import io.entgra.device.mgt.core.application.mgt.core.exception.ApplicationManagementDAOException; @@ -312,4 +315,201 @@ public interface SubscriptionDAO { * @throws ApplicationManagementDAOException thrown if an error occurs while deleting data */ void deleteScheduledSubscriptionByTenant(int tenantId) throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of group 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 GroupSubscriptionDTO} which contains the details of group subscriptions. + * @throws ApplicationManagementDAOException if connection establishment fails. + */ + 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 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 SubscriptionsDTO} which contains the details of subscriptions. + * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. + */ + 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 SubscriptionsDTO} which contains the details of 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 device 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 DeviceSubscriptionDTO} which contains the details of device subscriptions. + * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. + */ + 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 appReleaseId the appReleaseId of the application release. + * @param deviceId the deviceId of the device that need to get operation details. + * @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 getSubscriptionOperationsByAppReleaseIDAndDeviceID(int appReleaseId, int deviceId, 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. + * @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 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; + + /** + * This method is used to get the counts of all subscription types related to a UUID. + * + * @param appReleaseId the appReleaseId of the application release. + * @param tenantId id of the current tenant. + * @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; + + /** + * This method is used to get the counts of all unsubscription types related to a UUID. + * + * @param appReleaseId the UUID of the application release. + * @param tenantId id of the current tenant. + * @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; + + /** + * This method is used to get the counts of device subscriptions related to a UUID. + * + * @param appReleaseId the UUID of the application release. + * @param tenantId id of the current tenant. + * @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; + + /** + * This method is used to get the counts of device unsubscription related to a UUID. + * + * @param appReleaseId the UUID of the application release. + * @param tenantId id of the current tenant. + * @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; + + /** + * This method is used to get the counts of group subscriptions related to a UUID. + * + * @param appReleaseId the UUID of the application release. + * @param tenantId id of the current tenant. + * @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; + + /** + * This method is used to get the counts of group unsubscription related to a UUID. + * + * @param appReleaseId the UUID of the application release. + * @param tenantId id of the current tenant. + * @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; + + /** + * This method is used to get the counts of role subscriptions related to a UUID. + * + * @param appReleaseId the UUID of the application release. + * @param tenantId id of the current tenant. + * @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; + + /** + * This method is used to get the counts of role unsubscription related to a UUID. + * + * @param appReleaseId the UUID of the application release. + * @param tenantId id of the current tenant. + * @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; + + /** + * This method is used to get the counts of user subscriptions related to a UUID. + * + * @param appReleaseId the UUID of the application release. + * @param tenantId id of the current tenant. + * @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; + + /** + * This method is used to get the counts of user unsubscription related to a UUID. + * + * @param appReleaseId the UUID of the application release. + * @param tenantId id of the current tenant. + * @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; } 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 cc3a289a4b..8737c99d7c 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java @@ -17,6 +17,9 @@ */ package io.entgra.device.mgt.core.application.mgt.core.dao.impl.subscription; +import io.entgra.device.mgt.core.application.mgt.common.dto.GroupSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceOperationDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.SubscriptionsDTO; import io.entgra.device.mgt.core.application.mgt.core.dao.SubscriptionDAO; import io.entgra.device.mgt.core.application.mgt.core.dao.impl.AbstractDAOImpl; import io.entgra.device.mgt.core.application.mgt.core.exception.UnexpectedServerErrorException; @@ -44,6 +47,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); @@ -1635,4 +1639,803 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc throw new ApplicationManagementDAOException(msg, e); } } + + @Override + 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 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 " + + "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.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()) { + groupDetail = new GroupSubscriptionDTO(); + groupDetail.setGroupName(rs.getString("GROUP_NAME")); + groupDetail.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); + groupDetail.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_TIMESTAMP")); + groupDetail.setUnsubscribed(rs.getBoolean("UNSUBSCRIBED")); + groupDetail.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY")); + groupDetail.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_TIMESTAMP")); + groupDetail.setAppReleaseId(rs.getInt("AP_APP_RELEASE_ID")); + + groupDetails.add(groupDetail); + } + } + return groupDetails; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get groups for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting groups for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List 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 " + + "FROM AP_USER_SUBSCRIPTION US " + + "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.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()) { + SubscriptionsDTO userSubscription; + userSubscription = new SubscriptionsDTO(); + userSubscription.setName(rs.getString("USER_NAME")); + userSubscription.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); + userSubscription.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_TIMESTAMP")); + userSubscription.setUnsubscribed(rs.getBoolean("UNSUBSCRIBED")); + userSubscription.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY")); + userSubscription.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_TIMESTAMP")); + userSubscription.setAppReleaseId(rs.getInt("AP_APP_RELEASE_ID")); + + userSubscriptions.add(userSubscription); + } + } + return userSubscriptions; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get user subscriptions for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting user subscriptions for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List 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 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 " + + "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.setInt(1, appReleaseId); + ps.setBoolean(2, unsubscribe); + ps.setInt(3, tenantId); + ps.setInt(4, limit); + ps.setInt(5, offset); + try (ResultSet rs = ps.executeQuery()) { + SubscriptionsDTO roleSubscription; + while (rs.next()) { + roleSubscription = new SubscriptionsDTO(); + roleSubscription.setName(rs.getString("ROLE_NAME")); + roleSubscription.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); + roleSubscription.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_TIMESTAMP")); + roleSubscription.setUnsubscribed(rs.getBoolean("UNSUBSCRIBED")); + roleSubscription.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY")); + roleSubscription.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_TIMESTAMP")); + roleSubscription.setAppReleaseId(rs.getInt("AP_APP_RELEASE_ID")); + + roleSubscriptions.add(roleSubscription); + } + } + return roleSubscriptions; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get role subscriptions for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting role subscriptions for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List 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 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 getSubscriptionOperationsByAppReleaseIDAndDeviceID( + int appReleaseId, int deviceId, 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 and DeviceID."); + } + try { + Connection conn = this.getDBConnection(); + List deviceSubscriptions = new ArrayList<>(); + String sql = "SELECT " + + " ads.DM_DEVICE_ID, " + + " aasom.OPERATION_ID, " + + " ads.STATUS, " + + " ads.ACTION_TRIGGERED_FROM, " + + " ads.SUBSCRIBED_TIMESTAMP AS ACTION_TRIGGERED_AT, " + + " ads.AP_APP_RELEASE_ID " + + "FROM AP_APP_SUB_OP_MAPPING aasom " + + "JOIN AP_DEVICE_SUBSCRIPTION ads " + + "ON aasom.AP_DEVICE_SUBSCRIPTION_ID = ads.ID " + + "WHERE ads.AP_APP_RELEASE_ID = ? " + + "AND ads.DM_DEVICE_ID = ? " + + "AND ads.TENANT_ID = ? " + + "LIMIT ? OFFSET ?"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, deviceId); + ps.setInt(3, tenantId); + ps.setInt(4, limit); + ps.setInt(5, offset); + try (ResultSet rs = ps.executeQuery()) { + DeviceOperationDTO deviceSubscription; + while (rs.next()) { + deviceSubscription = new DeviceOperationDTO(); + deviceSubscription.setDeviceId(rs.getInt("DM_DEVICE_ID")); + deviceSubscription.setStatus(rs.getString("STATUS")); + deviceSubscription.setOperationId(rs.getInt("OPERATION_ID")); + deviceSubscription.setActionTriggeredFrom(rs.getString("ACTION_TRIGGERED_FROM")); + deviceSubscription.setActionTriggeredAt(rs.getTimestamp("ACTION_TRIGGERED_AT")); + deviceSubscription.setAppReleaseId(rs.getInt("AP_APP_RELEASE_ID")); + + deviceSubscriptions.add(deviceSubscription); + } + } + } + return deviceSubscriptions; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get device subscriptions for the given AppReleaseID and DeviceID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting device subscriptions for the given AppReleaseID and DeviceID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + 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, " + + "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=? " + + "ORDER BY " + subscriptionStatusTime + " DESC " + + "LIMIT ? OFFSET ?"; + + try { + Connection conn = this.getDBConnection(); + 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()) { + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved device subscriptions for application release id " + + appReleaseId); + } + List deviceSubscriptions = 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")); + + deviceSubscriptions.add(subscription); + } + return deviceSubscriptions; + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection for getting device subscription for " + + "application Id: " + appReleaseId + "."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while while running SQL to get device subscription data for application ID: " + appReleaseId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public int getAllSubscriptionCount(int appReleaseId, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting all subscriptions count for the application appReleaseId " + appReleaseId + + " from the database"); + } + try { + Connection conn = this.getDBConnection(); + String sql = "SELECT COUNT(*) AS count " + + "FROM AP_DEVICE_SUBSCRIPTION " + + "WHERE AP_APP_RELEASE_ID = ? " + + "AND TENANT_ID = ? " + + "AND UNSUBSCRIBED = FALSE"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + return rs.getInt("count"); + } + return 0; + } + } catch (SQLException e) { + String msg = "Error occurred while running SQL to get all subscriptions count for application appReleaseId: " + + appReleaseId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection for getting all subscriptions count for appReleaseId: " + + appReleaseId + "."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public int getAllUnsubscriptionCount(int appReleaseId, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting all unsubscription count for the application appReleaseId " + appReleaseId + + " from the database"); + } + try { + Connection conn = this.getDBConnection(); + String sql = "SELECT COUNT(*) AS count " + + "FROM AP_DEVICE_SUBSCRIPTION " + + "WHERE AP_APP_RELEASE_ID = ? " + + "AND TENANT_ID = ? " + + "AND UNSUBSCRIBED = TRUE"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + return rs.getInt("count"); + } + return 0; + } + } catch (SQLException e) { + String msg = "Error occurred while running SQL to get all unsubscription count for application appReleaseId: " + + appReleaseId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection for getting all unsubscription count for appReleaseId: " + + appReleaseId + "."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public int getDeviceSubscriptionCount(int appReleaseId, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting device subscriptions count for the application appReleaseId " + appReleaseId + + " from the database"); + } + try { + Connection conn = this.getDBConnection(); + String sql = "SELECT COUNT(*) AS count " + + "FROM AP_DEVICE_SUBSCRIPTION " + + "WHERE AP_APP_RELEASE_ID = ? " + + "AND TENANT_ID = ? " + + "AND UNSUBSCRIBED = FALSE " + + "AND ACTION_TRIGGERED_FROM = 'DEVICE'"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + return rs.getInt("count"); + } + return 0; + } + } catch (SQLException e) { + String msg = "Error occurred while running SQL to get device subscriptions count for application appReleaseId: " + + appReleaseId; + 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 count for appReleaseId: " + + appReleaseId + "."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public int getDeviceUnsubscriptionCount(int appReleaseId, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting device unsubscriptions count for the application appReleaseId " + appReleaseId + + " from the database"); + } + try { + Connection conn = this.getDBConnection(); + String sql = "SELECT COUNT(*) AS count " + + "FROM AP_DEVICE_SUBSCRIPTION " + + "WHERE AP_APP_RELEASE_ID = ? " + + "AND TENANT_ID = ? " + + "AND UNSUBSCRIBED = TRUE " + + "AND ACTION_TRIGGERED_FROM = 'DEVICE'"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + return rs.getInt("count"); + } + return 0; + } + } catch (SQLException e) { + String msg = "Error occurred while running SQL to get device unsubscription count for application appReleaseId: " + + appReleaseId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection for getting device unsubscription count for appReleaseId: " + + appReleaseId + "."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public int getGroupSubscriptionCount(int appReleaseId, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting group subscriptions count for the application appReleaseId " + appReleaseId + + " from the database"); + } + try { + Connection conn = this.getDBConnection(); + String sql = "SELECT COUNT(*) AS count " + + "FROM AP_GROUP_SUBSCRIPTION " + + "WHERE AP_APP_RELEASE_ID = ? " + + "AND TENANT_ID = ? " + + "AND UNSUBSCRIBED = FALSE"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + return rs.getInt("count"); + } + return 0; + } + } catch (SQLException e) { + String msg = "Error occurred while running SQL to get group subscriptions count for application appReleaseId: " + + appReleaseId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection for getting group subscriptions count for appReleaseId: " + + appReleaseId + "."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public int getGroupUnsubscriptionCount(int appReleaseId, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting group unsubscriptions count for the application appReleaseId " + appReleaseId + + " from the database"); + } + try { + Connection conn = this.getDBConnection(); + String sql = "SELECT COUNT(*) AS count " + + "FROM AP_GROUP_SUBSCRIPTION " + + "WHERE AP_APP_RELEASE_ID = ? " + + "AND TENANT_ID = ? " + + "AND UNSUBSCRIBED = TRUE"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + return rs.getInt("count"); + } + return 0; + } + } catch (SQLException e) { + String msg = "Error occurred while running SQL to get group unsubscription count for application appReleaseId: " + + appReleaseId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection for getting group unsubscription count for appReleaseId: " + + appReleaseId + "."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public int getRoleSubscriptionCount(int appReleaseId, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting role subscriptions count for the application appReleaseId " + appReleaseId + + " from the database"); + } + try { + Connection conn = this.getDBConnection(); + String sql = "SELECT COUNT(*) AS count " + + "FROM AP_ROLE_SUBSCRIPTION " + + "WHERE AP_APP_RELEASE_ID = ? " + + "AND TENANT_ID = ? " + + "AND UNSUBSCRIBED = FALSE"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + return rs.getInt("count"); + } + return 0; + } + } catch (SQLException e) { + String msg = "Error occurred while running SQL to get role subscriptions count for application appReleaseId: " + + appReleaseId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection for getting role subscriptions count for appReleaseId: " + + appReleaseId + "."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public int getRoleUnsubscriptionCount(int appReleaseId, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting role unsubscription count for the application appReleaseId " + appReleaseId + + " from the database"); + } + try { + Connection conn = this.getDBConnection(); + String sql = "SELECT COUNT(*) AS count " + + "FROM AP_ROLE_SUBSCRIPTION " + + "WHERE AP_APP_RELEASE_ID = ? " + + "AND TENANT_ID = ? " + + "AND UNSUBSCRIBED = TRUE"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + return rs.getInt("count"); + } + return 0; + } + } catch (SQLException e) { + String msg = "Error occurred while running SQL to get role unsubscription count for application appReleaseId: " + + appReleaseId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection for getting role unsubscription count for appReleaseId: " + + appReleaseId + "."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public int getUserSubscriptionCount(int appReleaseId, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting user subscriptions count for the application appReleaseId " + appReleaseId + + " from the database"); + } + try { + Connection conn = this.getDBConnection(); + String sql = "SELECT COUNT(*) AS count " + + "FROM AP_USER_SUBSCRIPTION " + + "WHERE AP_APP_RELEASE_ID = ? " + + "AND TENANT_ID = ? " + + "AND UNSUBSCRIBED = FALSE"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + return rs.getInt("count"); + } + return 0; + } + } catch (SQLException e) { + String msg = "Error occurred while running SQL to get user subscriptions count for application appReleaseId: " + + appReleaseId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection for getting user subscriptions count for appReleaseId: " + + appReleaseId + "."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public int getUserUnsubscriptionCount(int appReleaseId, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting user unsubscription count for the application appReleaseId " + appReleaseId + + " from the database"); + } + try { + Connection conn = this.getDBConnection(); + String sql = "SELECT COUNT(*) AS count " + + "FROM AP_USER_SUBSCRIPTION " + + "WHERE AP_APP_RELEASE_ID = ? " + + "AND TENANT_ID = ? " + + "AND UNSUBSCRIBED = TRUE"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + return rs.getInt("count"); + } + return 0; + } + } catch (SQLException e) { + String msg = "Error occurred while running SQL to get user unsubscription count for application appReleaseId: " + + appReleaseId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection for getting user unsubscription count for appReleaseId: " + + appReleaseId + "."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java index 931c45ddcf..0ade616d52 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java @@ -19,17 +19,44 @@ package io.entgra.device.mgt.core.application.mgt.core.impl; import com.google.gson.Gson; +import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstallResponse; +import io.entgra.device.mgt.core.application.mgt.common.ApplicationSubscriptionInfo; +import io.entgra.device.mgt.core.application.mgt.common.ApplicationType; +import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; +import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscriptionData; +import io.entgra.device.mgt.core.application.mgt.common.dto.CategorizedSubscriptionCountsDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.SubscriptionsDTO; +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; +import io.entgra.device.mgt.core.application.mgt.common.SubscribingDeviceIdHolder; +import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType; +import io.entgra.device.mgt.core.application.mgt.common.dto.GroupSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationPolicyDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.VppAssetDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.VppUserDTO; import io.entgra.device.mgt.core.application.mgt.common.services.VPPApplicationManager; +import io.entgra.device.mgt.core.application.mgt.core.dao.ApplicationReleaseDAO; 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; +import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOException; +import io.entgra.device.mgt.core.device.mgt.core.dto.OperationDTO; +import io.entgra.device.mgt.core.device.mgt.core.dto.OwnerWithDeviceDTO; import io.entgra.device.mgt.core.device.mgt.extensions.logger.spi.EntgraLogger; import io.entgra.device.mgt.core.notification.logger.AppInstallLogContext; import io.entgra.device.mgt.core.notification.logger.impl.EntgraAppInstallLoggerImpl; -import org.apache.commons.httpclient.HttpClient; import org.apache.commons.lang.StringUtils; import org.apache.http.HttpResponse; @@ -45,20 +72,6 @@ import org.json.JSONObject; import io.entgra.device.mgt.core.apimgt.application.extension.dto.ApiApplicationKey; import io.entgra.device.mgt.core.apimgt.application.extension.exception.APIManagerException; import org.wso2.carbon.context.PrivilegedCarbonContext; -import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstallResponse; -import io.entgra.device.mgt.core.application.mgt.common.ApplicationSubscriptionInfo; -import io.entgra.device.mgt.core.application.mgt.common.ApplicationType; -import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscriptionData; -import io.entgra.device.mgt.core.application.mgt.common.DeviceTypes; -import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus; -import io.entgra.device.mgt.core.application.mgt.common.SubAction; -import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType; -import io.entgra.device.mgt.core.application.mgt.common.SubscribingDeviceIdHolder; -import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationPolicyDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException; import io.entgra.device.mgt.core.application.mgt.common.exception.DBConnectionException; import io.entgra.device.mgt.core.application.mgt.common.exception.LifecycleManagementException; @@ -99,6 +112,7 @@ import io.entgra.device.mgt.core.device.mgt.core.util.MDMIOSOperationUtil; import io.entgra.device.mgt.core.device.mgt.core.util.MDMWindowsOperationUtil; import io.entgra.device.mgt.core.identity.jwt.client.extension.dto.AccessTokenInfo; import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; import javax.ws.rs.core.MediaType; import java.io.BufferedReader; @@ -113,6 +127,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; @@ -120,6 +135,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; /** @@ -131,12 +147,14 @@ public class SubscriptionManagerImpl implements SubscriptionManager { private SubscriptionDAO subscriptionDAO; private ApplicationDAO applicationDAO; private VppApplicationDAO vppApplicationDAO; + private ApplicationReleaseDAO applicationReleaseDAO; private LifecycleStateManager lifecycleStateManager; public SubscriptionManagerImpl() { this.lifecycleStateManager = DataHolder.getInstance().getLifecycleStateManager(); this.subscriptionDAO = ApplicationManagementDAOFactory.getSubscriptionDAO(); this.applicationDAO = ApplicationManagementDAOFactory.getApplicationDAO(); + this.applicationReleaseDAO = ApplicationManagementDAOFactory.getApplicationReleaseDAO(); this.vppApplicationDAO = ApplicationManagementDAOFactory.getVppApplicationDAO(); } @@ -1505,16 +1523,19 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } @Override - public PaginationResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, - String action, String installedVersion) throws ApplicationManagementException { + public CategorizedSubscriptionResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, + String action, String installedVersion) throws ApplicationManagementException { int limitValue = request.getRowCount(); int offsetValue = request.getStartIndex(); int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); - DeviceManagementProviderService deviceManagementProviderService = HelperUtil - .getDeviceManagementProviderService(); + DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); + List installedDevices = new ArrayList<>(); + List pendingDevices = new ArrayList<>(); + List errorDevices = new ArrayList<>(); + if (offsetValue < 0 || limitValue <= 0) { - String msg = "Found incompatible values for offset and limit. Hence please check the request and resend. " - + "Offset " + offsetValue + " limit " + limitValue; + String msg = "Found incompatible values for offset and limit. Hence please check the request and resend. " + + "Offset " + offsetValue + " limit " + limitValue; log.error(msg); throw new BadRequestException(msg); } @@ -1532,31 +1553,26 @@ public class SubscriptionManagerImpl implements SubscriptionManager { List deviceSubscriptionDTOS = subscriptionDAO .getDeviceSubscriptions(applicationReleaseId, tenantId, actionStatus, action); if (deviceSubscriptionDTOS.isEmpty()) { - PaginationResult paginationResult = new PaginationResult(); - paginationResult.setData(new ArrayList<>()); - paginationResult.setRecordsFiltered(0); - paginationResult.setRecordsTotal(0); - return paginationResult; + return new CategorizedSubscriptionResult(new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); } List deviceIdList = deviceSubscriptionDTOS.stream().map(DeviceSubscriptionDTO::getDeviceId) .collect(Collectors.toList()); - Map currentVersionsMap = subscriptionDAO.getCurrentInstalledAppVersion(applicationDTO.getId(),deviceIdList, installedVersion); + Map currentVersionsMap = + subscriptionDAO.getCurrentInstalledAppVersion(applicationDTO.getId(), deviceIdList, installedVersion); try { - //pass the device id list to device manager service method - PaginationResult paginationResult = deviceManagementProviderService.getAppSubscribedDevices - (request, deviceIdList); - List deviceSubscriptionDataList = new ArrayList<>(); + // Pass the device id list to device manager service method + PaginationResult paginationResult = deviceManagementProviderService.getAppSubscribedDevices(request, deviceIdList); if (!paginationResult.getData().isEmpty()) { List devices = (List) paginationResult.getData(); for (Device device : devices) { - if(installedVersion != null && !installedVersion.isEmpty() && !currentVersionsMap.containsKey(device.getId())){ + if (installedVersion != null && !installedVersion.isEmpty() && !currentVersionsMap.containsKey(device.getId())) { continue; } DeviceSubscriptionData deviceSubscriptionData = new DeviceSubscriptionData(); - if(currentVersionsMap.containsKey(device.getId())){ + if (currentVersionsMap.containsKey(device.getId())) { deviceSubscriptionData.setCurrentInstalledVersion(currentVersionsMap.get(device.getId())); - }else{ + } else { deviceSubscriptionData.setCurrentInstalledVersion("-"); } for (DeviceSubscriptionDTO subscription : deviceSubscriptionDTOS) { @@ -1565,39 +1581,51 @@ public class SubscriptionManagerImpl implements SubscriptionManager { if (subscription.isUnsubscribed()) { deviceSubscriptionData.setAction(Constants.UNSUBSCRIBED); deviceSubscriptionData.setActionTriggeredBy(subscription.getUnsubscribedBy()); - deviceSubscriptionData - .setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp().getTime() / 1000); + deviceSubscriptionData.setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp()); } else { deviceSubscriptionData.setAction(Constants.SUBSCRIBED); deviceSubscriptionData.setActionTriggeredBy(subscription.getSubscribedBy()); - deviceSubscriptionData - .setActionTriggeredTimestamp(subscription.getSubscribedTimestamp().getTime() / 1000); + deviceSubscriptionData.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); } deviceSubscriptionData.setActionType(subscription.getActionTriggeredFrom()); deviceSubscriptionData.setStatus(subscription.getStatus()); deviceSubscriptionData.setSubId(subscription.getId()); - deviceSubscriptionDataList.add(deviceSubscriptionData); + + // Categorize the subscription data based on its status + switch (subscription.getStatus()) { + case "COMPLETED": + installedDevices.add(deviceSubscriptionData); + break; + case "ERROR": + case "INVALID": + case "UNAUTHORIZED": + errorDevices.add(deviceSubscriptionData); + break; + case "IN_PROGRESS": + case "PENDING": + case "REPEATED": + pendingDevices.add(deviceSubscriptionData); + break; + } break; } } } } - paginationResult.setData(deviceSubscriptionDataList); - return paginationResult; + return new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices); } catch (DeviceManagementException e) { - String msg = "service error occurred while getting device data from the device management service. " - + "Device ids " + deviceIdList; + String msg = "Service error occurred while getting device data from the device management service. " + + "Device ids " + deviceIdList; log.error(msg, e); throw new ApplicationManagementException(msg, e); } } catch (ApplicationManagementDAOException e) { - String msg = - "Error occurred when getting application release data for application release UUID: " + appUUID; + String msg = "Error occurred when getting application release data for application release UUID: " + appUUID; log.error(msg, e); throw new ApplicationManagementException(msg, e); } catch (DBConnectionException e) { - String msg = "DB Connection error occurred while trying to get subscription data of application which has " - + "application release UUID " + appUUID; + String msg = "DB Connection error occurred while trying to get subscription data of application which has " + + "application release UUID " + appUUID; log.error(msg, e); throw new ApplicationManagementException(msg, e); } finally { @@ -1675,4 +1703,986 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } } + @Override + 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; + String status; + + 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.getGroupsSubscriptionDetailsByAppReleaseID(appReleaseId, unsubscribe, tenantId, offset, limit); + if (groupDetails == null) { + throw new ApplicationManagementException("Group details not found for appReleaseId: " + appReleaseId); + } + + GroupManagementProviderService groupManagementProviderService = HelperUtil.getGroupManagementProviderService(); + + for (GroupSubscriptionDTO groupDetail : groupDetails) { + groupName = groupDetail.getGroupName(); + + // Retrieve group details and device IDs for the group using the service layer + GroupDetailsDTO groupDetailWithDevices = + groupManagementProviderService.getGroupDetailsWithDevices(groupName, offset, limit); + + SubscriptionsDTO groupDetailDTO = new SubscriptionsDTO(); + groupDetailDTO.setId(groupDetailWithDevices.getGroupId()); + groupDetailDTO.setName(groupDetail.getGroupName()); + groupDetailDTO.setOwner(groupDetailWithDevices.getGroupOwner()); + groupDetailDTO.setSubscribedBy(groupDetail.getSubscribedBy()); + groupDetailDTO.setSubscribedTimestamp(groupDetail.getSubscribedTimestamp()); + groupDetailDTO.setUnsubscribed(groupDetail.isUnsubscribed()); + groupDetailDTO.setUnsubscribedBy(groupDetail.getUnsubscribedBy()); + groupDetailDTO.setUnsubscribedTimestamp(groupDetail.getUnsubscribedTimestamp()); + groupDetailDTO.setAppReleaseId(groupDetail.getAppReleaseId()); + groupDetailDTO.setDeviceCount(groupDetailWithDevices.getDeviceCount()); + + // Fetch device subscriptions for each device ID in the group + List pendingDevices = new ArrayList<>(); + List installedDevices = new ArrayList<>(); + List errorDevices = new ArrayList<>(); + List newDevices = new ArrayList<>(); + List subscribedDevices = new ArrayList<>(); + + List deviceIds = groupDetailWithDevices.getDeviceIds(); + Map statusCounts = new HashMap<>(); + statusCounts.put("PENDING", 0); + statusCounts.put("COMPLETED", 0); + statusCounts.put("ERROR", 0); + statusCounts.put("NEW", 0); + 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.getSubscriptionDetailsByDeviceIds( + groupDetail.getAppReleaseId(), unsubscribe, tenantId, deviceIds); + boolean isNewDevice = true; + for (DeviceSubscriptionDTO subscription : deviceSubscriptions) { + if (subscription.getDeviceId() == deviceId) { + DeviceSubscriptionData deviceDetail = new DeviceSubscriptionData(); + deviceDetail.setDeviceId(subscription.getDeviceId()); + deviceDetail.setStatus(subscription.getStatus()); + deviceDetail.setActionType(subscription.getActionTriggeredFrom()); + deviceDetail.setDeviceOwner(groupDetailWithDevices.getDeviceOwners().get(deviceId)); + deviceDetail.setDeviceStatus(groupDetailWithDevices.getDeviceStatuses().get(deviceId)); + deviceDetail.setDeviceName(groupDetailWithDevices.getDeviceNames().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) { + case "COMPLETED": + installedDevices.add(deviceDetail); + statusCounts.put("COMPLETED", statusCounts.get("COMPLETED") + 1); + break; + case "ERROR": + case "INVALID": + case "UNAUTHORIZED": + errorDevices.add(deviceDetail); + statusCounts.put("ERROR", statusCounts.get("ERROR") + 1); + break; + case "IN_PROGRESS": + case "PENDING": + case "REPEATED": + pendingDevices.add(deviceDetail); + statusCounts.put("PENDING", statusCounts.get("PENDING") + 1); + break; + } + isNewDevice = false; + } + } + if (isNewDevice) { + 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.setDeviceName(groupDetailWithDevices.getDeviceNames().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)); + newDeviceDetail.setDeviceName(groupDetailWithDevices.getDeviceNames().get(deviceId)); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } + } + } + + int totalDevices = deviceIds.size(); + Map statusPercentages = new HashMap<>(); + for (Map.Entry entry : statusCounts.entrySet()) { + double percentage = ((double) entry.getValue() / totalDevices) * 100; + String formattedPercentage = String.format("%.2f", percentage); + statusPercentages.put(entry.getKey(), Double.valueOf(formattedPercentage)); + } + + 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); + + groupDetailsWithDevices.add(groupDetailDTO); + } + + return groupDetailsWithDevices; + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while fetching groups and devices for UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "DB Connection error occurred while fetching groups and devices for UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (GroupManagementException e) { + String msg = "Error occurred while fetching group details and device IDs: " + e.getMessage(); + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public List getUserSubscriptionsByUUID(String uuid, String subscriptionStatus, int offset, int limit) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); + String userName; + String status; + + 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.getUserSubscriptionsByAppReleaseID(appReleaseId, unsubscribe, tenantId, offset, limit); + if (userSubscriptions == null) { + throw new ApplicationManagementException("User details not found for appReleaseId: " + appReleaseId); + } + + DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); + + for (SubscriptionsDTO userSubscription : userSubscriptions) { + userName = userSubscription.getName(); + + // Retrieve owner details and device IDs for the user using the service layer + OwnerWithDeviceDTO ownerDetailsWithDevices = + deviceManagementProviderService.getOwnersWithDeviceIds(userName); + + SubscriptionsDTO userSubscriptionDTO = new SubscriptionsDTO(); + userSubscriptionDTO.setName(userSubscription.getName()); + userSubscriptionDTO.setSubscribedBy(userSubscription.getSubscribedBy()); + userSubscriptionDTO.setSubscribedTimestamp(userSubscription.getSubscribedTimestamp()); + userSubscriptionDTO.setUnsubscribed(userSubscription.getUnsubscribed()); + userSubscriptionDTO.setUnsubscribedBy(userSubscription.getUnsubscribedBy()); + userSubscriptionDTO.setUnsubscribedTimestamp(userSubscription.getUnsubscribedTimestamp()); + userSubscriptionDTO.setAppReleaseId(userSubscription.getAppReleaseId()); + + userSubscriptionDTO.setDeviceCount(ownerDetailsWithDevices.getDeviceCount()); + + // Fetch device subscriptions for each device ID associated with the user + List pendingDevices = new ArrayList<>(); + List installedDevices = new ArrayList<>(); + List errorDevices = new ArrayList<>(); + List newDevices = new ArrayList<>(); + List subscribedDevices = new ArrayList<>(); + + List deviceIds = ownerDetailsWithDevices.getDeviceIds(); + Map statusCounts = new HashMap<>(); + statusCounts.put("PENDING", 0); + statusCounts.put("COMPLETED", 0); + statusCounts.put("ERROR", 0); + statusCounts.put("NEW", 0); + statusCounts.put("SUBSCRIBED", 0); + + List subscribedDeviceSubscriptions = new ArrayList<>(); + if (unsubscribe) { + subscribedDeviceSubscriptions = subscriptionDAO.getSubscriptionDetailsByDeviceIds( + appReleaseId, !unsubscribe, tenantId, deviceIds); + } + + for (Integer deviceId : deviceIds) { + 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.setDeviceName(ownerDetailsWithDevices.getDeviceNames()); + deviceDetail.setActionType(subscription.getActionTriggeredFrom()); + deviceDetail.setStatus(subscription.getStatus()); + deviceDetail.setActionType(subscription.getActionTriggeredFrom()); + 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) { + case "COMPLETED": + installedDevices.add(deviceDetail); + statusCounts.put("COMPLETED", statusCounts.get("COMPLETED") + 1); + break; + case "ERROR": + case "INVALID": + case "UNAUTHORIZED": + errorDevices.add(deviceDetail); + statusCounts.put("ERROR", statusCounts.get("ERROR") + 1); + break; + case "IN_PROGRESS": + case "PENDING": + case "REPEATED": + pendingDevices.add(deviceDetail); + statusCounts.put("PENDING", statusCounts.get("PENDING") + 1); + break; + } + isNewDevice = false; + } + } + if (isNewDevice) { + boolean isSubscribedDevice = false; + for (DeviceSubscriptionDTO subscribedDevice : subscribedDeviceSubscriptions) { + if (subscribedDevice.getDeviceId() == deviceId) { + DeviceSubscriptionData subscribedDeviceDetail = new DeviceSubscriptionData(); + subscribedDeviceDetail.setDeviceId(subscribedDevice.getDeviceId()); + subscribedDeviceDetail.setDeviceName(ownerDetailsWithDevices.getDeviceNames()); + 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()); + newDeviceDetail.setDeviceName(ownerDetailsWithDevices.getDeviceNames()); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } + } + } + + int totalDevices = deviceIds.size(); + Map statusPercentages = new HashMap<>(); + for (Map.Entry entry : statusCounts.entrySet()) { + double percentage = ((double) entry.getValue() / totalDevices) * 100; + String formattedPercentage = String.format("%.2f", percentage); + statusPercentages.put(entry.getKey(), Double.valueOf(formattedPercentage)); + } + + 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); + + userSubscriptionsWithDevices.add(userSubscriptionDTO); + } + + return userSubscriptionsWithDevices; + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while getting user subscriptions for the application release UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "DB Connection error occurred while getting user subscriptions for UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DeviceManagementDAOException e) { + throw new RuntimeException(e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public List getRoleSubscriptionsByUUID(String uuid, String subscriptionStatus, int offset, int limit) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); + String roleName; + String status; + + 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.getRoleSubscriptionsByAppReleaseID(appReleaseId, unsubscribe, tenantId, offset, limit); + if (roleSubscriptions == null) { + throw new ApplicationManagementException("Role details not found for appReleaseId: " + appReleaseId); + } + + DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); + + for (SubscriptionsDTO roleSubscription : roleSubscriptions) { + roleName = roleSubscription.getName(); + + SubscriptionsDTO roleSubscriptionDTO = new SubscriptionsDTO(); + roleSubscriptionDTO.setName(roleSubscription.getName()); + roleSubscriptionDTO.setSubscribedBy(roleSubscription.getSubscribedBy()); + roleSubscriptionDTO.setSubscribedTimestamp(roleSubscription.getSubscribedTimestamp()); + roleSubscriptionDTO.setUnsubscribed(roleSubscription.getUnsubscribed()); + roleSubscriptionDTO.setUnsubscribedBy(roleSubscription.getUnsubscribedBy()); + roleSubscriptionDTO.setUnsubscribedTimestamp(roleSubscription.getUnsubscribedTimestamp()); + roleSubscriptionDTO.setAppReleaseId(roleSubscription.getAppReleaseId()); + + List pendingDevices = new ArrayList<>(); + List installedDevices = new ArrayList<>(); + List errorDevices = new ArrayList<>(); + List newDevices = new ArrayList<>(); + 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); + + for (String user : users) { + OwnerWithDeviceDTO ownerDetailsWithDevices; + try { + ownerDetailsWithDevices = deviceManagementProviderService.getOwnersWithDeviceIds(user); + } catch (DeviceManagementDAOException e) { + throw new ApplicationManagementException("Error retrieving owner details with devices for user: " + user, e); + } + + List deviceIds = ownerDetailsWithDevices.getDeviceIds(); + for (Integer deviceId : deviceIds) { + + List subscribedDeviceSubscriptions = new ArrayList<>(); + if (unsubscribe) { + subscribedDeviceSubscriptions = subscriptionDAO.getSubscriptionDetailsByDeviceIds( + appReleaseId, !unsubscribe, tenantId, deviceIds); + } + + List deviceSubscriptions; + try { + deviceSubscriptions = subscriptionDAO.getSubscriptionDetailsByDeviceIds( + roleSubscription.getAppReleaseId(), unsubscribe, tenantId, deviceIds); + } catch (ApplicationManagementDAOException e) { + throw new ApplicationManagementException("Error retrieving device subscriptions", e); + } + + boolean isNewDevice = true; + for (DeviceSubscriptionDTO deviceSubscription : deviceSubscriptions) { + if (deviceSubscription.getDeviceId() == deviceId) { + DeviceSubscriptionData deviceDetail = new DeviceSubscriptionData(); + deviceDetail.setDeviceId(deviceSubscription.getDeviceId()); + deviceDetail.setDeviceName(ownerDetailsWithDevices.getDeviceNames()); + 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) { + case "COMPLETED": + installedDevices.add(deviceDetail); + statusCounts.put("COMPLETED", statusCounts.get("COMPLETED") + 1); + break; + case "ERROR": + case "INVALID": + case "UNAUTHORIZED": + errorDevices.add(deviceDetail); + statusCounts.put("ERROR", statusCounts.get("ERROR") + 1); + break; + case "IN_PROGRESS": + case "PENDING": + case "REPEATED": + pendingDevices.add(deviceDetail); + statusCounts.put("PENDING", statusCounts.get("PENDING") + 1); + break; + } + isNewDevice = false; + } + } + if (isNewDevice) { + boolean isSubscribedDevice = false; + for (DeviceSubscriptionDTO subscribedDevice : subscribedDeviceSubscriptions) { + if (subscribedDevice.getDeviceId() == deviceId) { + DeviceSubscriptionData subscribedDeviceDetail = new DeviceSubscriptionData(); + subscribedDeviceDetail.setDeviceId(subscribedDevice.getDeviceId()); + subscribedDeviceDetail.setDeviceName(ownerDetailsWithDevices.getDeviceNames()); + 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.setDeviceName(ownerDetailsWithDevices.getDeviceNames()); + 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() + subscribedDevices.size(); + Map statusPercentages = new HashMap<>(); + for (Map.Entry entry : statusCounts.entrySet()) { + double percentage = totalDevices == 0 ? 0.0 : ((double) entry.getValue() / totalDevices) * 100; + String formattedPercentage = String.format("%.2f", percentage); + statusPercentages.put(entry.getKey(), Double.valueOf(formattedPercentage)); + } + + 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); + + roleSubscriptionsWithDevices.add(roleSubscriptionDTO); + } + + return roleSubscriptionsWithDevices; + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred in retrieving role subscriptions with devices"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while retrieving the database connection"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (UserStoreException e) { + String msg = "Error occurred while retrieving users for role"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + // Get user list for each role + public List getUsersForRole(String roleName) throws UserStoreException { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + int tenantId = ctx.getTenantId(); + UserStoreManager userStoreManager = DataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId).getUserStoreManager(); + String[] users = userStoreManager.getUserListOfRole(roleName); + return Arrays.asList(users); + } + + @Override + public 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.setDeviceName(ownerWithDevice.getDeviceNames()); + 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.setDeviceName(ownerWithDevice.getDeviceNames()); + 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.setDeviceName(ownerWithDevice.getDeviceNames()); + 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; + String formattedPercentage = String.format("%.2f", percentage); + statusPercentages.put(entry.getKey(), Double.valueOf(formattedPercentage)); + } + + 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.setDeviceName(ownerWithDevice.getDeviceNames()); + 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.setDeviceName(ownerWithDevice.getDeviceNames()); + 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; + String formattedPercentage = String.format("%.2f", percentage); + statusPercentages.put(entry.getKey(), Double.valueOf(formattedPercentage)); + } + + 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 getSubscriptionOperationsByUUIDAndDeviceID(int deviceId, 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.getSubscriptionOperationsByAppReleaseIDAndDeviceID(appReleaseId, deviceId, tenantId, offset, limit); + for (DeviceOperationDTO deviceSubscription : deviceSubscriptions) { + Integer operationId = deviceSubscription.getOperationId(); + if (operationId != null) { + OperationDTO operationDetails = deviceManagementProviderService.getOperationDetailsById(operationId); + if (operationDetails != null) { + deviceSubscription.setOperationCode(operationDetails.getOperationCode()); + deviceSubscription.setOperationDetails(operationDetails.getOperationDetails()); + deviceSubscription.setOperationProperties(operationDetails.getOperationProperties()); + deviceSubscription.setOperationResponses(operationDetails.getOperationResponses()); + } + } + } + return deviceSubscriptions; + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while retrieving device subscriptions for UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while retrieving the database connection"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (OperationManagementException e) { + throw new RuntimeException(e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public List getSubscriptionCountsByUUID(String uuid) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + if (uuid == null || uuid.isEmpty()) { + throw new IllegalArgumentException("UUID cannot be null or empty."); + } + + try { + ConnectionManagerUtil.openDBConnection(); + + 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 subscriptionCounts = new ArrayList<>(); + + subscriptionCounts.add(new CategorizedSubscriptionCountsDTO( + "All", + subscriptionDAO.getAllSubscriptionCount(appReleaseId, tenantId), + subscriptionDAO.getAllUnsubscriptionCount(appReleaseId, tenantId))); + subscriptionCounts.add(new CategorizedSubscriptionCountsDTO( + "Device", + subscriptionDAO.getDeviceSubscriptionCount(appReleaseId, tenantId), + subscriptionDAO.getDeviceUnsubscriptionCount(appReleaseId, tenantId))); + subscriptionCounts.add(new CategorizedSubscriptionCountsDTO( + "Group", + subscriptionDAO.getGroupSubscriptionCount(appReleaseId, tenantId), + subscriptionDAO.getGroupUnsubscriptionCount(appReleaseId, tenantId))); + subscriptionCounts.add(new CategorizedSubscriptionCountsDTO( + "Role", + subscriptionDAO.getRoleSubscriptionCount(appReleaseId, tenantId), + subscriptionDAO.getRoleUnsubscriptionCount(appReleaseId, tenantId))); + subscriptionCounts.add(new CategorizedSubscriptionCountsDTO( + "User", + subscriptionDAO.getUserSubscriptionCount(appReleaseId, tenantId), + subscriptionDAO.getUserUnsubscriptionCount(appReleaseId, tenantId))); + + return subscriptionCounts; + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while retrieving subscriptions counts for UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while retrieving the database connection"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/test/java/io/entgra/device/mgt/core/application/mgt/core/BaseTestCase.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/test/java/io/entgra/device/mgt/core/application/mgt/core/BaseTestCase.java index 9243cb8930..7251a0d19e 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/test/java/io/entgra/device/mgt/core/application/mgt/core/BaseTestCase.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/test/java/io/entgra/device/mgt/core/application/mgt/core/BaseTestCase.java @@ -37,6 +37,7 @@ import io.entgra.device.mgt.core.device.mgt.core.config.DeviceConfigurationManag import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.core.internal.DeviceManagementDataHolder; import io.entgra.device.mgt.core.device.mgt.core.metadata.mgt.dao.MetadataManagementDAOFactory; +import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory; import org.wso2.carbon.registry.core.config.RegistryContext; import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.registry.core.internal.RegistryDataHolder; @@ -96,6 +97,7 @@ public abstract class BaseTestCase { ConnectionManagerUtil.init(dataSource); DeviceManagementDAOFactory.init(dataSource); MetadataManagementDAOFactory.init(dataSource); + OperationManagementDAOFactory.init(dataSource); // PolicyManagementDAOFactory.init(dataSource); // OperationManagementDAOFactory.init(dataSource); // GroupManagementDAOFactory.init(dataSource); diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/EnrollmentDAO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/EnrollmentDAO.java index e42d5c1524..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,9 +21,12 @@ 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; import java.util.List; +import java.util.Map; public interface EnrollmentDAO { @@ -94,5 +97,33 @@ public interface EnrollmentDAO { */ boolean addDeviceStatus(int enrolmentId, EnrolmentInfo.Status status) throws DeviceManagementDAOException; + /** + * Retrieves owners and the list of device IDs related to an owner. + * + * @param owner the owner whose device IDs need to be retrieved + * @param tenantId the ID of the tenant + * @return {@link OwnerWithDeviceDTO} which contains a list of devices related to a user + * @throws DeviceManagementDAOException if an error occurs while fetching the data + */ + 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 b3c4321df3..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 @@ -21,9 +21,9 @@ package io.entgra.device.mgt.core.device.mgt.core.dao; import io.entgra.device.mgt.core.device.mgt.common.Device; import io.entgra.device.mgt.core.device.mgt.common.GroupPaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; -import io.entgra.device.mgt.core.device.mgt.common.exceptions.ReportManagementException; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper; +import io.entgra.device.mgt.core.device.mgt.core.dto.GroupDetailsDTO; import java.util.List; import java.util.Map; @@ -469,4 +469,17 @@ public interface GroupDAO { List groupNames) throws GroupManagementDAOException; + /** + * Get group details and list of device IDs related to the group. + * + * @param groupName Group name + * @param tenantId Tenant ID + * @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 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 8bde335227..dff096c933 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 @@ -18,6 +18,9 @@ package io.entgra.device.mgt.core.device.mgt.core.dao.impl; import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier; +import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.util.OperationDAOUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; import io.entgra.device.mgt.core.device.mgt.common.Device; import io.entgra.device.mgt.core.device.mgt.common.DeviceManagementConstants; @@ -26,6 +29,8 @@ import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOExceptio import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.core.dao.EnrollmentDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.util.DeviceManagementDAOUtil; +import io.entgra.device.mgt.core.device.mgt.core.dto.OwnerWithDeviceDTO; +import io.entgra.device.mgt.core.device.mgt.core.dto.DeviceDetailsDTO; import java.sql.Connection; import java.sql.PreparedStatement; @@ -33,11 +38,12 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; -import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.ArrayList; public abstract class AbstractEnrollmentDAOImpl implements EnrollmentDAO { + private static final Log log = LogFactory.getLog(AbstractEnrollmentDAOImpl.class); @Override public EnrolmentInfo addEnrollment(int deviceId, DeviceIdentifier deviceIdentifier, EnrolmentInfo enrolmentInfo, @@ -557,4 +563,109 @@ public abstract class AbstractEnrollmentDAOImpl implements EnrollmentDAO { return enrolmentInfo; } + @Override + public OwnerWithDeviceDTO getOwnersWithDevices(String owner, int tenantId) + throws DeviceManagementDAOException { + Connection conn = null; + OwnerWithDeviceDTO ownerDetails = new OwnerWithDeviceDTO(); + List deviceIds = new ArrayList<>(); + int deviceCount = 0; + + String sql = "SELECT e.DEVICE_ID, e.OWNER, e.STATUS AS DEVICE_STATUS, d.NAME AS DEVICE_NAME " + + "FROM DM_ENROLMENT e " + + "JOIN DM_DEVICE d ON e.DEVICE_ID = d.ID " + + "WHERE e.OWNER = ? AND e.TENANT_ID = ?"; + try { + conn = this.getConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, owner); + stmt.setInt(2, tenantId); + + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + if (ownerDetails.getUserName() == null) { + ownerDetails.setUserName(rs.getString("OWNER")); + } + deviceIds.add(rs.getInt("DEVICE_ID")); + deviceCount++; + } + } + } + } catch (SQLException e) { + String msg = "Error occurred while retrieving owners and device IDs for owner: " + owner; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + + ownerDetails.setDeviceIds(deviceIds); + ownerDetails.setDeviceStatus("DEVICE_STATUS"); + ownerDetails.setDeviceNames("DEVICE_NAME"); + ownerDetails.setDeviceCount(deviceCount); + return ownerDetails; + } + + @Override + public OwnerWithDeviceDTO getOwnerWithDeviceByDeviceId(int deviceId, int tenantId) + throws DeviceManagementDAOException { + OwnerWithDeviceDTO deviceOwnerWithStatus = new OwnerWithDeviceDTO(); + Connection conn = null; + String sql = "SELECT e.DEVICE_ID, e.OWNER, e.STATUS AS DEVICE_STATUS, d.NAME AS DEVICE_NAME " + + "FROM DM_ENROLMENT e " + + "JOIN DM_DEVICE d ON e.DEVICE_ID = d.ID " + + "WHERE e.DEVICE_ID = ? AND e.TENANT_ID = ?"; + try { + conn = this.getConnection(); + try (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); + deviceOwnerWithStatus.setDeviceNames(rs.getString("DEVICE_NAME")); + } + } + } + } catch (SQLException e) { + String msg = "Error occurred while retrieving owner and status for device ID: " + deviceId; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, 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 = ?"; + Connection conn = null; + + try { + conn = this.getConnection(); + try (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) { + String msg = "Error occurred while retrieving devices for tenant ID: " + tenantId; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, 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 c65692870d..c3aa38539d 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java @@ -26,6 +26,7 @@ import io.entgra.device.mgt.core.device.mgt.common.Device; import io.entgra.device.mgt.core.device.mgt.common.GroupPaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup; +import io.entgra.device.mgt.core.device.mgt.core.dto.GroupDetailsDTO; import io.entgra.device.mgt.core.device.mgt.core.dao.GroupDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.GroupManagementDAOException; import io.entgra.device.mgt.core.device.mgt.core.dao.GroupManagementDAOFactory; @@ -164,7 +165,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { } } catch (SQLException e) { String msg = "Error occurred while retrieving groups of groups IDs " + deviceGroupIds.toString() - + " in tenant: " + tenantId; + + " in tenant: " + tenantId; log.error(msg); throw new GroupManagementDAOException(msg, e); } @@ -184,7 +185,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { for (int i = 0; i < deviceGroupIdsCount; i++) { sql += (deviceGroupIdsCount - 1 != i) ? "?," : "?"; } - sql += ")"; + sql += ")"; try (PreparedStatement stmt = conn.prepareStatement(sql)) { int paramIndex = 1; stmt.setInt(paramIndex++, tenantId); @@ -202,7 +203,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { } } catch (SQLException e) { String msg = "Error occurred while retrieving groups of groups IDs " + deviceGroupIds - + " in tenant: " + tenantId; + + " in tenant: " + tenantId; log.error(msg); throw new GroupManagementDAOException(msg, e); } @@ -227,7 +228,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { sql += " AND OWNER LIKE ?"; } if (StringUtils.isNotBlank(request.getParentPath())) { - if(isWithParentPath){ + if (isWithParentPath) { sql += " AND PARENT_PATH LIKE ?"; } } @@ -250,7 +251,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { stmt.setString(paramIndex++, request.getOwner() + "%"); } if (StringUtils.isNotBlank(request.getParentPath())) { - if(isWithParentPath){ + if (isWithParentPath) { stmt.setString(paramIndex++, request.getParentPath()); } } @@ -271,7 +272,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { } } catch (SQLException e) { String msg = "Error occurred while retrieving groups of groups IDs " + deviceGroupIds.toString() - + " in tenant: " + tenantId; + + " in tenant: " + tenantId; log.error(msg); throw new GroupManagementDAOException(msg, e); } @@ -484,7 +485,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { Connection conn = GroupManagementDAOFactory.getConnection(); String sql = "UPDATE DM_GROUP SET DESCRIPTION = ?, GROUP_NAME = ?, OWNER = ?, STATUS = ?, " + "PARENT_PATH = ?, PARENT_GROUP_ID = ? WHERE ID = ? AND TENANT_ID = ?"; - try (PreparedStatement stmt = conn.prepareStatement(sql)){ + try (PreparedStatement stmt = conn.prepareStatement(sql)) { for (DeviceGroup deviceGroup : deviceGroups) { stmt.setString(1, deviceGroup.getDescription()); stmt.setString(2, deviceGroup.getName()); @@ -609,6 +610,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { throw new GroupManagementDAOException(msg, e); } } + @Override public void deleteGroups(List groupIds, int tenantId) throws GroupManagementDAOException { try { @@ -1166,7 +1168,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { if (StringUtils.isNotBlank(parentPath)) { sql += " AND g.PARENT_PATH = ? "; } - sql += "GROUP BY g.ID"; + sql += "GROUP BY g.ID"; stmt = conn.prepareStatement(sql); int index = 0; while (index++ < rolesCount) { @@ -1279,7 +1281,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { return devices; } Connection conn = GroupManagementDAOFactory.getConnection(); - StringJoiner joiner = new StringJoiner(",","SELECT " + StringJoiner joiner = new StringJoiner(",", "SELECT " + "d1.DEVICE_ID, " + "d1.DESCRIPTION, " + "d1.NAME AS DEVICE_NAME, " @@ -1437,4 +1439,72 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { } return groupUnassignedDeviceList; } -} + + @Override + 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<>(); + Map deviceNames = new HashMap<>(); + + String sql = + "SELECT " + + " g.ID AS GROUP_ID, " + + " g.GROUP_NAME, " + + " g.OWNER AS GROUP_OWNER, " + + " e.OWNER AS DEVICE_OWNER, " + + " e.STATUS AS DEVICE_STATUS, " + + " dgm.DEVICE_ID, " + + " d.NAME AS DEVICE_NAME " + + "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 " + + " JOIN DM_DEVICE d ON e.DEVICE_ID = d.ID " + + "WHERE " + + " g.GROUP_NAME = ? " + + " AND g.TENANT_ID = ? " + + "LIMIT ? OFFSET ?"; + + Connection conn = null; + try { + conn = GroupManagementDAOFactory.getConnection(); + try (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()) { + if (groupDetails.getGroupId() == 0) { + groupDetails.setGroupId(rs.getInt("GROUP_ID")); + groupDetails.setGroupName(rs.getString("GROUP_NAME")); + groupDetails.setGroupOwner(rs.getString("GROUP_OWNER")); + } + int deviceId = rs.getInt("DEVICE_ID"); + deviceIds.add(deviceId); + deviceOwners.put(deviceId, rs.getString("DEVICE_OWNER")); + deviceStatuses.put(deviceId, rs.getString("DEVICE_STATUS")); + deviceNames.put(deviceId, rs.getString("DEVICE_NAME")); + } + } + } + } catch (SQLException e) { + String msg = "Error occurred while retrieving group details and device IDs for group: " + groupName; + log.error(msg, e); + throw new GroupManagementDAOException(msg, e); + } + groupDetails.setDeviceIds(deviceIds); + groupDetails.setDeviceCount(deviceIds.size()); + groupDetails.setDeviceOwners(deviceOwners); + groupDetails.setDeviceStatuses(deviceStatuses); + groupDetails.setDeviceNames(deviceNames); + return groupDetails; + } +} \ 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/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..2457e0bd3b --- /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,49 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.device.mgt.core.dto; + +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 new file mode 100644 index 0000000000..289fcfd472 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/GroupDetailsDTO.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.device.mgt.core.dto; + +import java.util.List; +import java.util.Map; + +public class GroupDetailsDTO { + private int groupId; + private String groupName; + private String groupOwner; + private List deviceIds; + private int deviceCount; + private String deviceOwner; + private String deviceStatus; + private Map deviceOwners; + private Map deviceStatuses; + private Map deviceNames; + + public int getGroupId() { + return groupId; + } + + public void setGroupId(int groupId) { + this.groupId = groupId; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public String getGroupOwner() { + return groupOwner; + } + + public void setGroupOwner(String groupOwner) { + this.groupOwner = groupOwner; + } + + public List getDeviceIds() { + return deviceIds; + } + + public void setDeviceIds(List deviceIds) { + this.deviceIds = deviceIds; + } + + public int getDeviceCount() { + return deviceCount; + } + + public void setDeviceCount(int deviceCount) { + this.deviceCount = deviceCount; + } + + 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; + } + + public Map getDeviceNames() { + return deviceNames; + } + + public void setDeviceNames(Map deviceNames) { + this.deviceNames = deviceNames; + } +} diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OperationDTO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OperationDTO.java new file mode 100644 index 0000000000..05530e231b --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OperationDTO.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.device.mgt.core.dto; + +import org.json.JSONObject; +import java.util.List; + +public class OperationDTO { + private int operationId; + private String operationCode; + private JSONObject operationDetails; + private JSONObject operationProperties; + private List operationResponses; + + // Getters and Setters + + public int getOperationId() { + return operationId; + } + + public void setOperationId(int operationId) { + this.operationId = operationId; + } + + public String getOperationCode() { + return operationCode; + } + + public void setOperationCode(String operationCode) { + this.operationCode = operationCode; + } + + public JSONObject getOperationDetails() { + return operationDetails; + } + + public void setOperationDetails(JSONObject operationDetails) { + this.operationDetails = operationDetails; + } + + public JSONObject getOperationProperties() { + return operationProperties; + } + + public void setOperationProperties(JSONObject operationProperties) { + this.operationProperties = operationProperties; + } + + public List getOperationResponses() { + return operationResponses; + } + + public void setOperationResponses(List operationResponses) { + this.operationResponses = operationResponses; + } +} 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/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OperationResponseDTO.java similarity index 55% rename from 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 rename to components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OperationResponseDTO.java index 4df7e4e64d..b52404ca0e 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/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OperationResponseDTO.java @@ -16,17 +16,28 @@ * under the License. */ -package io.entgra.device.mgt.core.application.mgt.common.dto; +package io.entgra.device.mgt.core.device.mgt.core.dto; import java.sql.Timestamp; -public class UserSubscriptionDTO { - private int id; - private String subscribedBy; - private Timestamp subscribedTimestamp; - private boolean isUnsubscribed; - private String unsubscribedBy; - private Timestamp unsubscribedTimestamp; - private String subscribedFrom; - private String userName; +public class OperationResponseDTO { + private String operationResponse; + private Timestamp responseTimeStamp; + + public String getOperationResponse() { + return operationResponse; + } + + public void setOperationResponse(String operationResponse) { + this.operationResponse = operationResponse; + } + + public Timestamp getResponseTimeStamp() { + return responseTimeStamp; + } + + public void setResponseTimeStamp(Timestamp responseTimeStamp) { + this.responseTimeStamp = responseTimeStamp; + } } + diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OwnerWithDeviceDTO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OwnerWithDeviceDTO.java new file mode 100644 index 0000000000..9d644b1930 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OwnerWithDeviceDTO.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.device.mgt.core.dto; + +import java.util.List; + +public class OwnerWithDeviceDTO { + + private String userName; + private List deviceIds; + private int deviceCount; + private String deviceStatus; + private String deviceNames; + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public List getDeviceIds() { + return deviceIds; + } + + public void setDeviceIds(List deviceIds) { + this.deviceIds = deviceIds; + } + + public int getDeviceCount() { + return deviceCount; + } + + public void setDeviceCount(int deviceCount) { + this.deviceCount = deviceCount; + } + + public String getDeviceStatus() { + return deviceStatus; + } + + public void setDeviceStatus(String deviceStatus) { + this.deviceStatus = deviceStatus; + } + + public String getDeviceNames() { + return deviceNames; + } + + public void setDeviceNames(String deviceNames) { + this.deviceNames = deviceNames; + } +} diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/OperationDAO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/OperationDAO.java index 4abaf40022..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 @@ -23,6 +23,8 @@ import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.OperationResponse; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.DeviceActivity; +import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOException; +import io.entgra.device.mgt.core.device.mgt.core.dto.OperationDTO; import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.Operation; import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.OperationResponseMeta; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.OperationMapping; @@ -124,4 +126,15 @@ public interface OperationDAO { int getDeviceActivitiesCount(ActivityPaginationRequest activityPaginationRequest) 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 8322905a5e..50ec3f1071 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java @@ -17,32 +17,36 @@ */ package io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.impl; -import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.ProfileOperation; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.context.PrivilegedCarbonContext; import io.entgra.device.mgt.core.device.mgt.common.ActivityPaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier; import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity; -import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.DeviceActivity; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.ActivityHolder; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.ActivityStatus; +import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.DeviceActivity; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.OperationResponse; import io.entgra.device.mgt.core.device.mgt.core.DeviceManagementConstants; import io.entgra.device.mgt.core.device.mgt.core.dao.util.DeviceManagementDAOUtil; +import io.entgra.device.mgt.core.device.mgt.core.dto.OperationDTO; +import io.entgra.device.mgt.core.device.mgt.core.dto.OperationResponseDTO; import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.Operation; import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.OperationResponseMeta; +import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.ProfileOperation; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.OperationMapping; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationDAO; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOException; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOUtil; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.util.OperationDAOUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.JSONObject; +import org.wso2.carbon.context.PrivilegedCarbonContext; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; +import java.sql.Blob; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -2774,4 +2778,66 @@ public class GenericOperationDAOImpl implements OperationDAO { } return 0; } + + @Override + public OperationDTO getOperationDetailsById(int operationId, int tenantId) + throws OperationManagementDAOException { + OperationDTO operationDetails = new OperationDTO(); + + String sql = "SELECT o.ID, " + + "o.OPERATION_CODE, " + + "o.OPERATION_DETAILS, " + + "o.OPERATION_PROPERTIES, " + + "r.OPERATION_RESPONSE, " + + "r.RECEIVED_TIMESTAMP " + + "FROM DM_OPERATION o " + + "LEFT JOIN DM_DEVICE_OPERATION_RESPONSE r " + + "ON o.ID = r.OPERATION_ID " + + "WHERE o.ID = ? " + + "AND o.TENANT_ID = ?"; + + try { + Connection conn = OperationManagementDAOFactory.getConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, operationId); + stmt.setInt(2, tenantId); + + try (ResultSet rs = stmt.executeQuery()) { + List responses = new ArrayList<>(); + while (rs.next()) { + if (operationDetails.getOperationId() == 0) { + operationDetails.setOperationId(rs.getInt("ID")); + operationDetails.setOperationCode(rs.getString("OPERATION_CODE")); + Blob detailsBlob = rs.getBlob("OPERATION_DETAILS"); + if (detailsBlob != null) { + JSONObject operationDetailsJson = OperationDAOUtil.convertBlobToJsonObject(detailsBlob); + operationDetails.setOperationDetails(operationDetailsJson); + } + Blob propertiesBlob = rs.getBlob("OPERATION_PROPERTIES"); + if (propertiesBlob != null) { + JSONObject operationPropertiesJson = OperationDAOUtil.convertBlobToJsonObject(propertiesBlob); + operationDetails.setOperationProperties(operationPropertiesJson); + } + } + + String response = rs.getString("OPERATION_RESPONSE"); + Timestamp responseTimestamp = rs.getTimestamp("RECEIVED_TIMESTAMP"); + if (response != null && responseTimestamp != null) { + OperationResponseDTO operationResponse = new OperationResponseDTO(); + operationResponse.setOperationResponse(response); + operationResponse.setResponseTimeStamp(responseTimestamp); + responses.add(operationResponse); + } + } + operationDetails.setOperationResponses(responses); + } + } + } catch (SQLException e) { + String msg = "Error occurred while retrieving operation details for operation ID: " + operationId; + log.error(msg, e); + throw new OperationManagementDAOException(msg, e); + } + + return operationDetails; + } } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/util/OperationDAOUtil.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/util/OperationDAOUtil.java index 6561868060..3aef7ea447 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/util/OperationDAOUtil.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/util/OperationDAOUtil.java @@ -33,10 +33,14 @@ import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.Operation; import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.PolicyOperation; import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.ProfileOperation; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOException; +import org.json.JSONObject; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.ObjectInputStream; +import java.sql.Blob; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; @@ -387,4 +391,53 @@ public class OperationDAOUtil { return operation; } + /** + * @param blob + * @return + * @throws SQLException + */ + public static JSONObject convertBlobToJsonObject(Blob blob) throws SQLException { + String jsonString; + try (InputStream inputStream = blob.getBinaryStream(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { + int bytesRead; + byte[] buffer = new byte[4096]; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + byte[] blobBytes = outputStream.toByteArray(); + + // Check if the blob data is a serialized Java object + if (blobBytes.length > 2 && (blobBytes[0] & 0xFF) == 0xAC && (blobBytes[1] & 0xFF) == 0xED) { + // Deserialize the object + try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(blobBytes))) { + Object obj = ois.readObject(); + if (obj instanceof String) { + jsonString = (String) obj; + } else { + jsonString = new JSONObject(obj).toString(); + } + } catch (ClassNotFoundException e) { + String msg = "Failed to deserialize object from BLOB"; + log.error(msg, e); + throw new SQLException(msg, e); + } + } else { + // If not serialized, treat it as plain JSON string + jsonString = new String(blobBytes, "UTF-8"); + } + } catch (IOException e) { + String msg = "Failed to convert BLOB to JSON string"; + log.error(msg, e); + throw new SQLException(msg, e); + } + // Convert JSON string to JSONObject + if (jsonString == null || jsonString.isEmpty()) { + String msg = "Converted JSON string is null or empty"; + log.error(msg); + throw new SQLException(msg); + } + return new JSONObject(jsonString); + } + } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderService.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderService.java index 689fc1b243..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,9 @@ 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; import io.entgra.device.mgt.core.device.mgt.common.*; import io.entgra.device.mgt.core.device.mgt.common.app.mgt.ApplicationManagementException; @@ -1073,4 +1076,39 @@ public interface DeviceManagementProviderService { List getEnrolledDevicesSince(Date since) throws DeviceManagementException; List getEnrolledDevicesPriorTo(Date before) throws DeviceManagementException; void deleteDeviceDataByTenantDomain(String tenantDomain) throws DeviceManagementException; + + /** + * Get owner details and device IDs for a given owner and tenant. + * + * @param owner the name of the owner. + * @return {@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 {@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 75f3836a34..aee7f67e02 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,11 @@ 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; +import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.extensions.logger.spi.EntgraLogger; import io.entgra.device.mgt.core.notification.logger.DeviceEnrolmentLogContext; import io.entgra.device.mgt.core.notification.logger.impl.EntgraDeviceEnrolmentLoggerImpl; @@ -120,6 +125,7 @@ import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceStatusDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceTypeDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.EnrollmentDAO; +import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.util.DeviceManagementDAOUtil; import io.entgra.device.mgt.core.device.mgt.core.device.details.mgt.DeviceDetailsMgtException; import io.entgra.device.mgt.core.device.mgt.core.device.details.mgt.DeviceInformationManager; @@ -173,6 +179,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv private final DeviceDAO deviceDAO; private final DeviceTypeDAO deviceTypeDAO; private final EnrollmentDAO enrollmentDAO; + private final OperationDAO operationDAO; private final ApplicationDAO applicationDAO; private MetadataDAO metadataDAO; private final DeviceStatusDAO deviceStatusDAO; @@ -185,6 +192,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv this.applicationDAO = DeviceManagementDAOFactory.getApplicationDAO(); this.deviceTypeDAO = DeviceManagementDAOFactory.getDeviceTypeDAO(); this.enrollmentDAO = DeviceManagementDAOFactory.getEnrollmentDAO(); + this.operationDAO = OperationManagementDAOFactory.getOperationDAO(); this.metadataDAO = MetadataManagementDAOFactory.getMetadataDAO(); this.deviceStatusDAO = DeviceManagementDAOFactory.getDeviceStatusDAO(); this.tenantDao = DeviceManagementDAOFactory.getTenantDAO(); @@ -5339,4 +5347,106 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv DeviceManagementDAOFactory.closeConnection(); } } + + @Override + public OwnerWithDeviceDTO getOwnersWithDeviceIds(String owner) throws DeviceManagementDAOException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + OwnerWithDeviceDTO ownerWithDeviceDTO; + + try { + DeviceManagementDAOFactory.openConnection(); + ownerWithDeviceDTO = this.enrollmentDAO.getOwnersWithDevices(owner, tenantId); + if (ownerWithDeviceDTO == null) { + String msg = "No data found for owner: " + owner; + log.error(msg); + throw new DeviceManagementDAOException(msg); + } + List deviceIds = ownerWithDeviceDTO.getDeviceIds(); + if (deviceIds != null) { + ownerWithDeviceDTO.setDeviceCount(deviceIds.size()); + } else { + ownerWithDeviceDTO.setDeviceCount(0); + } + } catch (DeviceManagementDAOException | SQLException e) { + String msg = "Error occurred while retrieving device IDs for owner: " + owner; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + 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); + if (deviceOwnerWithStatus == null) { + throw new DeviceManagementDAOException("No data found for device ID: " + deviceId); + } + List deviceIds = deviceOwnerWithStatus.getDeviceIds(); + if (deviceIds != null) { + deviceOwnerWithStatus.setDeviceCount(deviceIds.size()); + } else { + deviceOwnerWithStatus.setDeviceCount(0); + } + } 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(); + } + return deviceOwnerWithStatus; + } + + @Override + public List getDevicesByTenantId(int tenantId) throws DeviceManagementDAOException { + List devices; + try { + DeviceManagementDAOFactory.openConnection(); + devices = enrollmentDAO.getDevicesByTenantId(tenantId); + if (devices == null || devices.isEmpty()) { + String msg = "No devices found for tenant ID: " + tenantId; + log.error(msg); + throw new DeviceManagementDAOException(msg); + } + } 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); + OperationDTO operationDetails; + try { + OperationManagementDAOFactory.openConnection(); + operationDetails = this.operationDAO.getOperationDetailsById(operationId, tenantId); + if (operationDetails == null) { + String msg = "No operation details found for operation ID: " + operationId; + log.error(msg); + throw new OperationManagementException(msg); + } + } catch (SQLException | OperationManagementDAOException e) { + String msg = "Error occurred while retrieving operation details for operation ID: " + operationId; + log.error(msg, e); + throw new OperationManagementException(msg, e); + } finally { + OperationManagementDAOFactory.closeConnection(); + } + return operationDetails; + } + } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderService.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderService.java index 2c741730bd..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 @@ -30,6 +30,7 @@ import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupAlreadyExistEx import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupManagementException; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupNotExistException; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.RoleDoesNotExistException; +import io.entgra.device.mgt.core.device.mgt.core.dto.GroupDetailsDTO; import org.wso2.carbon.user.api.AuthorizationManager; import org.wso2.carbon.user.api.UserStoreManager; @@ -371,4 +372,16 @@ public interface GroupManagementProviderService { DeviceTypesOfGroups getDeviceTypesOfGroups(List identifiers) throws GroupManagementException; DeviceGroup getUserOwnGroup(int groupId, boolean requireGroupProps, int depth) throws GroupManagementException; + + /** + * Get group details and device IDs for a given group name. + * + * @param groupName the name of the group. + * @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 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 88aad71dcd..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 @@ -26,13 +26,13 @@ import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupAlreadyExistEx import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupManagementException; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupNotExistException; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.RoleDoesNotExistException; +import io.entgra.device.mgt.core.device.mgt.core.dto.GroupDetailsDTO; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOException; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.core.dao.GroupDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.GroupManagementDAOException; import io.entgra.device.mgt.core.device.mgt.core.dao.GroupManagementDAOFactory; -import io.entgra.device.mgt.core.device.mgt.core.permission.mgt.PermissionManagerServiceImpl; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -1629,6 +1629,7 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid createGroupWithChildren(nextParentGroup, childrenGroups, requireGroupProps, tenantId, depth, counter); } } + @Override public DeviceTypesOfGroups getDeviceTypesOfGroups(List identifiers) throws GroupManagementException { DeviceTypesOfGroups deviceTypesOfGroups = new DeviceTypesOfGroups(); @@ -1685,4 +1686,37 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid return deviceTypesOfGroups; } + + @Override + public GroupDetailsDTO getGroupDetailsWithDevices(String groupName, int offset, int limit) + throws GroupManagementException { + if (log.isDebugEnabled()) { + log.debug("Retrieving group details and device IDs for group: " + groupName); + } + int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId(); + GroupDetailsDTO groupDetailsWithDevices; + + try { + GroupManagementDAOFactory.openConnection(); + groupDetailsWithDevices = this.groupDAO.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); + throw new GroupManagementException(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); + } + + if (groupDetailsWithDevices != null) { + List deviceIds = groupDetailsWithDevices.getDeviceIds(); + if (deviceIds != null) { + groupDetailsWithDevices.setDeviceCount(deviceIds.size()); + } else { + groupDetailsWithDevices.setDeviceCount(0); + } + } + + return groupDetailsWithDevices; + } + } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.extensions/src/test/java/io/entgra/device/mgt/core/device/mgt/extensions/device/type/template/BaseExtensionsTest.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.extensions/src/test/java/io/entgra/device/mgt/core/device/mgt/extensions/device/type/template/BaseExtensionsTest.java index aff8d17eda..992969aa92 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.extensions/src/test/java/io/entgra/device/mgt/core/device/mgt/extensions/device/type/template/BaseExtensionsTest.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.extensions/src/test/java/io/entgra/device/mgt/core/device/mgt/extensions/device/type/template/BaseExtensionsTest.java @@ -18,6 +18,7 @@ package io.entgra.device.mgt.core.device.mgt.extensions.device.type.template; +import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory; import org.apache.tomcat.jdbc.pool.PoolProperties; import org.mockito.Mockito; import org.testng.annotations.BeforeSuite; @@ -131,6 +132,7 @@ public class BaseExtensionsTest { readDataSourceConfig(datasourceLocation + DATASOURCE_EXT)); DeviceManagementDAOFactory.init(dataSource); MetadataManagementDAOFactory.init(dataSource); + OperationManagementDAOFactory.init(dataSource); } protected DataSourceConfig readDataSourceConfig(String configLocation) throws DeviceManagementException {