From 7616c2255c054e21a10f4f85ced02513f94ab385 Mon Sep 17 00:00:00 2001 From: ashvini Date: Wed, 29 May 2024 12:44:59 +0530 Subject: [PATCH 01/17] Add filter to get Web apps in Enrollment Application Install Add filter file --- .../mgt/core/application/mgt/common/Filter.java | 13 +++++++++++++ .../impl/application/GenericApplicationDAOImpl.java | 12 ++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/Filter.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/Filter.java index 272e9ba8a3..88f7e90a0a 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/Filter.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/Filter.java @@ -118,6 +118,11 @@ public class Filter { */ private boolean isNotRetired; + /** + * To check whether web applications should be returned + */ + private boolean withWebApps; + public int getLimit() { return limit; } @@ -221,4 +226,12 @@ public class Filter { public void setNotRetired(boolean notRetired) { isNotRetired = notRetired; } + + public boolean isWithWebApps() { + return withWebApps; + } + + public void setWithWebApps(boolean withWebApps) { + this.withWebApps = withWebApps; + } } 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/application/GenericApplicationDAOImpl.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/application/GenericApplicationDAOImpl.java index 7c71880fa6..618149cd72 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/application/GenericApplicationDAOImpl.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/application/GenericApplicationDAOImpl.java @@ -178,7 +178,11 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic sql += "AND AP_APP_RELEASE.CURRENT_STATE = ? "; } if (deviceTypeId != -1) { - sql += "AND AP_APP.DEVICE_TYPE_ID = ? "; + sql += "AND (AP_APP.DEVICE_TYPE_ID = ? "; + if (filter.isWithWebApps()) { + sql += "OR AP_APP.DEVICE_TYPE_ID = 0 "; + } + sql += ") "; } if (filter.isNotRetired()) { sql += "AND AP_APP.STATUS != 'RETIRED' "; @@ -309,7 +313,11 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic sql += " AND AP_APP_RELEASE.CURRENT_STATE = ?"; } if (deviceTypeId != -1) { - sql += " AND AP_APP.DEVICE_TYPE_ID = ?"; + sql += "AND (AP_APP.DEVICE_TYPE_ID = ? "; + if (filter.isWithWebApps()) { + sql += "OR AP_APP.DEVICE_TYPE_ID = 0 "; + } + sql += ") "; } if (filter.isNotRetired()) { sql += " AND AP_APP.STATUS != 'RETIRED'"; From b0362c58256ed0a3a1c6d8a7d9d456e9190a3c91 Mon Sep 17 00:00:00 2001 From: prathabanKavin Date: Fri, 7 Jun 2024 21:57:21 +0530 Subject: [PATCH 02/17] Fix devices of a group not loading --- .../mgt/core/dao/impl/device/GenericDeviceDAOImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java index efe07d1335..d1ea236645 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java @@ -646,8 +646,7 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { } @Override - public List searchDevicesInGroup(PaginationRequest request, int tenantId) - throws DeviceManagementDAOException { + public List searchDevicesInGroup(PaginationRequest request, int tenantId) throws DeviceManagementDAOException { List devices = null; int groupId = request.getGroupId(); String deviceType = request.getDeviceType(); @@ -687,6 +686,7 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { "gd.DESCRIPTION, " + "gd.NAME, " + "gd.DEVICE_IDENTIFICATION, " + + "gd.LAST_UPDATED_TIMESTAMP " + "FROM " + "(SELECT d.ID AS DEVICE_ID, " + "d.DESCRIPTION, " + @@ -708,10 +708,10 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { sql = sql + " WHERE 1 = 1"; //Add query for last updated timestamp if (since != null) { - sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?"; + sql = sql + " AND gd.LAST_UPDATED_TIMESTAMP > ?"; isSinceProvided = true; } - sql = sql + " ) d1 WHERE d1.DEVICE_ID = e.DEVICE_ID AND TENANT_ID = ? "; + sql = sql + " ) d1 WHERE d1.DEVICE_ID = e.DEVICE_ID AND e.TENANT_ID = ? "; //Add the query for device-type if (deviceType != null && !deviceType.isEmpty()) { sql = sql + " AND e.DEVICE_TYPE = ?"; From 1aec609bff712089d658ee56608967286658efaf Mon Sep 17 00:00:00 2001 From: Lasantha Dharmakeerthi Date: Mon, 10 Jun 2024 07:43:29 +0000 Subject: [PATCH 03/17] Fix SQL error --- .../core/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java index 58bfed7d4a..ec03136c6b 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java @@ -1716,7 +1716,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { String sql = "SELECT d.ID AS DEVICE_ID, d.DESCRIPTION, d.NAME AS DEVICE_NAME, d.LAST_UPDATED_TIMESTAMP, " + "e.DEVICE_TYPE, e.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.IS_TRANSFERRED, " + "e.DATE_OF_LAST_UPDATE, e.DATE_OF_ENROLMENT, e.ENROLMENT_ID FROM " + - "(SELECT e.ID, e.DEVICE_ID, e.DEVICE_TYPE, e.OWNER, " + + "(SELECT e.ID, e.DEVICE_ID, e.DEVICE_TYPE, e.DEVICE_IDENTIFICATION, e.OWNER, " + "e.OWNERSHIP, e.STATUS, e.IS_TRANSFERRED, e.DATE_OF_ENROLMENT, e.DATE_OF_LAST_UPDATE, e.ID AS " + "ENROLMENT_ID FROM DM_ENROLMENT e WHERE TENANT_ID = ? AND STATUS = ?) e, " + "DM_DEVICE d WHERE d.ID = e.DEVICE_ID AND d.TENANT_ID = ?"; From d443fef6e0314ab2a8c3799405d1ced60d096bcc Mon Sep 17 00:00:00 2001 From: pramilaniroshan Date: Tue, 11 Jun 2024 10:38:54 +0530 Subject: [PATCH 04/17] Add missing test cases for DevicePersistTests and GroupPersistTests --- .../mgt/core/common/TestDataHolder.java | 18 + .../mgt/core/dao/DevicePersistTests.java | 514 ++++++++++++++++++ .../mgt/core/dao/GroupPersistTests.java | 306 ++++++++++- 3 files changed, 817 insertions(+), 21 deletions(-) diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/test/java/io/entgra/device/mgt/core/device/mgt/core/common/TestDataHolder.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/test/java/io/entgra/device/mgt/core/device/mgt/core/common/TestDataHolder.java index bea2094a77..322b2b449d 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/test/java/io/entgra/device/mgt/core/device/mgt/core/common/TestDataHolder.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/test/java/io/entgra/device/mgt/core/device/mgt/core/common/TestDataHolder.java @@ -23,6 +23,7 @@ import io.entgra.device.mgt.core.device.mgt.common.EnrolmentInfo; import io.entgra.device.mgt.core.device.mgt.common.MonitoringOperation; import io.entgra.device.mgt.core.device.mgt.common.OperationMonitoringTaskConfig; import io.entgra.device.mgt.core.device.mgt.common.app.mgt.Application; +import io.entgra.device.mgt.core.device.mgt.common.device.details.DeviceData; import io.entgra.device.mgt.core.device.mgt.common.device.details.DeviceInfo; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup; import io.entgra.device.mgt.core.device.mgt.common.notification.mgt.Notification; @@ -32,6 +33,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Properties; +import java.util.Calendar; public class TestDataHolder { @@ -39,11 +41,18 @@ public class TestDataHolder { public final static Integer SUPER_TENANT_ID = -1234; public final static String SUPER_TENANT_DOMAIN = "carbon.super"; public final static String initialDeviceIdentifier = "12345"; + public final static String initialDeviceName = "TEST-DEVICE"; public final static String OWNER = "admin"; public static final String OPERATION_CONFIG = "TEST-OPERATION-"; public static Device initialTestDevice; public static DeviceType initialTestDeviceType; + public static Date getTimeBefore(int minutes) { + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.MINUTE, -minutes); + return calendar.getTime(); + } + public static Device generateDummyDeviceData(String deviceType) { Device device = new Device(); device.setEnrolmentInfo(generateEnrollmentInfo(new Date().getTime(), new Date().getTime(), OWNER, EnrolmentInfo @@ -141,6 +150,15 @@ public class TestDataHolder { return device; } + public static DeviceData generateDummyDevice(DeviceIdentifier deviceIdentifier) { + DeviceData deviceData = new DeviceData(); + deviceData.setDeviceIdentifier(deviceIdentifier); + deviceData.setDeviceOwner(OWNER); + deviceData.setDeviceOwnership(EnrolmentInfo.OwnerShip.BYOD.toString()); + deviceData.setLastModifiedDate(getTimeBefore(1)); + return deviceData; + } + public static DeviceType generateDeviceTypeData(String devTypeName) { DeviceType deviceType = new DeviceType(); deviceType.setName(devTypeName); diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/test/java/io/entgra/device/mgt/core/device/mgt/core/dao/DevicePersistTests.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/test/java/io/entgra/device/mgt/core/device/mgt/core/dao/DevicePersistTests.java index e76a4f7850..a8bc1b6924 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/test/java/io/entgra/device/mgt/core/device/mgt/core/dao/DevicePersistTests.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/test/java/io/entgra/device/mgt/core/device/mgt/core/dao/DevicePersistTests.java @@ -18,7 +18,13 @@ package io.entgra.device.mgt.core.device.mgt.core.dao; +import io.entgra.device.mgt.core.device.mgt.common.EnrolmentInfo; import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; +import io.entgra.device.mgt.core.device.mgt.common.device.details.DeviceData; +import io.entgra.device.mgt.core.device.mgt.common.geo.service.GeoCluster; +import io.entgra.device.mgt.core.device.mgt.common.geo.service.GeoCoordinate; +import io.entgra.device.mgt.core.device.mgt.common.geo.service.GeoQuery; +import org.apache.commons.collections.map.SingletonMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.testng.Assert; @@ -34,6 +40,7 @@ import io.entgra.device.mgt.core.device.mgt.core.common.TestDataHolder; import io.entgra.device.mgt.core.device.mgt.core.dto.DeviceType; import java.sql.*; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -89,6 +96,7 @@ public class DevicePersistTests extends BaseDeviceManagementTest { public void testAddDeviceTest() { int tenantId = TestDataHolder.SUPER_TENANT_ID; Device device = TestDataHolder.generateDummyDeviceData(TestDataHolder.TEST_DEVICE_TYPE); + device.setName(TestDataHolder.initialDeviceName); try { DeviceManagementDAOFactory.beginTransaction(); @@ -275,6 +283,7 @@ public class DevicePersistTests extends BaseDeviceManagementTest { pr.setStatusList(Collections.singletonList(Status.ACTIVE.name())); List results = deviceDAO.getDevicesByStatus(pr, TestDataHolder.SUPER_TENANT_ID); Assert.assertEquals(1, results.size(), "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); } catch (DeviceManagementDAOException e) { throw new DeviceManagementDAOException("Error occurred while retrieving the current status of the " + "enrolment", e); @@ -283,4 +292,509 @@ public class DevicePersistTests extends BaseDeviceManagementTest { } } + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDevicesByTenantId() throws DeviceManagementDAOException, TransactionManagementException { + try { + DeviceManagementDAOFactory.beginTransaction(); + List results = deviceDAO.getDevices(TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(1, results.size(), "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceByDeviceId() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + try { + DeviceManagementDAOFactory.beginTransaction(); + Device results = deviceDAO.getDevice(device.getDeviceIdentifier(), TestDataHolder.SUPER_TENANT_ID); + Assert.assertNotNull(results.getDeviceIdentifier(), "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceByDeviceIdentifierWithTenantId() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + try { + DeviceManagementDAOFactory.beginTransaction(); + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()); + Device results = deviceDAO.getDevice(deviceIdentifier, TestDataHolder.SUPER_TENANT_ID); + Assert.assertNotNull(results.getDeviceIdentifier(), "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceByDeviceData() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()); + DeviceData deviceData = TestDataHolder.generateDummyDevice(deviceIdentifier); + try { + DeviceManagementDAOFactory.beginTransaction(); + Device results = deviceDAO.getDevice(deviceData, TestDataHolder.SUPER_TENANT_ID); + Assert.assertNotNull(results.getDeviceIdentifier(), "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceByOwner() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()); + try { + DeviceManagementDAOFactory.beginTransaction(); + Device results = deviceDAO.getDevice(deviceIdentifier, TestDataHolder.OWNER, TestDataHolder.SUPER_TENANT_ID); + Assert.assertNotNull(results.getDeviceIdentifier(), "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceByDateSince() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()); + try { + DeviceManagementDAOFactory.beginTransaction(); + Device results = deviceDAO.getDevice(deviceIdentifier, TestDataHolder.getTimeBefore(1), TestDataHolder.SUPER_TENANT_ID); + Assert.assertNotNull(results.getDeviceIdentifier(), "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceByDateSinceWithDeviceId() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + try { + DeviceManagementDAOFactory.beginTransaction(); + Device results = deviceDAO.getDevice(device.getDeviceIdentifier(), TestDataHolder.getTimeBefore(1), TestDataHolder.SUPER_TENANT_ID); + Assert.assertNotNull(results.getDeviceIdentifier(), "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceByEnrollmentStatus() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()); + try { + DeviceManagementDAOFactory.beginTransaction(); + Device results = deviceDAO.getDevice(deviceIdentifier, Status.ACTIVE, TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(device.getDeviceIdentifier(), results.getDeviceIdentifier(), "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceByDeviceIdentifier() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()); + try { + DeviceManagementDAOFactory.beginTransaction(); + SingletonMap results = deviceDAO.getDevice(deviceIdentifier); + Assert.assertNotNull(results, "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceByDeviceType() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + try { + DeviceManagementDAOFactory.beginTransaction(); + List results = deviceDAO.getDevices(device.getType(), TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(1, results.size(), "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getAllocatedDevices() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + try { + DeviceManagementDAOFactory.beginTransaction(); + List results = deviceDAO.getAllocatedDevices(device.getType(), TestDataHolder.SUPER_TENANT_ID, 1, 0); + Assert.assertEquals(1, results.size(), "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDevicesOfUser() throws DeviceManagementDAOException, TransactionManagementException { + try { + DeviceManagementDAOFactory.beginTransaction(); + List results = deviceDAO.getDevicesOfUser(TestDataHolder.OWNER, TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(1, results.size(), "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDevicesOfUserWithDeviceType() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + try { + DeviceManagementDAOFactory.beginTransaction(); + List results = deviceDAO.getDevicesOfUser(TestDataHolder.OWNER, device.getType(), TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(1, results.size(), "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDevicesOfUserWithDeviceStatus() throws DeviceManagementDAOException, TransactionManagementException { + List status = new ArrayList<>() ; + status.add(Status.ACTIVE.name()); + try { + DeviceManagementDAOFactory.beginTransaction(); + List results = deviceDAO.getDevicesOfUser(TestDataHolder.OWNER, TestDataHolder.SUPER_TENANT_ID, status); + Assert.assertEquals(1, results.size(), "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getCountOfDevicesInGroup() throws DeviceManagementDAOException, TransactionManagementException { + PaginationRequest pr = new PaginationRequest(0, 10); + pr.setGroupId(1); + try { + DeviceManagementDAOFactory.beginTransaction(); + int results = deviceDAO.getCountOfDevicesInGroup(pr, TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(0, results, "No device count returned in group"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device count" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceCountWithOwner() throws DeviceManagementDAOException, TransactionManagementException { + try { + DeviceManagementDAOFactory.beginTransaction(); + int results = deviceDAO.getDeviceCount(TestDataHolder.OWNER, TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(1, results, "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceCountWithType() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + try { + DeviceManagementDAOFactory.beginTransaction(); + int results = deviceDAO.getDeviceCount(device.getType(), Status.ACTIVE.name(), TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(1, results, "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void setEnrolmentStatusInBulk() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + List devices = new ArrayList<>() ; + devices.add(device.getDeviceIdentifier()); + try { + DeviceManagementDAOFactory.beginTransaction(); + boolean results = deviceDAO.setEnrolmentStatusInBulk(device.getType(), Status.ACTIVE.name(),TestDataHolder.SUPER_TENANT_ID, devices ); + Assert.assertTrue(results, "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceCount() throws DeviceManagementDAOException, TransactionManagementException { + try { + DeviceManagementDAOFactory.beginTransaction(); + int results = deviceDAO.getDeviceCount(TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(1, results, "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceCountWithPagination() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + PaginationRequest pr = new PaginationRequest(0, 10); + pr.setDeviceName(device.getName()); + pr.setDeviceType(device.getType()); + pr.setOwner(TestDataHolder.OWNER); + try { + DeviceManagementDAOFactory.beginTransaction(); + int results = deviceDAO.getDeviceCount(pr, TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(1, results, "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceCountByType() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + try { + DeviceManagementDAOFactory.beginTransaction(); + int results = deviceDAO.getDeviceCountByType(device.getType(), TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(1, results, "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceCountByUser() throws DeviceManagementDAOException, TransactionManagementException { + try { + DeviceManagementDAOFactory.beginTransaction(); + int results = deviceDAO.getDeviceCountByUser(TestDataHolder.OWNER, TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(1, results, "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceCountByName() throws DeviceManagementDAOException, TransactionManagementException { + try { + DeviceManagementDAOFactory.beginTransaction(); + int results = deviceDAO.getDeviceCountByName(TestDataHolder.initialDeviceName, TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(1, results, "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceCountByOwnership() throws DeviceManagementDAOException, TransactionManagementException { + try { + DeviceManagementDAOFactory.beginTransaction(); + int results = deviceDAO.getDeviceCountByOwnership(EnrolmentInfo.OwnerShip.BYOD.name(), TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(1, results, "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceCountByStatus() throws DeviceManagementDAOException, TransactionManagementException { + try { + DeviceManagementDAOFactory.beginTransaction(); + int results = deviceDAO.getDeviceCountByStatus(Status.ACTIVE.name(), TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(1, results, "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceCountByStatusWithType() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + try { + DeviceManagementDAOFactory.beginTransaction(); + int results = deviceDAO.getDeviceCountByStatus(device.getType(), Status.ACTIVE.name(), TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(1, results, "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getActiveEnrolment() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()); + try { + DeviceManagementDAOFactory.beginTransaction(); + EnrolmentInfo results = deviceDAO.getActiveEnrolment(deviceIdentifier, TestDataHolder.SUPER_TENANT_ID); + Assert.assertEquals(Status.ACTIVE, results.getStatus(), "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDeviceEnrolledTenants() throws DeviceManagementDAOException, TransactionManagementException { + try { + DeviceManagementDAOFactory.beginTransaction(); + List results = deviceDAO.getDeviceEnrolledTenants(); + Assert.assertEquals(1, results.size(), "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void findGeoClusters() throws DeviceManagementDAOException, TransactionManagementException { + GeoQuery geoQuery = new GeoQuery(new GeoCoordinate(123, 123), new GeoCoordinate(123, 123), 12345); + try { + DeviceManagementDAOFactory.beginTransaction(); + List results = deviceDAO.findGeoClusters(geoQuery, TestDataHolder.SUPER_TENANT_ID); + Assert.assertNotNull(results, "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getAppNotInstalledDevices() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + PaginationRequest pr = new PaginationRequest(0, 10); + pr.setDeviceType(device.getType()); + try { + DeviceManagementDAOFactory.beginTransaction(); + List results = deviceDAO.getAppNotInstalledDevices(pr, TestDataHolder.SUPER_TENANT_ID, "com.google.calc", "1.0.0"); + Assert.assertNotNull(results, "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getCountOfAppNotInstalledDevices() throws DeviceManagementDAOException, TransactionManagementException { + Device device = TestDataHolder.initialTestDevice; + PaginationRequest pr = new PaginationRequest(0, 10); + pr.setDeviceType(device.getType()); + try { + DeviceManagementDAOFactory.beginTransaction(); + int results = deviceDAO.getCountOfAppNotInstalledDevices(pr, TestDataHolder.SUPER_TENANT_ID, "com.google.calc", "1.0.0"); + Assert.assertEquals(1, results, "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getDevicesByEncryptionStatus() throws DeviceManagementDAOException, TransactionManagementException { + PaginationRequest pr = new PaginationRequest(0, 10); + try { + DeviceManagementDAOFactory.beginTransaction(); + List results = deviceDAO.getDevicesByEncryptionStatus(pr, TestDataHolder.SUPER_TENANT_ID, false); + Assert.assertNotNull(results, "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = "testAddDeviceTest") + public void getCountOfDevicesByEncryptionStatus() throws DeviceManagementDAOException, TransactionManagementException { + try { + DeviceManagementDAOFactory.beginTransaction(); + int results = deviceDAO.getCountOfDevicesByEncryptionStatus(TestDataHolder.SUPER_TENANT_ID, true); + Assert.assertEquals(0, results, "No device returned"); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the device" + e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } + } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/test/java/io/entgra/device/mgt/core/device/mgt/core/dao/GroupPersistTests.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/test/java/io/entgra/device/mgt/core/device/mgt/core/dao/GroupPersistTests.java index 0ea871994c..e484bc4923 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/test/java/io/entgra/device/mgt/core/device/mgt/core/dao/GroupPersistTests.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/test/java/io/entgra/device/mgt/core/device/mgt/core/dao/GroupPersistTests.java @@ -18,6 +18,8 @@ package io.entgra.device.mgt.core.device.mgt.core.dao; +import io.entgra.device.mgt.core.device.mgt.common.EnrolmentInfo; +import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.testng.Assert; @@ -54,19 +56,18 @@ public class GroupPersistTests extends BaseDeviceManagementTest { GroupManagementDAOFactory.beginTransaction(); groupId = groupDAO.addGroup(deviceGroup, TestDataHolder.SUPER_TENANT_ID); GroupManagementDAOFactory.commitTransaction(); - GroupManagementDAOFactory.closeConnection(); log.debug("Group added to database. ID: " + groupId); } catch (GroupManagementDAOException e) { GroupManagementDAOFactory.rollbackTransaction(); - GroupManagementDAOFactory.closeConnection(); String msg = "Error occurred while adding device type '" + deviceGroup.getName() + "'."; log.error(msg, e); Assert.fail(msg, e); } catch (TransactionManagementException e) { - GroupManagementDAOFactory.closeConnection(); String msg = "Error occurred while initiating transaction."; log.error(msg, e); Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); } DeviceGroup group = getGroupById(groupId); if (!isMock()) { @@ -83,22 +84,21 @@ public class GroupPersistTests extends BaseDeviceManagementTest { request.setGroupName(null); request.setOwner(null); List groups = groupDAO.getGroups(request, TestDataHolder.SUPER_TENANT_ID); - GroupManagementDAOFactory.closeConnection(); if (!isMock()) { Assert.assertNotEquals(groups.size(), 0, "No groups found"); Assert.assertNotNull(groups.get(0), "Group is null"); log.debug("No of Groups found: " + groups.size()); } } catch (GroupManagementDAOException e) { - GroupManagementDAOFactory.closeConnection(); String msg = "Error occurred while find group by name."; log.error(msg, e); Assert.fail(msg, e); } catch (SQLException e) { - GroupManagementDAOFactory.closeConnection(); String msg = "Error occurred while opening a connection to the data source."; log.error(msg, e); Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); } } @@ -114,21 +114,20 @@ public class GroupPersistTests extends BaseDeviceManagementTest { } GroupManagementDAOFactory.commitTransaction(); List roles = groupDAO.getRoles(groupId, TestDataHolder.SUPER_TENANT_ID); - GroupManagementDAOFactory.closeConnection(); if (!isMock()) { Assert.assertEquals(roles, addedRoles, "Added roles are not equal to returned roles."); } log.debug("Group shared with roles."); } catch (GroupManagementDAOException e) { - GroupManagementDAOFactory.closeConnection(); String msg = "Error occurred while find group by name."; log.error(msg, e); Assert.fail(msg, e); } catch (TransactionManagementException e) { - GroupManagementDAOFactory.closeConnection(); String msg = "Error occurred while opening a connection to the data source."; log.error(msg, e); Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); } } @@ -141,22 +140,21 @@ public class GroupPersistTests extends BaseDeviceManagementTest { roles.remove(0); } List deviceGroups = groupDAO.getGroups(roles.toArray(new String[roles.size()]), TestDataHolder.SUPER_TENANT_ID); - GroupManagementDAOFactory.closeConnection(); if (!isMock()) { Assert.assertEquals(deviceGroups.size(), 1, "Unexpected number of device groups found with role."); Assert.assertEquals(deviceGroups.get(0).getGroupId(), groupId, "Unexpected groupId found with role."); } log.debug("Group found for given roles."); } catch (GroupManagementDAOException e) { - GroupManagementDAOFactory.closeConnection(); String msg = "Error occurred while getting groups shared with roles."; log.error(msg, e); Assert.fail(msg, e); } catch (SQLException e) { - GroupManagementDAOFactory.closeConnection(); String msg = "Error occurred while opening a connection to the data source."; log.error(msg, e); Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); } } @@ -271,19 +269,18 @@ public class GroupPersistTests extends BaseDeviceManagementTest { GroupManagementDAOFactory.beginTransaction(); groupDAO.updateGroup(group, groupId, TestDataHolder.SUPER_TENANT_ID); GroupManagementDAOFactory.commitTransaction(); - GroupManagementDAOFactory.closeConnection(); log.debug("Group updated"); } catch (GroupManagementDAOException e) { GroupManagementDAOFactory.rollbackTransaction(); - GroupManagementDAOFactory.closeConnection(); String msg = "Error occurred while updating group details."; log.error(msg, e); Assert.fail(msg, e); } catch (TransactionManagementException e) { - GroupManagementDAOFactory.closeConnection(); String msg = "Error occurred while initiating transaction."; log.error(msg, e); Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); } if (!isMock()) { group = getGroupById(groupId); @@ -301,20 +298,20 @@ public class GroupPersistTests extends BaseDeviceManagementTest { GroupManagementDAOFactory.beginTransaction(); groupDAO.deleteGroup(group.getGroupId(), TestDataHolder.SUPER_TENANT_ID); GroupManagementDAOFactory.commitTransaction(); - GroupManagementDAOFactory.closeConnection(); log.debug("Group deleted"); } catch (GroupManagementDAOException e) { GroupManagementDAOFactory.rollbackTransaction(); - GroupManagementDAOFactory.closeConnection(); String msg = "Error occurred while updating group details."; log.error(msg, e); Assert.fail(msg, e); } catch (TransactionManagementException e) { - GroupManagementDAOFactory.closeConnection(); String msg = "Error occurred while initiating transaction."; log.error(msg, e); Assert.fail(msg, e); } + finally { + GroupManagementDAOFactory.closeConnection(); + } group = getGroupById(groupId); if (!isMock()) { Assert.assertNull(group, "Group is not deleted"); @@ -325,23 +322,290 @@ public class GroupPersistTests extends BaseDeviceManagementTest { try { GroupManagementDAOFactory.openConnection(); DeviceGroup deviceGroup = groupDAO.getGroup(groupId, TestDataHolder.SUPER_TENANT_ID); - GroupManagementDAOFactory.closeConnection(); if (deviceGroup == null && isMock()) { deviceGroup = new DeviceGroup(); deviceGroup.setGroupId(groupId); } return deviceGroup; } catch (GroupManagementDAOException e) { - GroupManagementDAOFactory.closeConnection(); String msg = "Error occurred while retrieving group details."; log.error(msg, e); Assert.fail(msg, e); } catch (SQLException e) { - GroupManagementDAOFactory.closeConnection(); String msg = "Error occurred while opening a connection to the data source."; log.error(msg, e); Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); } return null; } + + @Test(dependsOnMethods = {"addDeviceToGroupTest"}) + public void getAllDevicesOfGroupWithStatus() { + DeviceGroup deviceGroup = getGroupById(groupId); + Assert.assertNotNull(deviceGroup, "Group is null"); + List deviceStatus = new ArrayList<>(); + deviceStatus.add(EnrolmentInfo.Status.ACTIVE.name()); + try { + GroupManagementDAOFactory.beginTransaction(); + groupDAO.getAllDevicesOfGroup(deviceGroup.getName(), deviceStatus, TestDataHolder.SUPER_TENANT_ID); + GroupManagementDAOFactory.commitTransaction(); + } catch (GroupManagementDAOException e) { + GroupManagementDAOFactory.rollbackTransaction(); + String msg = "Error occurred while getting devices of group '" + groupId + "'."; + log.error(msg, e); + Assert.fail(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while initiating transaction."; + log.error(msg, e); + Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = {"addDeviceToGroupTest"}) + public void getAllDevicesOfGroup() { + DeviceGroup deviceGroup = getGroupById(groupId); + Assert.assertNotNull(deviceGroup, "Group is null"); + try { + GroupManagementDAOFactory.beginTransaction(); + groupDAO.getAllDevicesOfGroup(deviceGroup.getName(), TestDataHolder.SUPER_TENANT_ID); + GroupManagementDAOFactory.commitTransaction(); + } catch (GroupManagementDAOException e) { + GroupManagementDAOFactory.rollbackTransaction(); + String msg = "Error occurred while getting devices of group '" + groupId + "'."; + log.error(msg, e); + Assert.fail(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while initiating transaction."; + log.error(msg, e); + Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = {"addDeviceToGroupTest"}) + public void getGroupUnassignedDevices() { + DeviceGroup deviceGroup = getGroupById(groupId); + Device device = TestDataHolder.initialTestDevice; + Assert.assertNotNull(deviceGroup, "Group is null"); + PaginationRequest pr = new PaginationRequest(0,10); + pr.setDeviceType(device.getType()); + List groupNames = new ArrayList<>(); + groupNames.add(deviceGroup.getName()); + try { + GroupManagementDAOFactory.beginTransaction(); + groupDAO.getGroupUnassignedDevices(pr, groupNames); + GroupManagementDAOFactory.commitTransaction(); + } catch (GroupManagementDAOException e) { + GroupManagementDAOFactory.rollbackTransaction(); + String msg = "Error occurred while getting devices of group '" + groupId + "'."; + log.error(msg, e); + Assert.fail(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while initiating transaction."; + log.error(msg, e); + Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = {"addDeviceToGroupTest"}) + public void getOwnGroupsCount() { + try { + GroupManagementDAOFactory.beginTransaction(); + groupDAO.getOwnGroupsCount(TestDataHolder.OWNER, TestDataHolder.SUPER_TENANT_ID, "/"); + GroupManagementDAOFactory.commitTransaction(); + } catch (GroupManagementDAOException e) { + GroupManagementDAOFactory.rollbackTransaction(); + String msg = "Error occurred while getting own group count for '" + TestDataHolder.OWNER + "'."; + log.error(msg, e); + Assert.fail(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while initiating transaction."; + log.error(msg, e); + Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = {"addDeviceToGroupTest"}) + public void getOwnGroups() { + try { + GroupManagementDAOFactory.beginTransaction(); + groupDAO.getOwnGroups(TestDataHolder.OWNER, TestDataHolder.SUPER_TENANT_ID); + GroupManagementDAOFactory.commitTransaction(); + } catch (GroupManagementDAOException e) { + GroupManagementDAOFactory.rollbackTransaction(); + String msg = "Error occurred while getting own groups for '" + TestDataHolder.OWNER + "'."; + log.error(msg, e); + Assert.fail(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while initiating transaction."; + log.error(msg, e); + Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = {"addDeviceToGroupTest"}) + public void getOwnGroupIds() { + try { + GroupManagementDAOFactory.beginTransaction(); + groupDAO.getOwnGroupIds(TestDataHolder.OWNER, TestDataHolder.SUPER_TENANT_ID); + GroupManagementDAOFactory.commitTransaction(); + } catch (GroupManagementDAOException e) { + GroupManagementDAOFactory.rollbackTransaction(); + String msg = "Error occurred while getting own group Ids for '" + TestDataHolder.OWNER + "'."; + log.error(msg, e); + Assert.fail(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while initiating transaction."; + log.error(msg, e); + Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = {"addDeviceToGroupTest"}) + public void getDeviceCount() { + DeviceGroup deviceGroup = getGroupById(groupId); + Assert.assertNotNull(deviceGroup, "Group is null"); + try { + GroupManagementDAOFactory.beginTransaction(); + groupDAO.getDeviceCount(deviceGroup.getGroupId(), TestDataHolder.SUPER_TENANT_ID); + GroupManagementDAOFactory.commitTransaction(); + } catch (GroupManagementDAOException e) { + GroupManagementDAOFactory.rollbackTransaction(); + String msg = "Error occurred while getting device count for '" +groupId+ "'."; + log.error(msg, e); + Assert.fail(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while initiating transaction."; + log.error(msg, e); + Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = {"addDeviceToGroupTest"}) + public void isDeviceMappedToGroup() { + DeviceGroup deviceGroup = getGroupById(groupId); + Device device = TestDataHolder.initialTestDevice; + Assert.assertNotNull(deviceGroup, "Group is null"); + try { + GroupManagementDAOFactory.beginTransaction(); + groupDAO.isDeviceMappedToGroup(deviceGroup.getGroupId(), Integer.parseInt(device.getDeviceIdentifier()), TestDataHolder.SUPER_TENANT_ID); + GroupManagementDAOFactory.commitTransaction(); + } catch (GroupManagementDAOException e) { + GroupManagementDAOFactory.rollbackTransaction(); + String msg = "Error occurred while checking device map to group for '" +groupId+ "'."; + log.error(msg, e); + Assert.fail(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while initiating transaction."; + log.error(msg, e); + Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = {"addDeviceToGroupTest"}) + public void getGroupCount() { + DeviceGroup deviceGroup = getGroupById(groupId); + GroupPaginationRequest pr = new GroupPaginationRequest(0,10); + pr.setGroupName(deviceGroup.getName()); + Assert.assertNotNull(deviceGroup, "Group is null"); + try { + GroupManagementDAOFactory.beginTransaction(); + groupDAO.getGroupCount(pr, TestDataHolder.SUPER_TENANT_ID); + GroupManagementDAOFactory.commitTransaction(); + } catch (GroupManagementDAOException e) { + GroupManagementDAOFactory.rollbackTransaction(); + String msg = "Error occurred while getting group count for '" +TestDataHolder.SUPER_TENANT_ID+ "'."; + log.error(msg, e); + Assert.fail(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while initiating transaction."; + log.error(msg, e); + Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = {"addDeviceToGroupTest"}) + public void getGroupCountWithStatus() { + DeviceGroup deviceGroup = getGroupById(groupId); + Assert.assertNotNull(deviceGroup, "Group is null"); + try { + GroupManagementDAOFactory.beginTransaction(); + groupDAO.getGroupCount(TestDataHolder.SUPER_TENANT_ID, EnrolmentInfo.Status.ACTIVE.name()); + GroupManagementDAOFactory.commitTransaction(); + } catch (GroupManagementDAOException e) { + GroupManagementDAOFactory.rollbackTransaction(); + String msg = "Error occurred while getting group count for" + TestDataHolder.SUPER_TENANT_ID; + log.error(msg, e); + Assert.fail(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while initiating transaction."; + log.error(msg, e); + Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = {"addDeviceToGroupTest"}) + public void getRootGroups() { + DeviceGroup deviceGroup = getGroupById(groupId); + Assert.assertNotNull(deviceGroup, "Group is null"); + try { + GroupManagementDAOFactory.beginTransaction(); + groupDAO.getRootGroups(TestDataHolder.SUPER_TENANT_ID); + GroupManagementDAOFactory.commitTransaction(); + } catch (GroupManagementDAOException e) { + GroupManagementDAOFactory.rollbackTransaction(); + String msg = "Error occurred while getting group count for " + TestDataHolder.SUPER_TENANT_ID; + log.error(msg, e); + Assert.fail(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while initiating transaction."; + log.error(msg, e); + Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); + } + } + + @Test(dependsOnMethods = {"addDeviceToGroupTest"}) + public void getAllGroupProperties() { + DeviceGroup deviceGroup = getGroupById(groupId); + Assert.assertNotNull(deviceGroup, "Group is null"); + try { + GroupManagementDAOFactory.beginTransaction(); + groupDAO.getAllGroupProperties(groupId, TestDataHolder.SUPER_TENANT_ID); + GroupManagementDAOFactory.commitTransaction(); + } catch (GroupManagementDAOException e) { + GroupManagementDAOFactory.rollbackTransaction(); + String msg = "Error occurred while getting groups for " + TestDataHolder.SUPER_TENANT_ID; + log.error(msg, e); + Assert.fail(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while initiating transaction."; + log.error(msg, e); + Assert.fail(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); + } + } } From 31c25de95663c7d25345515ff0e70e5ca3121179 Mon Sep 17 00:00:00 2001 From: Gimhan-minion Date: Thu, 13 Jun 2024 00:51:15 +0530 Subject: [PATCH 05/17] Modify permission of operation status update --- .../jaxrs/service/api/DeviceManagementService.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/DeviceManagementService.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/DeviceManagementService.java index f1e464a0d9..a028654cdc 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/DeviceManagementService.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/DeviceManagementService.java @@ -165,6 +165,13 @@ import java.util.Map; roles = {"Internal/devicemgt-user"}, permissions = {"/device-mgt/devices/change-status"} ), + @Scope( + name = "Update status of a given operation", + description = "Updates the status of a given operation of a given device", + key = "dm:devices:ops:status:update", + roles = {"Internal/devicemgt-user"}, + permissions = {"/device-mgt/devices/operations/status-update"} + ), @Scope( name = "Enroll Device", description = "Register a device", @@ -2714,12 +2721,12 @@ public interface DeviceManagementService { @ApiOperation( produces = MediaType.APPLICATION_JSON, httpMethod = "PUT", - value = "Update status of a given opeation", + value = "Update status of a given operation", notes = "Updates the status of a given operation of a given device in Entgra IoT Server.", tags = "Device Management", extensions = { @Extension(properties = { - @ExtensionProperty(name = Constants.SCOPE, value = "dm:devices:ops:view") + @ExtensionProperty(name = Constants.SCOPE, value = "dm:devices:ops:status:update") }) } ) From eadb2efb8636395b0a35f29589a163e187d46a27 Mon Sep 17 00:00:00 2001 From: pasindu Date: Fri, 14 Jun 2024 09:31:17 +0530 Subject: [PATCH 06/17] Change scope key not found log to debug level log --- .../extension/rest/api/PublisherRESTAPIServicesImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/PublisherRESTAPIServicesImpl.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/PublisherRESTAPIServicesImpl.java index 8db730cc7b..e322ae0307 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/PublisherRESTAPIServicesImpl.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.extension.rest.api/src/main/java/io/entgra/device/mgt/core/apimgt/extension/rest/api/PublisherRESTAPIServicesImpl.java @@ -120,7 +120,9 @@ public class PublisherRESTAPIServicesImpl implements PublisherRESTAPIServices { throw new BadRequestException(msg); } else if (HttpStatus.SC_NOT_FOUND == response.code()) { String msg = "Shared scope key not found : " + key; - log.info(msg); + if (log.isDebugEnabled()) { + log.debug(msg); + } return false; } else { String msg = "Response : " + response.code() + response.body(); From b7848fd0c315819f9082f60a4a833501305b2688 Mon Sep 17 00:00:00 2001 From: "amalka.subasinghe" Date: Mon, 24 Jun 2024 12:04:41 +0530 Subject: [PATCH 07/17] scopes and related permissions added when scope is not attached to an api --- .../pom.xml | 4 +++- .../webapp/publisher/APIPublisherServiceImpl.java | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/pom.xml b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/pom.xml index 10bfbf4145..a668025519 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/pom.xml +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/pom.xml @@ -205,7 +205,9 @@ org.wso2.carbon.utils;version="4.6", org.wso2.carbon.utils.multitenancy;version="4.6", org.apache.commons.lang, - org.json + org.json, + io.entgra.device.mgt.core.device.mgt.common.permission.mgt, + io.entgra.device.mgt.core.device.mgt.core.permission.mgt jsr311-api;scope=compile|runtime;inline=false diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherServiceImpl.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherServiceImpl.java index e9a58e556c..cab16f8482 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherServiceImpl.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherServiceImpl.java @@ -46,6 +46,7 @@ import io.entgra.device.mgt.core.device.mgt.core.config.DeviceManagementConfig; import io.entgra.device.mgt.core.device.mgt.core.config.permission.DefaultPermission; import io.entgra.device.mgt.core.device.mgt.core.config.permission.DefaultPermissions; import io.entgra.device.mgt.core.device.mgt.core.config.permission.ScopeMapping; +import io.entgra.device.mgt.core.device.mgt.core.permission.mgt.PermissionUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -68,6 +69,8 @@ import org.wso2.carbon.user.core.tenant.TenantSearchResult; import org.wso2.carbon.utils.CarbonUtils; import org.wso2.carbon.utils.multitenancy.MultitenantConstants; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; +import io.entgra.device.mgt.core.device.mgt.core.permission.mgt.PermissionUtils; +import io.entgra.device.mgt.core.device.mgt.common.permission.mgt.PermissionManagementException; import java.io.BufferedReader; import java.io.File; @@ -610,9 +613,17 @@ public class APIPublisherServiceImpl implements APIPublisherService { if (publisherRESTAPIServices.isSharedScopeNameExists(apiApplicationKey, accessTokenInfo, scope.getName())) { publisherRESTAPIServices.updateSharedScope(apiApplicationKey, accessTokenInfo, scope); + // todo: permission changed in update path, is not handled yet. } else { - // todo: come to this level means, that scope is removed from API, but haven't removed from the scope-role-permission-mappings list - log.warn(scope.getName() + " not available as shared scope"); + // This scope doesn't have an api attached. + log.warn(scope.getName() + " not available as shared, add as new scope"); + publisherRESTAPIServices.addNewSharedScope(apiApplicationKey, accessTokenInfo, scope); + // add permission if not exist + try { + PermissionUtils.putPermission(permission); + } catch(PermissionManagementException e) { + log.error("Error when adding permission ", e); + } } } for (String role : rolePermissions.keySet()) { From 01d76c6dbd251e090ea70d4e5f32f38e6ec54b40 Mon Sep 17 00:00:00 2001 From: Sasini Sandamali Date: Mon, 24 Jun 2024 14:21:34 +0000 Subject: [PATCH 08/17] Add necessary improvements and configs for grafana version 10.3.3 (#396) Co-authored-by: Sasini_Sandamali Reviewed-on: https://repository.entgra.net/community/device-mgt-core/pulls/396 Co-authored-by: Sasini Sandamali Co-committed-by: Sasini Sandamali --- .../proxy/api/GrafanaAPIProxyService.java | 50 +++++++++++++++++++ .../api/impl/GrafanaAPIProxyServiceImpl.java | 37 +++++++++++++- .../impl/util/GrafanaRequestHandlerUtil.java | 20 +++++--- .../core/config/GrafanaConfiguration.java | 11 ++++ .../config/xml/bean/ValidationConfig.java | 45 +++++++++++++++++ .../main/resources/conf/grafana-config.xml | 6 +++ .../grafana-config.xml.j2 | 6 +++ 7 files changed, 166 insertions(+), 9 deletions(-) create mode 100644 components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/core/config/xml/bean/ValidationConfig.java diff --git a/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/api/GrafanaAPIProxyService.java b/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/api/GrafanaAPIProxyService.java index 18fb6201af..5bdf335d30 100644 --- a/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/api/GrafanaAPIProxyService.java +++ b/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/api/GrafanaAPIProxyService.java @@ -107,6 +107,23 @@ public interface GrafanaAPIProxyService { ) Response frontendMetrics(JsonObject body, @Context HttpHeaders headers, @Context UriInfo requestUriInfo); + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @Path("/user/auth-tokens/rotate") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Rotate authentication tokens", + tags = "Analytics", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "grafana:api:view") + }) + } + ) + Response rotateAuthToken(JsonObject body, @Context HttpHeaders headers, @Context UriInfo requestUriInfo); + @GET @Produces(MediaType.APPLICATION_JSON) @Path("/dashboards/uid/{uid}") @@ -123,6 +140,22 @@ public interface GrafanaAPIProxyService { ) Response getDashboard(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) throws ClassNotFoundException; + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("/folders/{uid}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Grafana dashboard folder information", + tags = "Analytics", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "grafana:api:view") + }) + } + ) + Response getFolders(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) throws ClassNotFoundException; + @GET @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @@ -140,6 +173,23 @@ public interface GrafanaAPIProxyService { ) Response getAnnotations(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) throws ClassNotFoundException; + @GET + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @Path("/prometheus/grafana/api/v1/rules") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Accessing Grafana Prometheus rule information", + tags = "Analytics", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "grafana:api:view") + }) + } + ) + Response prometheusRuleInfo(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) throws ClassNotFoundException; + @GET @Produces(MediaType.APPLICATION_JSON) @Path("/alerts/states-for-dashboard") diff --git a/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/api/impl/GrafanaAPIProxyServiceImpl.java b/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/api/impl/GrafanaAPIProxyServiceImpl.java index 8ed6fe1ca1..92eed32c74 100644 --- a/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/api/impl/GrafanaAPIProxyServiceImpl.java +++ b/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/api/impl/GrafanaAPIProxyServiceImpl.java @@ -26,6 +26,8 @@ import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.impl.util.Grafa import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.impl.util.GrafanaRequestHandlerUtil; import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.common.exception.GrafanaManagementException; import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.bean.GrafanaPanelIdentifier; +import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.config.GrafanaConfiguration; +import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.config.GrafanaConfigurationManager; import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.exception.MaliciousQueryAttempt; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -56,9 +58,13 @@ public class GrafanaAPIProxyServiceImpl implements GrafanaAPIProxyService { @Override public Response queryDatasource(JsonObject body, @Context HttpHeaders headers, @Context UriInfo requestUriInfo) { try { + GrafanaConfiguration configuration = GrafanaConfigurationManager.getInstance().getGrafanaConfiguration(); GrafanaPanelIdentifier panelIdentifier = GrafanaRequestHandlerUtil.getPanelIdentifier(headers); - GrafanaMgtAPIUtils.getGrafanaQueryService().buildSafeQuery(body, panelIdentifier.getDashboardId(), - panelIdentifier.getPanelId(), requestUriInfo.getRequestUri()); + boolean queryValidationConfig = configuration.getValidationConfig().getDSQueryValidation(); + if (queryValidationConfig) { + GrafanaMgtAPIUtils.getGrafanaQueryService().buildSafeQuery(body, panelIdentifier.getDashboardId(), + panelIdentifier.getPanelId(), requestUriInfo.getRequestUri()); + } return GrafanaRequestHandlerUtil.proxyPassPostRequest(body, requestUriInfo, panelIdentifier.getOrgId()); } catch (MaliciousQueryAttempt e) { return Response.status(Response.Status.BAD_REQUEST).entity( @@ -83,6 +89,15 @@ public class GrafanaAPIProxyServiceImpl implements GrafanaAPIProxyService { return proxyPassPostRequest(body, headers, requestUriInfo); } + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @Path("/user/auth-tokens/rotate") + @Override + public Response rotateAuthToken(JsonObject body, @Context HttpHeaders headers, @Context UriInfo requestUriInfo) { + return proxyPassPostRequest(body, headers, requestUriInfo); + } + @GET @Produces(MediaType.APPLICATION_JSON) @Path("/dashboards/uid/{uid}") @@ -91,6 +106,14 @@ public class GrafanaAPIProxyServiceImpl implements GrafanaAPIProxyService { return proxyPassGetRequest(headers, requestUriInfo); } + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("/folders/{uid}") + @Override + public Response getFolders(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) { + return proxyPassGetRequest(headers, requestUriInfo); + } + @GET @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @@ -99,6 +122,16 @@ public class GrafanaAPIProxyServiceImpl implements GrafanaAPIProxyService { public Response getAnnotations(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) { return proxyPassGetRequest(headers, requestUriInfo); } + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @Path("/prometheus/grafana/api/v1/rules") + @Override + public Response prometheusRuleInfo(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) { + return proxyPassGetRequest(headers, requestUriInfo); + } + @GET @Produces(MediaType.APPLICATION_JSON) @Path("/alerts/states-for-dashboard") diff --git a/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/api/impl/util/GrafanaRequestHandlerUtil.java b/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/api/impl/util/GrafanaRequestHandlerUtil.java index d81a6d4d26..e94b3ccf53 100644 --- a/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/api/impl/util/GrafanaRequestHandlerUtil.java +++ b/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/api/impl/util/GrafanaRequestHandlerUtil.java @@ -22,6 +22,8 @@ import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.bean.ErrorRespo import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.api.exception.RefererNotValid; import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.common.exception.GrafanaManagementException; import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.bean.GrafanaPanelIdentifier; +import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.config.GrafanaConfiguration; +import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.config.GrafanaConfigurationManager; import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.exception.GrafanaEnvVariablesNotDefined; import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.util.GrafanaConstants; import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.util.GrafanaUtil; @@ -120,19 +122,23 @@ public class GrafanaRequestHandlerUtil { return path; } - public static GrafanaPanelIdentifier getPanelIdentifier(HttpHeaders headers) throws RefererNotValid { + public static GrafanaPanelIdentifier getPanelIdentifier(HttpHeaders headers) throws RefererNotValid, GrafanaManagementException { String referer = headers.getHeaderString(GrafanaConstants.REFERER_HEADER); - if(referer == null) { + if (referer == null) { String errMsg = "Request does not contain Referer header"; log.error(errMsg); throw new RefererNotValid(errMsg); } + GrafanaConfiguration configuration = GrafanaConfigurationManager.getInstance().getGrafanaConfiguration(); + boolean dashboardIntegrationConfig = configuration.getValidationConfig().getDashboardIntegration(); GrafanaPanelIdentifier panelIdentifier = GrafanaUtil.getPanelIdentifierFromReferer(referer); - if(panelIdentifier.getDashboardId() == null || - panelIdentifier.getPanelId() == null || panelIdentifier.getOrgId() == null) { - String errMsg = "Referer must contain dashboardId, panelId and orgId"; - log.error(errMsg); - throw new RefererNotValid(errMsg); + if (!dashboardIntegrationConfig) { + if (panelIdentifier.getDashboardId() == null || + panelIdentifier.getPanelId() == null || panelIdentifier.getOrgId() == null) { + String errMsg = "Referer must contain dashboardId, panelId, and orgId"; + log.error(errMsg); + throw new RefererNotValid(errMsg); + } } return panelIdentifier; } diff --git a/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/core/config/GrafanaConfiguration.java b/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/core/config/GrafanaConfiguration.java index bf2cbce90f..137dc86025 100644 --- a/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/core/config/GrafanaConfiguration.java +++ b/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/core/config/GrafanaConfiguration.java @@ -19,6 +19,7 @@ package io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.config; import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.config.xml.bean.CacheConfiguration; +import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.config.xml.bean.ValidationConfig; import io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core.config.xml.bean.User; import javax.xml.bind.annotation.XmlElement; @@ -30,6 +31,7 @@ import java.util.List; public class GrafanaConfiguration { private User adminUser; + private ValidationConfig validationConfig; private List caches; @XmlElement(name = "AdminUser") @@ -37,6 +39,15 @@ public class GrafanaConfiguration { return adminUser; } + @XmlElement(name = "ValidationConfig") + public ValidationConfig getValidationConfig() { + return validationConfig; + } + + public void setValidationConfig(ValidationConfig validationConfig) { + this.validationConfig = validationConfig; + } + public void setAdminUser(User user) { this.adminUser = user; } diff --git a/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/core/config/xml/bean/ValidationConfig.java b/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/core/config/xml/bean/ValidationConfig.java new file mode 100644 index 0000000000..b15955bbe2 --- /dev/null +++ b/components/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.core/src/main/java/io/entgra/device/mgt/core/analytics/mgt/grafana/proxy/core/config/xml/bean/ValidationConfig.java @@ -0,0 +1,45 @@ +/* + * 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.analytics.mgt.grafana.proxy.core.config.xml.bean; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "ValidationConfig") +public class ValidationConfig { + private boolean dsQueryValidation; + private boolean dashboardIntegration; + + @XmlElement(name = "DSQueryValidation") + public boolean getDSQueryValidation() { + return dsQueryValidation; + } + + public void setDSQueryValidation(boolean dsQueryValidation) { + this.dsQueryValidation = dsQueryValidation; + } + + @XmlElement(name = "DashboardIntegration") + public boolean getDashboardIntegration() { + return dashboardIntegration; + } + + public void setDashboardIntegration(boolean dashboardIntegration) { + this.dashboardIntegration = dashboardIntegration; + } +} diff --git a/features/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.server.feature/src/main/resources/conf/grafana-config.xml b/features/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.server.feature/src/main/resources/conf/grafana-config.xml index f6ae22a601..e7b5a7bf3e 100644 --- a/features/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.server.feature/src/main/resources/conf/grafana-config.xml +++ b/features/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.server.feature/src/main/resources/conf/grafana-config.xml @@ -32,4 +32,10 @@ admin admin + + + true + + false + diff --git a/features/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.server.feature/src/main/resources/conf_templates.templates.repository.conf/grafana-config.xml.j2 b/features/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.server.feature/src/main/resources/conf_templates.templates.repository.conf/grafana-config.xml.j2 index 623a6cda06..dbf9d38a6e 100644 --- a/features/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.server.feature/src/main/resources/conf_templates.templates.repository.conf/grafana-config.xml.j2 +++ b/features/analytics-mgt/grafana-mgt/io.entgra.device.mgt.core.analytics.mgt.grafana.proxy.server.feature/src/main/resources/conf_templates.templates.repository.conf/grafana-config.xml.j2 @@ -32,4 +32,10 @@ admin admin + + + true + + false + From 502e89ecf3c4c5593259d878b78b4066ed41ecf1 Mon Sep 17 00:00:00 2001 From: "osh.silva" Date: Fri, 28 Jun 2024 09:10:57 +0530 Subject: [PATCH 09/17] Add status scope to mdm-config --- .../src/main/resources/conf/mdm-ui-config.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml b/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml index 8303fc6402..32dc388789 100644 --- a/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml +++ b/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml @@ -421,6 +421,7 @@ dm:admin:cea:delete dm:admin:cea:sync am:pub:app:upload + dm:devices:ops:status:update device-mgt From 0790aa609aa3d096c4eed013ab64939278c4995e Mon Sep 17 00:00:00 2001 From: Kavin Prathaban Date: Tue, 28 May 2024 11:18:44 +0000 Subject: [PATCH 10/17] Modify methods to categorize device subscriptions ## Purpose * Fixes https://roadmap.entgra.net/issues/11162 Co-authored-by: Kavin Prathaban Co-committed-by: Kavin Prathaban --- .../common/CategorizedSubscriptionResult.java | 41 ++++++++ .../common/services/SubscriptionManager.java | 3 +- .../core/impl/SubscriptionManagerImpl.java | 95 +++++++++++-------- 3 files changed, 96 insertions(+), 43 deletions(-) create mode 100644 components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java new file mode 100644 index 0000000000..8e59f287a3 --- /dev/null +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java @@ -0,0 +1,41 @@ +package io.entgra.device.mgt.core.application.mgt.common; + +import java.util.List; + +public class CategorizedSubscriptionResult { + private List installedDevices; + private List pendingDevices; + private List errorDevices; + + public CategorizedSubscriptionResult(List installedDevices, + List pendingDevices, + List errorDevices) { + this.installedDevices = installedDevices; + this.pendingDevices = pendingDevices; + this.errorDevices = errorDevices; + } + + public List getInstalledDevices() { + return installedDevices; + } + + public void setInstalledDevices(List installedDevices) { + this.installedDevices = installedDevices; + } + + public List getPendingDevices() { + return pendingDevices; + } + + public void setPendingDevices(List pendingDevices) { + this.pendingDevices = pendingDevices; + } + + public List getErrorDevices() { + return errorDevices; + } + + public void setErrorDevices(List errorDevices) { + this.errorDevices = errorDevices; + } +} diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java index e06a17cb9b..c5b8ac8153 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java @@ -18,6 +18,7 @@ package io.entgra.device.mgt.core.application.mgt.common.services; import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstallResponse; +import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus; import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException; @@ -194,7 +195,7 @@ public interface SubscriptionManager { * application release for given UUID, if an error occurred while getting device details of subscribed device ids, * if an error occurred while getting subscription details of given application release UUID. */ - PaginationResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, String action, String installedVersion) + CategorizedSubscriptionResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, String action, String installedVersion) throws ApplicationManagementException; /*** diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java index 931c45ddcf..ddfd1cfe46 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java @@ -19,17 +19,28 @@ package io.entgra.device.mgt.core.application.mgt.core.impl; import com.google.gson.Gson; +import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstallResponse; +import io.entgra.device.mgt.core.application.mgt.common.ApplicationSubscriptionInfo; +import io.entgra.device.mgt.core.application.mgt.common.ApplicationType; +import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; +import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscriptionData; +import io.entgra.device.mgt.core.application.mgt.common.DeviceTypes; +import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus; +import io.entgra.device.mgt.core.application.mgt.common.SubAction; +import io.entgra.device.mgt.core.application.mgt.common.SubscribingDeviceIdHolder; +import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType; import io.entgra.device.mgt.core.application.mgt.common.dto.VppAssetDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.VppUserDTO; import io.entgra.device.mgt.core.application.mgt.common.services.VPPApplicationManager; import io.entgra.device.mgt.core.application.mgt.core.dao.VppApplicationDAO; import io.entgra.device.mgt.core.application.mgt.core.exception.BadRequestException; +import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; +import io.entgra.device.mgt.core.device.mgt.common.PaginationResult; import io.entgra.device.mgt.core.device.mgt.core.DeviceManagementConstants; import io.entgra.device.mgt.core.application.mgt.core.exception.UnexpectedServerErrorException; import io.entgra.device.mgt.core.device.mgt.extensions.logger.spi.EntgraLogger; import io.entgra.device.mgt.core.notification.logger.AppInstallLogContext; import io.entgra.device.mgt.core.notification.logger.impl.EntgraAppInstallLoggerImpl; -import org.apache.commons.httpclient.HttpClient; import org.apache.commons.lang.StringUtils; import org.apache.http.HttpResponse; @@ -45,15 +56,6 @@ import org.json.JSONObject; import io.entgra.device.mgt.core.apimgt.application.extension.dto.ApiApplicationKey; import io.entgra.device.mgt.core.apimgt.application.extension.exception.APIManagerException; import org.wso2.carbon.context.PrivilegedCarbonContext; -import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstallResponse; -import io.entgra.device.mgt.core.application.mgt.common.ApplicationSubscriptionInfo; -import io.entgra.device.mgt.core.application.mgt.common.ApplicationType; -import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscriptionData; -import io.entgra.device.mgt.core.application.mgt.common.DeviceTypes; -import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus; -import io.entgra.device.mgt.core.application.mgt.common.SubAction; -import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType; -import io.entgra.device.mgt.core.application.mgt.common.SubscribingDeviceIdHolder; import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationPolicyDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO; @@ -1505,16 +1507,19 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } @Override - public PaginationResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, - String action, String installedVersion) throws ApplicationManagementException { + public CategorizedSubscriptionResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, + String action, String installedVersion) throws ApplicationManagementException { int limitValue = request.getRowCount(); int offsetValue = request.getStartIndex(); int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); - DeviceManagementProviderService deviceManagementProviderService = HelperUtil - .getDeviceManagementProviderService(); + DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); + List installedDevices = new ArrayList<>(); + List pendingDevices = new ArrayList<>(); + List errorDevices = new ArrayList<>(); + if (offsetValue < 0 || limitValue <= 0) { - String msg = "Found incompatible values for offset and limit. Hence please check the request and resend. " - + "Offset " + offsetValue + " limit " + limitValue; + String msg = "Found incompatible values for offset and limit. Hence please check the request and resend. " + + "Offset " + offsetValue + " limit " + limitValue; log.error(msg); throw new BadRequestException(msg); } @@ -1532,31 +1537,25 @@ public class SubscriptionManagerImpl implements SubscriptionManager { List deviceSubscriptionDTOS = subscriptionDAO .getDeviceSubscriptions(applicationReleaseId, tenantId, actionStatus, action); if (deviceSubscriptionDTOS.isEmpty()) { - PaginationResult paginationResult = new PaginationResult(); - paginationResult.setData(new ArrayList<>()); - paginationResult.setRecordsFiltered(0); - paginationResult.setRecordsTotal(0); - return paginationResult; + return new CategorizedSubscriptionResult(new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); } List deviceIdList = deviceSubscriptionDTOS.stream().map(DeviceSubscriptionDTO::getDeviceId) .collect(Collectors.toList()); - Map currentVersionsMap = subscriptionDAO.getCurrentInstalledAppVersion(applicationDTO.getId(),deviceIdList, installedVersion); + Map currentVersionsMap = subscriptionDAO.getCurrentInstalledAppVersion(applicationDTO.getId(), deviceIdList, installedVersion); try { - //pass the device id list to device manager service method - PaginationResult paginationResult = deviceManagementProviderService.getAppSubscribedDevices - (request, deviceIdList); - List deviceSubscriptionDataList = new ArrayList<>(); + // Pass the device id list to device manager service method + PaginationResult paginationResult = deviceManagementProviderService.getAppSubscribedDevices(request, deviceIdList); if (!paginationResult.getData().isEmpty()) { List devices = (List) paginationResult.getData(); for (Device device : devices) { - if(installedVersion != null && !installedVersion.isEmpty() && !currentVersionsMap.containsKey(device.getId())){ + if (installedVersion != null && !installedVersion.isEmpty() && !currentVersionsMap.containsKey(device.getId())) { continue; } DeviceSubscriptionData deviceSubscriptionData = new DeviceSubscriptionData(); - if(currentVersionsMap.containsKey(device.getId())){ + if (currentVersionsMap.containsKey(device.getId())) { deviceSubscriptionData.setCurrentInstalledVersion(currentVersionsMap.get(device.getId())); - }else{ + } else { deviceSubscriptionData.setCurrentInstalledVersion("-"); } for (DeviceSubscriptionDTO subscription : deviceSubscriptionDTOS) { @@ -1565,39 +1564,51 @@ public class SubscriptionManagerImpl implements SubscriptionManager { if (subscription.isUnsubscribed()) { deviceSubscriptionData.setAction(Constants.UNSUBSCRIBED); deviceSubscriptionData.setActionTriggeredBy(subscription.getUnsubscribedBy()); - deviceSubscriptionData - .setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp().getTime() / 1000); + deviceSubscriptionData.setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp().getTime() / 1000); } else { deviceSubscriptionData.setAction(Constants.SUBSCRIBED); deviceSubscriptionData.setActionTriggeredBy(subscription.getSubscribedBy()); - deviceSubscriptionData - .setActionTriggeredTimestamp(subscription.getSubscribedTimestamp().getTime() / 1000); + deviceSubscriptionData.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp().getTime() / 1000); } deviceSubscriptionData.setActionType(subscription.getActionTriggeredFrom()); deviceSubscriptionData.setStatus(subscription.getStatus()); deviceSubscriptionData.setSubId(subscription.getId()); - deviceSubscriptionDataList.add(deviceSubscriptionData); + + // Categorize the subscription data based on its status + switch (subscription.getStatus()) { + case "COMPLETED": + installedDevices.add(deviceSubscriptionData); + break; + case "ERROR": + case "INVALID": + case "UNAUTHORIZED": + errorDevices.add(deviceSubscriptionData); + break; + case "IN_PROGRESS": + case "PENDING": + case "REPEATED": + pendingDevices.add(deviceSubscriptionData); + break; + } break; } } } } - paginationResult.setData(deviceSubscriptionDataList); - return paginationResult; + return new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices); } catch (DeviceManagementException e) { - String msg = "service error occurred while getting device data from the device management service. " - + "Device ids " + deviceIdList; + String msg = "Service error occurred while getting device data from the device management service. " + + "Device ids " + deviceIdList; log.error(msg, e); throw new ApplicationManagementException(msg, e); } } catch (ApplicationManagementDAOException e) { - String msg = - "Error occurred when getting application release data for application release UUID: " + appUUID; + String msg = "Error occurred when getting application release data for application release UUID: " + appUUID; log.error(msg, e); throw new ApplicationManagementException(msg, e); } catch (DBConnectionException e) { - String msg = "DB Connection error occurred while trying to get subscription data of application which has " - + "application release UUID " + appUUID; + String msg = "DB Connection error occurred while trying to get subscription data of application which has " + + "application release UUID " + appUUID; log.error(msg, e); throw new ApplicationManagementException(msg, e); } finally { From 86bed7b83ad5d8c723e22db98ecb0dabb3963bfd Mon Sep 17 00:00:00 2001 From: nipuni Date: Mon, 27 May 2024 10:27:16 +0530 Subject: [PATCH 11/17] Feature to manage subscription type base subscriptions and Installation Percentage Calculation based on groups, users and roles --- .../common/CategorizedSubscriptionResult.java | 40 ++ .../mgt/common/DeviceSubscriptionData.java | 36 +- .../mgt/common/dto/DeviceOperationDTO.java | 115 +++++ .../mgt/common/dto/GroupSubscriptionDTO.java | 18 + .../dto/GroupSubscriptionDetailDTO.java | 136 ++++++ .../mgt/common/dto/RoleSubscriptionDTO.java | 98 +++- .../common/dto/SubscriptionResponseDTO.java | 52 ++ .../mgt/common/dto/UserSubscriptionDTO.java | 102 +++- .../common/services/SubscriptionManager.java | 48 +- .../mgt/core/dao/SubscriptionDAO.java | 64 ++- .../GenericSubscriptionDAOImpl.java | 258 ++++++++++ .../core/impl/SubscriptionManagerImpl.java | 460 +++++++++++++++++- .../device/mgt/core/dao/EnrollmentDAO.java | 12 +- .../core/device/mgt/core/dao/GroupDAO.java | 12 +- .../dao/impl/AbstractEnrollmentDAOImpl.java | 35 +- .../core/dao/impl/AbstractGroupDAOImpl.java | 40 ++ .../device/mgt/core/dto/GroupDetailsDTO.java | 70 +++ .../device/mgt/core/dto/OperationDTO.java | 118 +++++ .../mgt/core/dto/OwnerWithDeviceDTO.java | 52 ++ .../core/operation/mgt/dao/OperationDAO.java | 4 + .../mgt/dao/impl/GenericOperationDAOImpl.java | 52 +- .../mgt/dao/util/OperationDAOUtil.java | 43 ++ .../DeviceManagementProviderService.java | 20 + .../DeviceManagementProviderServiceImpl.java | 55 +++ .../GroupManagementProviderService.java | 11 + .../GroupManagementProviderServiceImpl.java | 36 +- 26 files changed, 1938 insertions(+), 49 deletions(-) create mode 100644 components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/DeviceOperationDTO.java create mode 100644 components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDetailDTO.java create mode 100644 components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/SubscriptionResponseDTO.java create mode 100644 components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/GroupDetailsDTO.java create mode 100644 components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OperationDTO.java create mode 100644 components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OwnerWithDeviceDTO.java diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java index 8e59f287a3..60531ac8aa 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package io.entgra.device.mgt.core.application.mgt.common; import java.util.List; @@ -6,13 +24,27 @@ public class CategorizedSubscriptionResult { private List installedDevices; private List pendingDevices; private List errorDevices; + private List newDevices; + // without newDevices public CategorizedSubscriptionResult(List installedDevices, List pendingDevices, List errorDevices) { this.installedDevices = installedDevices; this.pendingDevices = pendingDevices; this.errorDevices = errorDevices; + this.newDevices = null; + } + + // with newDevices + public CategorizedSubscriptionResult(List installedDevices, + List pendingDevices, + List errorDevices, + List newDevices) { + this.installedDevices = installedDevices; + this.pendingDevices = pendingDevices; + this.errorDevices = errorDevices; + this.newDevices = newDevices; } public List getInstalledDevices() { @@ -38,4 +70,12 @@ public class CategorizedSubscriptionResult { public void setErrorDevices(List errorDevices) { this.errorDevices = errorDevices; } + + public List getNewDevices() { + return newDevices; + } + + public void setNewDevices(List newDevices) { + this.newDevices = newDevices; + } } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/DeviceSubscriptionData.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/DeviceSubscriptionData.java index 55f2ec9edc..5ea565af90 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/DeviceSubscriptionData.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/DeviceSubscriptionData.java @@ -26,12 +26,14 @@ public class DeviceSubscriptionData { private int subId; private String action; - private long actionTriggeredTimestamp; + private Timestamp actionTriggeredTimestamp; + private String actionTriggeredFrom; private String actionTriggeredBy; private String actionType; private String status; private Device device; private String currentInstalledVersion; + private int deviceId; public String getAction() { return action; @@ -41,14 +43,6 @@ public class DeviceSubscriptionData { this.action = action; } - public long getActionTriggeredTimestamp() { - return actionTriggeredTimestamp; - } - - public void setActionTriggeredTimestamp(long actionTriggeredTimestamp) { - this.actionTriggeredTimestamp = actionTriggeredTimestamp; - } - public String getActionTriggeredBy() { return actionTriggeredBy; } @@ -92,4 +86,28 @@ public class DeviceSubscriptionData { public void setSubId(int subId) { this.subId = subId; } + + public int getDeviceId() { + return deviceId; + } + + public void setDeviceId(int deviceId) { + this.deviceId = deviceId; + } + + public String getActionTriggeredFrom() { + return actionTriggeredFrom; + } + + public void setActionTriggeredFrom(String actionTriggeredFrom) { + this.actionTriggeredFrom = actionTriggeredFrom; + } + + public Timestamp getActionTriggeredTimestamp() { + return actionTriggeredTimestamp; + } + + public void setActionTriggeredTimestamp(Timestamp actionTriggeredTimestamp) { + this.actionTriggeredTimestamp = actionTriggeredTimestamp; + } } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/DeviceOperationDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/DeviceOperationDTO.java new file mode 100644 index 0000000000..bca7e8b002 --- /dev/null +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/DeviceOperationDTO.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.application.mgt.common.dto; + +import java.sql.Timestamp; + +public class DeviceOperationDTO { + private int deviceId; + private String uuid; + private String status; + private int operationId; + private String actionTriggeredFrom; + private Timestamp actionTriggeredAt; + private int appReleaseId; + private String operationCode; + private Object operationDetails; + private Object operationProperties; + + + public int getDeviceId() { + return deviceId; + } + + public void setDeviceId(int deviceId) { + this.deviceId = deviceId; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public int getOperationId() { + return operationId; + } + + public void setOperationId(int operationId) { + this.operationId = operationId; + } + + public String getActionTriggeredFrom() { + return actionTriggeredFrom; + } + + public void setActionTriggeredFrom(String actionTriggeredFrom) { + this.actionTriggeredFrom = actionTriggeredFrom; + } + + public Timestamp getActionTriggeredAt() { + return actionTriggeredAt; + } + + public void setActionTriggeredAt(Timestamp actionTriggeredAt) { + this.actionTriggeredAt = actionTriggeredAt; + } + + public int getAppReleaseId() { + return appReleaseId; + } + + public void setAppReleaseId(int appReleaseId) { + this.appReleaseId = appReleaseId; + } + + public String getOperationCode() { + return operationCode; + } + + public void setOperationCode(String operationCode) { + this.operationCode = operationCode; + } + + public Object getOperationDetails() { + return operationDetails; + } + + public void setOperationDetails(Object operationDetails) { + this.operationDetails = operationDetails; + } + + public Object getOperationProperties() { + return operationProperties; + } + + public void setOperationProperties(Object operationProperties) { + this.operationProperties = operationProperties; + } +} diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDTO.java index 3d9e6dfd2c..76a7b39d2d 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDTO.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDTO.java @@ -22,6 +22,7 @@ import java.sql.Timestamp; public class GroupSubscriptionDTO { private int id; + private String groupName; private String subscribedBy; private Timestamp subscribedTimestamp; private boolean isUnsubscribed; @@ -29,6 +30,7 @@ public class GroupSubscriptionDTO { private Timestamp unsubscribedTimestamp; private String subscribedFrom; private int groupdId; + private int appReleaseId; public int getId() { return id; } @@ -61,4 +63,20 @@ public class GroupSubscriptionDTO { public int getGroupdId() { return groupdId; } public void setGroupdId(int groupdId) { this.groupdId = groupdId; } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public int getAppReleaseId() { + return appReleaseId; + } + + public void setAppReleaseId(int appReleaseId) { + this.appReleaseId = appReleaseId; + } } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDetailDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDetailDTO.java new file mode 100644 index 0000000000..442d82faed --- /dev/null +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDetailDTO.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.application.mgt.common.dto; + +import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; + +import java.sql.Timestamp; +import java.util.Map; + +public class GroupSubscriptionDetailDTO { + private int groupId; + private String groupName; + private String groupOwner; + private String subscribedBy; + private Timestamp subscribedTimestamp; + private boolean isUnsubscribed; + private String unsubscribedBy; + private Timestamp unsubscribedTimestamp; + private int appReleaseId; + private int deviceCount; + private CategorizedSubscriptionResult devices; + private Map statusPercentages; + + // Getters and Setters + public int getGroupId() { + return groupId; + } + + public void setGroupId(int groupId) { + this.groupId = groupId; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public String getGroupOwner() { + return groupOwner; + } + + public void setGroupOwner(String groupOwner) { + this.groupOwner = groupOwner; + } + + public String getSubscribedBy() { + return subscribedBy; + } + + public void setSubscribedBy(String subscribedBy) { + this.subscribedBy = subscribedBy; + } + + public Timestamp getSubscribedTimestamp() { + return subscribedTimestamp; + } + + public void setSubscribedTimestamp(Timestamp subscribedTimestamp) { + this.subscribedTimestamp = subscribedTimestamp; + } + + public boolean isUnsubscribed() { + return isUnsubscribed; + } + + public void setUnsubscribed(boolean unsubscribed) { + isUnsubscribed = unsubscribed; + } + + public String getUnsubscribedBy() { + return unsubscribedBy; + } + + public void setUnsubscribedBy(String unsubscribedBy) { + this.unsubscribedBy = unsubscribedBy; + } + + public Timestamp getUnsubscribedTimestamp() { + return unsubscribedTimestamp; + } + + public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) { + this.unsubscribedTimestamp = unsubscribedTimestamp; + } + + public int getAppReleaseId() { + return appReleaseId; + } + + public void setAppReleaseId(int appReleaseId) { + this.appReleaseId = appReleaseId; + } + + public int getDeviceCount() { + return deviceCount; + } + + public void setDeviceCount(int deviceCount) { + this.deviceCount = deviceCount; + } + + public CategorizedSubscriptionResult getDevices() { + return devices; + } + + public void setDevices(CategorizedSubscriptionResult devices) { + this.devices = devices; + } + + public Map getStatusPercentages() { + return statusPercentages; + } + + public void setStatusPercentages(Map statusPercentages) { + this.statusPercentages = statusPercentages; + } +} diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/RoleSubscriptionDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/RoleSubscriptionDTO.java index 869ed1fd6d..b8139181de 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/RoleSubscriptionDTO.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/RoleSubscriptionDTO.java @@ -18,51 +18,115 @@ package io.entgra.device.mgt.core.application.mgt.common.dto; +import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; + import java.sql.Timestamp; +import java.util.Map; public class RoleSubscriptionDTO { - private int id; private String subscribedBy; private Timestamp subscribedTimestamp; private boolean isUnsubscribed; + private boolean unsubscribed; private String unsubscribedBy; private Timestamp unsubscribedTimestamp; private String subscribedFrom; private String roleName; + private int appReleaseId; + private int deviceCount; + private Map statusPercentages; + private CategorizedSubscriptionResult devices; - public int getId() { return id; } - - public void setId(int id) { this.id = id; } - - public String getSubscribedBy() { return subscribedBy; } + public String getSubscribedBy() { + return subscribedBy; + } - public void setSubscribedBy(String subscribedBy) { this.subscribedBy = subscribedBy; } + public void setSubscribedBy(String subscribedBy) { + this.subscribedBy = subscribedBy; + } - public Timestamp getSubscribedTimestamp() { return subscribedTimestamp; } + public Timestamp getSubscribedTimestamp() { + return subscribedTimestamp; + } public void setSubscribedTimestamp(Timestamp subscribedTimestamp) { this.subscribedTimestamp = subscribedTimestamp; } - public boolean isUnsubscribed() { return isUnsubscribed; } + public boolean getUnsubscribed() { + return unsubscribed; + } - public void setUnsubscribed(boolean unsubscribed) { isUnsubscribed = unsubscribed; } + public void setUnsubscribed(boolean unsubscribed) { + this.unsubscribed = unsubscribed; + } - public String getUnsubscribedBy() { return unsubscribedBy; } + public boolean isUnsubscribed() { + return isUnsubscribed; + } - public void setUnsubscribedBy(String unsubscribedBy) { this.unsubscribedBy = unsubscribedBy; } + public String getUnsubscribedBy() { + return unsubscribedBy; + } + + public void setUnsubscribedBy(String unsubscribedBy) { + this.unsubscribedBy = unsubscribedBy; + } - public Timestamp getUnsubscribedTimestamp() { return unsubscribedTimestamp; } + public Timestamp getUnsubscribedTimestamp() { + return unsubscribedTimestamp; + } public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) { this.unsubscribedTimestamp = unsubscribedTimestamp; } - public String getSubscribedFrom() { return subscribedFrom; } + public String getSubscribedFrom() { + return subscribedFrom; + } + + public void setSubscribedFrom(String subscribedFrom) { + this.subscribedFrom = subscribedFrom; + } + + public String getRoleName() { + return roleName; + } - public void setSubscribedFrom(String subscribedFrom) { this.subscribedFrom = subscribedFrom; } + public void setRoleName(String roleName) { + this.roleName = roleName; + } - public String getRoleName() { return roleName; } + public int getAppReleaseId() { + return appReleaseId; + } + + public void setAppReleaseId(int appReleaseId) { + this.appReleaseId = appReleaseId; + } + + public int getDeviceCount() { + return deviceCount; + } + + public void setDeviceCount(int deviceCount) { + this.deviceCount = deviceCount; + } + + public Map getStatusPercentages() { + return statusPercentages; + } + + public void setStatusPercentages(Map statusPercentages) { + this.statusPercentages = statusPercentages; + } + + public CategorizedSubscriptionResult getDevices() { + return devices; + } + + public void setDevices(CategorizedSubscriptionResult devices) { + this.devices = devices; + } - public void setRoleName(String roleName) { this.roleName = roleName; } } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/SubscriptionResponseDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/SubscriptionResponseDTO.java new file mode 100644 index 0000000000..aecee2460f --- /dev/null +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/SubscriptionResponseDTO.java @@ -0,0 +1,52 @@ +package io.entgra.device.mgt.core.application.mgt.common.dto; + +import java.util.List; + +public class SubscriptionResponseDTO { + + private String UUID; + private List GroupsSubscriptions; + private List UserSubscriptions; + private List RolesSubscriptions; + private List DevicesOperations; + + public String getUUID() { + return UUID; + } + + public void setUUID(String UUID) { + this.UUID = UUID; + } + + public List getGroupsSubscriptions() { + return GroupsSubscriptions; + } + + public void setGroupsSubscriptions(List groupsSubscriptions) { + GroupsSubscriptions = groupsSubscriptions; + } + + public List getUserSubscriptions() { + return UserSubscriptions; + } + + public void setUserSubscriptions(List userSubscriptions) { + UserSubscriptions = userSubscriptions; + } + + public List getRolesSubscriptions() { + return RolesSubscriptions; + } + + public void setRolesSubscriptions(List rolesSubscriptions) { + RolesSubscriptions = rolesSubscriptions; + } + + public List getDevicesOperations() { + return DevicesOperations; + } + + public void setDevicesOperations(List devicesOperations) { + DevicesOperations = devicesOperations; + } +} diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/UserSubscriptionDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/UserSubscriptionDTO.java index 4df7e4e64d..7238f7ebba 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/UserSubscriptionDTO.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/UserSubscriptionDTO.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. * * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -18,15 +18,107 @@ package io.entgra.device.mgt.core.application.mgt.common.dto; +import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; + import java.sql.Timestamp; +import java.util.Map; public class UserSubscriptionDTO { - private int id; + + private String userName; private String subscribedBy; private Timestamp subscribedTimestamp; - private boolean isUnsubscribed; + private boolean unsubscribed; private String unsubscribedBy; private Timestamp unsubscribedTimestamp; - private String subscribedFrom; - private String userName; + private int appReleaseId; + private int deviceCount; + private Map statusPercentages; + private CategorizedSubscriptionResult devices; + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getSubscribedBy() { + return subscribedBy; + } + + public void setSubscribedBy(String subscribedBy) { + this.subscribedBy = subscribedBy; + } + + public Timestamp getSubscribedTimestamp() { + return subscribedTimestamp; + } + + public void setSubscribedTimestamp(Timestamp subscribedTimestamp) { + this.subscribedTimestamp = subscribedTimestamp; + } + + public boolean isUnsubscribed() { + return unsubscribed; + } + + public boolean getUnsubscribed() { + return unsubscribed; + } + + public void setUnsubscribed(boolean unsubscribed) { + this.unsubscribed = unsubscribed; + } + + public String getUnsubscribedBy() { + return unsubscribedBy; + } + + public void setUnsubscribedBy(String unsubscribedBy) { + this.unsubscribedBy = unsubscribedBy; + } + + public Timestamp getUnsubscribedTimestamp() { + return unsubscribedTimestamp; + } + + public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) { + this.unsubscribedTimestamp = unsubscribedTimestamp; + } + + public int getAppReleaseId() { + return appReleaseId; + } + + public void setAppReleaseId(int appReleaseId) { + this.appReleaseId = appReleaseId; + } + + public int getDeviceCount() { + return deviceCount; + } + + public void setDeviceCount(int deviceCount) { + this.deviceCount = deviceCount; + } + + public Map getStatusPercentages() { + return statusPercentages; + } + + public void setStatusPercentages(Map statusPercentages) { + this.statusPercentages = statusPercentages; + } + + public CategorizedSubscriptionResult getDevices() { + return devices; + } + + public void setDevices(CategorizedSubscriptionResult devices) { + this.devices = devices; + } + } + diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java index c5b8ac8153..9fa1defa8b 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java @@ -20,10 +20,14 @@ package io.entgra.device.mgt.core.application.mgt.common.services; import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstallResponse; import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus; +import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType; +import io.entgra.device.mgt.core.application.mgt.common.dto.GroupSubscriptionDetailDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.UserSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.RoleSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceOperationDTO; import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException; import io.entgra.device.mgt.core.application.mgt.common.exception.SubscriptionManagementException; -import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType; import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier; import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.PaginationResult; @@ -31,6 +35,7 @@ import io.entgra.device.mgt.core.device.mgt.common.app.mgt.App; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity; import java.util.List; +import java.util.Map; import java.util.Properties; /** @@ -218,4 +223,45 @@ public interface SubscriptionManager { * @throws {@link SubscriptionManagementException} Exception of the subscription management */ Activity getOperationAppDetails(String id) throws SubscriptionManagementException; + + /** + * Retrieves the group details associated with a given app release UUID. + * + * @param uuid the UUID of the app release + * @return a list of maps containing group details and their associated devices + * @throws ApplicationManagementException if an error occurs while fetching the group details + */ + List getGroupsSubscriptionDetailsByUUID(String uuid, String subscriptionStatus) + throws ApplicationManagementException; + + /** + * Retrieves the user details associated with a given app release UUID. + * + * @param uuid the UUID of the app release + * @return a list of maps containing user details and their associated devices + * @throws ApplicationManagementException if an error occurs while fetching the group details + */ + List getUserSubscriptionsByUUID(String uuid, String subscriptionStatus) + throws ApplicationManagementException; + + /** + * Retrieves the Role details associated with a given app release UUID. + * + * @param uuid the UUID of the app release + * @return a list of maps containing role details and their associated devices + * @throws ApplicationManagementException if an error occurs while fetching the group details + */ + List getRoleSubscriptionsByUUID(String uuid, String subscriptionStatus) + throws ApplicationManagementException; + + /** + * This method is responsible for retrieving device subscription details related to the given UUID. + * + * @param uuid the UUID of the application release. + * @return List of device subscription details. + * @throws SubscriptionManagementException if there is an error while fetching the details. + */ + List getDeviceSubscriptionsOperationsByUUID(String uuid) + throws ApplicationManagementException; + } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/SubscriptionDAO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/SubscriptionDAO.java index 3213db3484..925bd9c231 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/SubscriptionDAO.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/SubscriptionDAO.java @@ -18,8 +18,12 @@ package io.entgra.device.mgt.core.application.mgt.core.dao; import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus; -import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.GroupSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.UserSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceOperationDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.RoleSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.exception.SubscriptionManagementException; import io.entgra.device.mgt.core.application.mgt.core.exception.ApplicationManagementDAOException; @@ -312,4 +316,62 @@ public interface SubscriptionDAO { * @throws ApplicationManagementDAOException thrown if an error occurs while deleting data */ void deleteScheduledSubscriptionByTenant(int tenantId) throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of groups related to a UUID. + * + * @param uuid the UUID of the application release. + * @param unsubscribe the Status of the subscription. + * @param tenantId id of the current tenant. + * @return groupDetails - list of group details related to the UUID. + * @throws ApplicationManagementDAOException if connection establishment fails. + */ + List getGroupsSubscriptionDetailsByUUID(String uuid, boolean unsubscribe, int tenantId) + throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of user subscriptions related to a UUID. + * + * @param uuid the UUID of the application release. + * @param unsubscribe the Status of the subscription. + * @param tenantId id of the current tenant. + * @return userSubscriptions - list of user subscription details related to the UUID. + * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. + */ + List getUserSubscriptionsByUUID(String uuid, boolean unsubscribe, int tenantId) + throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of role subscriptions related to a UUID. + * + * @param uuid the UUID of the application release. + * @param unsubscribe the Status of the subscription. + * @param tenantId id of the current tenant. + * @return roleSubscriptions - list of role subscription details related to the UUID. + * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. + */ + List getRoleSubscriptionsByUUID(String uuid, boolean unsubscribe, int tenantId) + throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of device subscriptions related to a UUID. + * + * @param uuid the UUID of the application release. + * @param tenantId id of the current tenant. + * @return deviceSubscriptions - list of device subscription details related to the UUID. + * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. + */ + List getDeviceSubscriptionsOperationsByUUID(String uuid, int tenantId) + throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of device subscriptions related to a UUID. + * + * @param appReleaseId the appReleaseId of the application release. + * @param tenantId id of the current tenant. + * @return deviceSubscriptions - list of device subscription details related to the UUID. + * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. + */ + List getDeviceSubscriptionsDetails(int appReleaseId, int tenantId) + throws ApplicationManagementDAOException; } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java index 79e7b76660..2dca5ac0a0 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java @@ -17,6 +17,10 @@ */ package io.entgra.device.mgt.core.application.mgt.core.dao.impl.subscription; +import io.entgra.device.mgt.core.application.mgt.common.dto.GroupSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceOperationDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.RoleSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.UserSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.core.dao.SubscriptionDAO; import io.entgra.device.mgt.core.application.mgt.core.dao.impl.AbstractDAOImpl; import io.entgra.device.mgt.core.application.mgt.core.exception.UnexpectedServerErrorException; @@ -1635,4 +1639,258 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc throw new ApplicationManagementDAOException(msg, e); } } + + @Override + public List getGroupsSubscriptionDetailsByUUID(String uuid, boolean unsubscribe, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get groups related to the given UUID."); + } + try { + Connection conn = this.getDBConnection(); + List groupDetails = new ArrayList<>(); + String sql = "SELECT GS.GROUP_NAME, GS.SUBSCRIBED_BY, GS.SUBSCRIBED_TIMESTAMP, GS.UNSUBSCRIBED, " + + "GS.UNSUBSCRIBED_BY, GS.UNSUBSCRIBED_TIMESTAMP, GS.AP_APP_RELEASE_ID " + + "FROM AP_GROUP_SUBSCRIPTION GS " + + "JOIN AP_APP_RELEASE AR ON GS.AP_APP_RELEASE_ID = AR.ID " + + "WHERE AR.UUID = ? AND GS.UNSUBSCRIBED = ? AND AR.TENANT_ID = ?"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, uuid); + ps.setBoolean(2, unsubscribe); + ps.setInt(3, tenantId); + try (ResultSet rs = ps.executeQuery()) { + GroupSubscriptionDTO groupDetail; + while (rs.next()) { + groupDetail = new GroupSubscriptionDTO(); + groupDetail.setGroupName(rs.getString("GROUP_NAME")); + groupDetail.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); + groupDetail.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_TIMESTAMP")); + groupDetail.setUnsubscribed(rs.getBoolean("UNSUBSCRIBED")); + groupDetail.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY")); + groupDetail.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_TIMESTAMP")); + groupDetail.setAppReleaseId(rs.getInt("AP_APP_RELEASE_ID")); + + groupDetails.add(groupDetail); + } + } + return groupDetails; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get groups for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting groups for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getUserSubscriptionsByUUID(String uuid, boolean unsubscribe, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get user subscriptions related to the given UUID."); + } + try { + Connection conn = this.getDBConnection(); + List userSubscriptions = new ArrayList<>(); + String sql = "SELECT US.USER_NAME, US.SUBSCRIBED_BY, US.SUBSCRIBED_TIMESTAMP, US.UNSUBSCRIBED, " + + "US.UNSUBSCRIBED_BY, US.UNSUBSCRIBED_TIMESTAMP, US.AP_APP_RELEASE_ID, AR.UUID " + + "FROM AP_USER_SUBSCRIPTION US " + + "JOIN AP_APP_RELEASE AR ON US.AP_APP_RELEASE_ID = AR.ID " + + "WHERE AR.UUID = ? AND US.UNSUBSCRIBED = ? AND AR.TENANT_ID = ?"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, uuid); + ps.setBoolean(2, unsubscribe); + ps.setInt(3, tenantId); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + UserSubscriptionDTO userSubscription; + userSubscription = new UserSubscriptionDTO(); + userSubscription.setUserName(rs.getString("USER_NAME")); + userSubscription.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); + userSubscription.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_TIMESTAMP")); + userSubscription.setUnsubscribed(rs.getBoolean("UNSUBSCRIBED")); + userSubscription.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY")); + userSubscription.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_TIMESTAMP")); + userSubscription.setAppReleaseId(rs.getInt("AP_APP_RELEASE_ID")); + + userSubscriptions.add(userSubscription); + } + } + return userSubscriptions; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get user subscriptions for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting user subscriptions for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getRoleSubscriptionsByUUID(String uuid, boolean unsubscribe, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get role subscriptions related to the given UUID."); + } + try { + Connection conn = this.getDBConnection(); + List roleSubscriptions = new ArrayList<>(); + String sql = "SELECT ARS.ROLE_NAME, ARS.SUBSCRIBED_BY, ARS.SUBSCRIBED_TIMESTAMP, ARS.UNSUBSCRIBED, " + + "ARS.UNSUBSCRIBED_BY, ARS.UNSUBSCRIBED_TIMESTAMP, ARS.AP_APP_RELEASE_ID " + + "FROM AP_ROLE_SUBSCRIPTION ARS " + + "JOIN AP_APP_RELEASE AAR ON ARS.AP_APP_RELEASE_ID = AAR.ID " + + "WHERE AAR.UUID = ? AND ARS.UNSUBSCRIBED = ? AND AAR.TENANT_ID = ?"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, uuid); + ps.setBoolean(2, unsubscribe); + ps.setInt(3, tenantId); + try (ResultSet rs = ps.executeQuery()) { + RoleSubscriptionDTO roleSubscription; + while (rs.next()) { + roleSubscription = new RoleSubscriptionDTO(); + roleSubscription.setRoleName(rs.getString("ROLE_NAME")); + roleSubscription.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); + roleSubscription.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_TIMESTAMP")); + roleSubscription.setUnsubscribed(rs.getBoolean("UNSUBSCRIBED")); + roleSubscription.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY")); + roleSubscription.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_TIMESTAMP")); + roleSubscription.setAppReleaseId(rs.getInt("AP_APP_RELEASE_ID")); + + roleSubscriptions.add(roleSubscription); + } + } + return roleSubscriptions; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get role subscriptions for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting role subscriptions for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getDeviceSubscriptionsOperationsByUUID(String uuid, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get device subscriptions related to the given UUID."); + } + try { + Connection conn = this.getDBConnection(); + List deviceSubscriptions = new ArrayList<>(); + String sql = "SELECT " + + " aar.UUID, " + + " ads.DM_DEVICE_ID, " + + " aasom.OPERATION_ID, " + + " ads.STATUS, " + + " ads.ACTION_TRIGGERED_FROM, " + + " ads.SUBSCRIBED_TIMESTAMP AS ACTION_TRIGGERED_AT, " + + " ads.AP_APP_RELEASE_ID " + + "FROM AP_APP_SUB_OP_MAPPING aasom " + + "JOIN AP_DEVICE_SUBSCRIPTION ads ON aasom.AP_DEVICE_SUBSCRIPTION_ID = ads.ID " + + "JOIN AP_APP_RELEASE aar ON ads.AP_APP_RELEASE_ID = aar.ID " + + "WHERE aar.UUID = ? AND aar.TENANT_ID = ?"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, uuid); + ps.setInt(2, tenantId); + try (ResultSet rs = ps.executeQuery()) { + DeviceOperationDTO deviceSubscription; + while (rs.next()) { + deviceSubscription = new DeviceOperationDTO(); + deviceSubscription.setDeviceId(rs.getInt("DM_DEVICE_ID")); + deviceSubscription.setUuid(rs.getString("UUID")); + deviceSubscription.setStatus(rs.getString("STATUS")); + deviceSubscription.setOperationId(rs.getInt("OPERATION_ID")); + deviceSubscription.setActionTriggeredFrom(rs.getString("ACTION_TRIGGERED_FROM")); + deviceSubscription.setActionTriggeredAt(rs.getTimestamp("ACTION_TRIGGERED_AT")); + deviceSubscription.setAppReleaseId(rs.getInt("AP_APP_RELEASE_ID")); + + deviceSubscriptions.add(deviceSubscription); + } + } + } + return deviceSubscriptions; + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get device subscriptions for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting device subscriptions for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getDeviceSubscriptionsDetails(int appReleaseId, int tenantId) throws + ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting device subscriptions for the application release id " + appReleaseId + + " from the database"); + } + String sql = "SELECT " + + "DS.ID AS ID, " + + "DS.SUBSCRIBED_BY AS SUBSCRIBED_BY, " + + "DS.SUBSCRIBED_TIMESTAMP AS SUBSCRIBED_AT, " + + "DS.UNSUBSCRIBED AS IS_UNSUBSCRIBED, " + + "DS.UNSUBSCRIBED_BY AS UNSUBSCRIBED_BY, " + + "DS.UNSUBSCRIBED_TIMESTAMP AS UNSUBSCRIBED_AT, " + + "DS.ACTION_TRIGGERED_FROM AS ACTION_TRIGGERED_FROM, " + + "DS.STATUS AS STATUS," + + "DS.DM_DEVICE_ID AS DEVICE_ID " + + "FROM AP_DEVICE_SUBSCRIPTION DS " + + "WHERE DS.AP_APP_RELEASE_ID = ? AND DS.TENANT_ID=?"; + + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setInt(2, tenantId); + try (ResultSet rs = ps.executeQuery()) { + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved device subscriptions for application release id " + + appReleaseId); + } + List deviceSubscriptions = new ArrayList<>(); + + DeviceSubscriptionDTO subscription; + while (rs.next()) { + subscription = new DeviceSubscriptionDTO(); + subscription.setId(rs.getInt("ID")); + subscription.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); + subscription.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_AT")); + subscription.setUnsubscribed(rs.getBoolean("IS_UNSUBSCRIBED")); + subscription.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY")); + subscription.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_AT")); + subscription.setActionTriggeredFrom(rs.getString("ACTION_TRIGGERED_FROM")); + subscription.setStatus(rs.getString("STATUS")); + subscription.setDeviceId(rs.getInt("DEVICE_ID")); + + deviceSubscriptions.add(subscription); + } + return deviceSubscriptions; + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection for getting device subscription for " + + "application Id: " + appReleaseId + "."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while while running SQL to get device subscription data for application ID: " + appReleaseId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java index ddfd1cfe46..35f74f9c43 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java @@ -24,11 +24,21 @@ import io.entgra.device.mgt.core.application.mgt.common.ApplicationSubscriptionI import io.entgra.device.mgt.core.application.mgt.common.ApplicationType; import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscriptionData; +import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.GroupSubscriptionDetailDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.UserSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.RoleSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceOperationDTO; import io.entgra.device.mgt.core.application.mgt.common.DeviceTypes; import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus; import io.entgra.device.mgt.core.application.mgt.common.SubAction; import io.entgra.device.mgt.core.application.mgt.common.SubscribingDeviceIdHolder; import io.entgra.device.mgt.core.application.mgt.common.SubscriptionType; +import io.entgra.device.mgt.core.application.mgt.common.dto.GroupSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationPolicyDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.VppAssetDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.VppUserDTO; import io.entgra.device.mgt.core.application.mgt.common.services.VPPApplicationManager; @@ -36,8 +46,12 @@ import io.entgra.device.mgt.core.application.mgt.core.dao.VppApplicationDAO; import io.entgra.device.mgt.core.application.mgt.core.exception.BadRequestException; import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.PaginationResult; +import io.entgra.device.mgt.core.device.mgt.core.dto.GroupDetailsDTO; import io.entgra.device.mgt.core.device.mgt.core.DeviceManagementConstants; import io.entgra.device.mgt.core.application.mgt.core.exception.UnexpectedServerErrorException; +import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOException; +import io.entgra.device.mgt.core.device.mgt.core.dto.OperationDTO; +import io.entgra.device.mgt.core.device.mgt.core.dto.OwnerWithDeviceDTO; import io.entgra.device.mgt.core.device.mgt.extensions.logger.spi.EntgraLogger; import io.entgra.device.mgt.core.notification.logger.AppInstallLogContext; import io.entgra.device.mgt.core.notification.logger.impl.EntgraAppInstallLoggerImpl; @@ -56,11 +70,6 @@ import org.json.JSONObject; import io.entgra.device.mgt.core.apimgt.application.extension.dto.ApiApplicationKey; import io.entgra.device.mgt.core.apimgt.application.extension.exception.APIManagerException; import org.wso2.carbon.context.PrivilegedCarbonContext; -import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationPolicyDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.ApplicationReleaseDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException; import io.entgra.device.mgt.core.application.mgt.common.exception.DBConnectionException; import io.entgra.device.mgt.core.application.mgt.common.exception.LifecycleManagementException; @@ -101,6 +110,7 @@ import io.entgra.device.mgt.core.device.mgt.core.util.MDMIOSOperationUtil; import io.entgra.device.mgt.core.device.mgt.core.util.MDMWindowsOperationUtil; import io.entgra.device.mgt.core.identity.jwt.client.extension.dto.AccessTokenInfo; import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; import javax.ws.rs.core.MediaType; import java.io.BufferedReader; @@ -1564,11 +1574,11 @@ public class SubscriptionManagerImpl implements SubscriptionManager { if (subscription.isUnsubscribed()) { deviceSubscriptionData.setAction(Constants.UNSUBSCRIBED); deviceSubscriptionData.setActionTriggeredBy(subscription.getUnsubscribedBy()); - deviceSubscriptionData.setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp().getTime() / 1000); + deviceSubscriptionData.setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp()); } else { deviceSubscriptionData.setAction(Constants.SUBSCRIBED); deviceSubscriptionData.setActionTriggeredBy(subscription.getSubscribedBy()); - deviceSubscriptionData.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp().getTime() / 1000); + deviceSubscriptionData.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); } deviceSubscriptionData.setActionType(subscription.getActionTriggeredFrom()); deviceSubscriptionData.setStatus(subscription.getStatus()); @@ -1686,4 +1696,440 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } } + @Override + public List getGroupsSubscriptionDetailsByUUID(String uuid, String subscriptionStatus) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); + String groupName; + String status; + + try { + ConnectionManagerUtil.openDBConnection(); + List groupDetailsWithDevices = new ArrayList<>(); + + List groupDetails = subscriptionDAO.getGroupsSubscriptionDetailsByUUID(uuid, unsubscribe, tenantId); + if (groupDetails == null) { + throw new ApplicationManagementException("Group details not found for UUID: " + uuid); + } + + GroupManagementProviderService groupManagementProviderService = HelperUtil.getGroupManagementProviderService(); + + for (GroupSubscriptionDTO groupDetail : groupDetails) { + groupName = groupDetail.getGroupName(); + + // Retrieve group details and device IDs for the group using the service layer + GroupDetailsDTO groupDetailWithDevices = groupManagementProviderService.getGroupDetailsWithDeviceIds(groupName); + + GroupSubscriptionDetailDTO groupDetailDTO = new GroupSubscriptionDetailDTO(); + groupDetailDTO.setGroupId(groupDetailWithDevices.getGroupId()); + groupDetailDTO.setGroupName(groupDetail.getGroupName()); + groupDetailDTO.setGroupOwner(groupDetailWithDevices.getGroupOwner()); + groupDetailDTO.setSubscribedBy(groupDetail.getSubscribedBy()); + groupDetailDTO.setSubscribedTimestamp(groupDetail.getSubscribedTimestamp()); + groupDetailDTO.setUnsubscribed(groupDetail.isUnsubscribed()); + groupDetailDTO.setUnsubscribedBy(groupDetail.getUnsubscribedBy()); + groupDetailDTO.setUnsubscribedTimestamp(groupDetail.getUnsubscribedTimestamp()); + groupDetailDTO.setAppReleaseId(groupDetail.getAppReleaseId()); + groupDetailDTO.setDeviceCount(groupDetailWithDevices.getDeviceCount()); + + // Fetch device subscriptions for each device ID in the group + List pendingDevices = new ArrayList<>(); + List installedDevices = new ArrayList<>(); + List errorDevices = new ArrayList<>(); + List newDevices = new ArrayList<>(); + + List deviceIds = groupDetailWithDevices.getDeviceIds(); + Map statusCounts = new HashMap<>(); + statusCounts.put("PENDING", 0); + statusCounts.put("COMPLETED", 0); + statusCounts.put("ERROR", 0); + statusCounts.put("NEW", 0); + + for (Integer deviceId : deviceIds) { + List deviceSubscriptions = subscriptionDAO.getDeviceSubscriptionsDetails( + groupDetail.getAppReleaseId(), tenantId); + boolean isNewDevice = true; + for (DeviceSubscriptionDTO subscription : deviceSubscriptions) { + if (subscription.getDeviceId() == deviceId) { + DeviceSubscriptionData deviceDetail = new DeviceSubscriptionData(); + deviceDetail.setDeviceId(subscription.getDeviceId()); + deviceDetail.setStatus(subscription.getStatus()); + deviceDetail.setActionType(subscription.getActionTriggeredFrom()); + deviceDetail.setSubId(subscription.getId()); + deviceDetail.setActionTriggeredBy(subscription.getSubscribedBy()); + deviceDetail.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); + + status = subscription.getStatus(); + switch (status) { + case "COMPLETED": + installedDevices.add(deviceDetail); + statusCounts.put("COMPLETED", statusCounts.get("COMPLETED") + 1); + break; + case "ERROR": + case "INVALID": + case "UNAUTHORIZED": + errorDevices.add(deviceDetail); + statusCounts.put("ERROR", statusCounts.get("ERROR") + 1); + break; + case "IN_PROGRESS": + case "PENDING": + case "REPEATED": + pendingDevices.add(deviceDetail); + statusCounts.put("PENDING", statusCounts.get("PENDING") + 1); + break; + } + isNewDevice = false; + } + } + if (isNewDevice) { + DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); + newDeviceDetail.setDeviceId(deviceId); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } + } + + int totalDevices = deviceIds.size(); + Map statusPercentages = new HashMap<>(); + for (Map.Entry entry : statusCounts.entrySet()) { + double percentage = ((double) entry.getValue() / totalDevices) * 100; + statusPercentages.put(entry.getKey(), percentage); + } + + CategorizedSubscriptionResult categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + groupDetailDTO.setDevices(categorizedSubscriptionResult); + groupDetailDTO.setStatusPercentages(statusPercentages); + + groupDetailsWithDevices.add(groupDetailDTO); + } + + return groupDetailsWithDevices; + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while fetching groups and devices for UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "DB Connection error occurred while fetching groups and devices for UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (GroupManagementException e) { + String msg = "Error occurred while fetching group details and device IDs: " + e.getMessage(); + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public List getUserSubscriptionsByUUID(String uuid, String subscriptionStatus) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); + String userName; + String status; + + try { + ConnectionManagerUtil.openDBConnection(); + List userSubscriptionsWithDevices = new ArrayList<>(); + + List userSubscriptions = subscriptionDAO.getUserSubscriptionsByUUID(uuid, unsubscribe, tenantId); + if (userSubscriptions == null) { + throw new ApplicationManagementException("User details not found for UUID: " + uuid); + } + + DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); + + for (UserSubscriptionDTO userSubscription : userSubscriptions) { + userName = userSubscription.getUserName(); + + // Retrieve owner details and device IDs for the user using the service layer + OwnerWithDeviceDTO ownerDetailsWithDevices = deviceManagementProviderService.getOwnersWithDeviceIds(userName); + + UserSubscriptionDTO userSubscriptionDTO = new UserSubscriptionDTO(); + userSubscriptionDTO.setUserName(userSubscription.getUserName()); + userSubscriptionDTO.setSubscribedBy(userSubscription.getSubscribedBy()); + userSubscriptionDTO.setSubscribedTimestamp(userSubscription.getSubscribedTimestamp()); + userSubscriptionDTO.setUnsubscribed(userSubscription.getUnsubscribed()); + userSubscriptionDTO.setUnsubscribedBy(userSubscription.getUnsubscribedBy()); + userSubscriptionDTO.setUnsubscribedTimestamp(userSubscription.getUnsubscribedTimestamp()); + userSubscriptionDTO.setAppReleaseId(userSubscription.getAppReleaseId()); + + userSubscriptionDTO.setDeviceCount(ownerDetailsWithDevices.getDeviceCount()); + + // Fetch device subscriptions for each device ID associated with the user + List pendingDevices = new ArrayList<>(); + List installedDevices = new ArrayList<>(); + List errorDevices = new ArrayList<>(); + List newDevices = new ArrayList<>(); + + List deviceIds = ownerDetailsWithDevices.getDeviceIds(); + Map statusCounts = new HashMap<>(); + statusCounts.put("PENDING", 0); + statusCounts.put("COMPLETED", 0); + statusCounts.put("ERROR", 0); + statusCounts.put("NEW", 0); + + for (Integer deviceId : deviceIds) { + List deviceSubscriptions = subscriptionDAO.getDeviceSubscriptionsDetails( + userSubscription.getAppReleaseId(), tenantId); + boolean isNewDevice = true; + for (DeviceSubscriptionDTO subscription : deviceSubscriptions) { + if (subscription.getDeviceId() == deviceId) { + DeviceSubscriptionData deviceDetail = new DeviceSubscriptionData(); + deviceDetail.setDeviceId(subscription.getDeviceId()); + deviceDetail.setActionType(subscription.getActionTriggeredFrom()); + deviceDetail.setStatus(subscription.getStatus()); + deviceDetail.setActionType(subscription.getActionTriggeredFrom()); + deviceDetail.setActionTriggeredBy(subscription.getSubscribedBy()); + deviceDetail.setSubId(subscription.getId()); + deviceDetail.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); + + status = subscription.getStatus(); + switch (status) { + case "COMPLETED": + installedDevices.add(deviceDetail); + statusCounts.put("COMPLETED", statusCounts.get("COMPLETED") + 1); + break; + case "ERROR": + case "INVALID": + case "UNAUTHORIZED": + errorDevices.add(deviceDetail); + statusCounts.put("ERROR", statusCounts.get("ERROR") + 1); + break; + case "IN_PROGRESS": + case "PENDING": + case "REPEATED": + pendingDevices.add(deviceDetail); + statusCounts.put("PENDING", statusCounts.get("PENDING") + 1); + break; + } + isNewDevice = false; + } + } + if (isNewDevice) { + DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); + newDeviceDetail.setDeviceId(deviceId); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } + } + + int totalDevices = deviceIds.size(); + Map statusPercentages = new HashMap<>(); + for (Map.Entry entry : statusCounts.entrySet()) { + double percentage = ((double) entry.getValue() / totalDevices) * 100; + statusPercentages.put(entry.getKey(), percentage); + } + + CategorizedSubscriptionResult categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + userSubscriptionDTO.setDevices(categorizedSubscriptionResult); + userSubscriptionDTO.setStatusPercentages(statusPercentages); + + userSubscriptionsWithDevices.add(userSubscriptionDTO); + } + + return userSubscriptionsWithDevices; + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while getting user subscriptions for the application release UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "DB Connection error occurred while getting user subscriptions for UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DeviceManagementDAOException e) { + throw new RuntimeException(e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public List getRoleSubscriptionsByUUID(String uuid, String subscriptionStatus) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); + String roleName; + String status; + + try { + ConnectionManagerUtil.openDBConnection(); + List roleSubscriptionsWithDevices = new ArrayList<>(); + + List roleSubscriptions = subscriptionDAO.getRoleSubscriptionsByUUID(uuid, unsubscribe, tenantId); + if (roleSubscriptions == null) { + throw new ApplicationManagementException("Role details not found for UUID: " + uuid); + } + + DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); + + for (RoleSubscriptionDTO roleSubscription : roleSubscriptions) { + roleName = roleSubscription.getRoleName(); + + RoleSubscriptionDTO roleSubscriptionDTO = new RoleSubscriptionDTO(); + roleSubscriptionDTO.setRoleName(roleSubscription.getRoleName()); + roleSubscriptionDTO.setSubscribedBy(roleSubscription.getSubscribedBy()); + roleSubscriptionDTO.setSubscribedTimestamp(roleSubscription.getSubscribedTimestamp()); + roleSubscriptionDTO.setUnsubscribed(roleSubscription.getUnsubscribed()); + roleSubscriptionDTO.setUnsubscribedBy(roleSubscription.getUnsubscribedBy()); + roleSubscriptionDTO.setUnsubscribedTimestamp(roleSubscription.getUnsubscribedTimestamp()); + roleSubscriptionDTO.setAppReleaseId(roleSubscription.getAppReleaseId()); + + List pendingDevices = new ArrayList<>(); + List installedDevices = new ArrayList<>(); + List errorDevices = new ArrayList<>(); + List newDevices = new ArrayList<>(); + + Map statusCounts = new HashMap<>(); + statusCounts.put("PENDING", 0); + statusCounts.put("COMPLETED", 0); + statusCounts.put("ERROR", 0); + statusCounts.put("NEW", 0); + + List users = this.getUsersForRole(roleName); + + for (String user : users) { + OwnerWithDeviceDTO ownerDetailsWithDevices; + try { + ownerDetailsWithDevices = deviceManagementProviderService.getOwnersWithDeviceIds(user); + } catch (DeviceManagementDAOException e) { + throw new ApplicationManagementException("Error retrieving owner details with devices for user: " + user, e); + } + + List deviceIds = ownerDetailsWithDevices.getDeviceIds(); + for (Integer deviceId : deviceIds) { + List deviceSubscriptions; + try { + deviceSubscriptions = subscriptionDAO.getDeviceSubscriptionsDetails( + roleSubscription.getAppReleaseId(), tenantId); + } catch (ApplicationManagementDAOException e) { + throw new ApplicationManagementException("Error retrieving device subscriptions", e); + } + + boolean isNewDevice = true; + for (DeviceSubscriptionDTO deviceSubscription : deviceSubscriptions) { + if (deviceSubscription.getDeviceId() == deviceId) { + DeviceSubscriptionData deviceDetail = new DeviceSubscriptionData(); + deviceDetail.setDeviceId(deviceSubscription.getDeviceId()); + deviceDetail.setActionType(deviceSubscription.getActionTriggeredFrom()); + deviceDetail.setStatus(deviceSubscription.getStatus()); + deviceDetail.setActionType(deviceSubscription.getActionTriggeredFrom()); + deviceDetail.setActionTriggeredBy(deviceSubscription.getSubscribedBy()); + deviceDetail.setSubId(deviceSubscription.getId()); + deviceDetail.setActionTriggeredTimestamp(deviceSubscription.getSubscribedTimestamp()); + + status = deviceSubscription.getStatus(); + switch (status) { + case "COMPLETED": + installedDevices.add(deviceDetail); + statusCounts.put("COMPLETED", statusCounts.get("COMPLETED") + 1); + break; + case "ERROR": + case "INVALID": + case "UNAUTHORIZED": + errorDevices.add(deviceDetail); + statusCounts.put("ERROR", statusCounts.get("ERROR") + 1); + break; + case "IN_PROGRESS": + case "PENDING": + case "REPEATED": + pendingDevices.add(deviceDetail); + statusCounts.put("PENDING", statusCounts.get("PENDING") + 1); + break; + } + isNewDevice = false; + } + } + if (isNewDevice) { + DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); + newDeviceDetail.setDeviceId(deviceId); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } + } + } + + int totalDevices = pendingDevices.size() + installedDevices.size() + errorDevices.size() + newDevices.size(); + Map statusPercentages = new HashMap<>(); + for (Map.Entry entry : statusCounts.entrySet()) { + double percentage = totalDevices == 0 ? 0.0 : ((double) entry.getValue() / totalDevices) * 100; + statusPercentages.put(entry.getKey(), percentage); + } + + CategorizedSubscriptionResult categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + roleSubscriptionDTO.setDevices(categorizedSubscriptionResult); + roleSubscriptionDTO.setStatusPercentages(statusPercentages); + roleSubscriptionDTO.setDeviceCount(totalDevices); + + roleSubscriptionsWithDevices.add(roleSubscriptionDTO); + } + + return roleSubscriptionsWithDevices; + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred in retrieving role subscriptions with devices"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while retrieving the database connection"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (UserStoreException e) { + String msg = "Error occurred while retrieving users for role"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + // Get user list for each role + public List getUsersForRole(String roleName) throws UserStoreException { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + int tenantId = ctx.getTenantId(); + UserStoreManager userStoreManager = DataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId).getUserStoreManager(); + String[] users = userStoreManager.getUserListOfRole(roleName); + return Arrays.asList(users); + } + + @Override + public List getDeviceSubscriptionsOperationsByUUID(String uuid) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + if (uuid == null || uuid.isEmpty()) { + throw new IllegalArgumentException("UUID cannot be null or empty."); + } + try { + ConnectionManagerUtil.openDBConnection(); + DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); + List deviceSubscriptions = subscriptionDAO.getDeviceSubscriptionsOperationsByUUID(uuid, tenantId); + for (DeviceOperationDTO deviceSubscription : deviceSubscriptions) { + Integer operationId = deviceSubscription.getOperationId(); + if (operationId != null) { + OperationDTO operationDetails = deviceManagementProviderService.getOperationDetailsById(operationId); + if (operationDetails != null) { + deviceSubscription.setOperationCode(operationDetails.getOperationCode()); + deviceSubscription.setOperationDetails(operationDetails.getOperationDetails()); + deviceSubscription.setOperationProperties(operationDetails.getOperationProperties()); + } + } + } + return deviceSubscriptions; + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while retrieving device subscriptions for UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while retrieving the database connection"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (OperationManagementException e) { + throw new RuntimeException(e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/EnrollmentDAO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/EnrollmentDAO.java index e42d5c1524..5b2b35a29e 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/EnrollmentDAO.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/EnrollmentDAO.java @@ -21,9 +21,11 @@ import io.entgra.device.mgt.core.device.mgt.common.Device; import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier; import io.entgra.device.mgt.core.device.mgt.common.EnrolmentInfo; import io.entgra.device.mgt.core.device.mgt.common.EnrolmentInfo.Status; +import io.entgra.device.mgt.core.device.mgt.core.dto.OwnerWithDeviceDTO; import java.sql.Timestamp; import java.util.List; +import java.util.Map; public interface EnrollmentDAO { @@ -94,5 +96,13 @@ public interface EnrollmentDAO { */ boolean addDeviceStatus(int enrolmentId, EnrolmentInfo.Status status) throws DeviceManagementDAOException; - + /** + * Retrieves owners and the list of device IDs related to an owner. + * + * @param owner the owner whose device IDs need to be retrieved + * @param tenantId the ID of the tenant + * @return a map containing owner details, device IDs, and device count + * @throws DeviceManagementDAOException if an error occurs while fetching the data + */ + OwnerWithDeviceDTO getOwnersWithDeviceIds(String owner, int tenantId) throws DeviceManagementDAOException; } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/GroupDAO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/GroupDAO.java index b3c4321df3..34dc3213df 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/GroupDAO.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/GroupDAO.java @@ -21,9 +21,9 @@ package io.entgra.device.mgt.core.device.mgt.core.dao; import io.entgra.device.mgt.core.device.mgt.common.Device; import io.entgra.device.mgt.core.device.mgt.common.GroupPaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; -import io.entgra.device.mgt.core.device.mgt.common.exceptions.ReportManagementException; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupRoleWrapper; +import io.entgra.device.mgt.core.device.mgt.core.dto.GroupDetailsDTO; import java.util.List; import java.util.Map; @@ -469,4 +469,14 @@ public interface GroupDAO { List groupNames) throws GroupManagementDAOException; + /** + * Get group details and list of device IDs related to the group. + * + * @param groupName Group name + * @param tenantId Tenant ID + * @return A map containing group details and a list of device IDs + * @throws GroupManagementDAOException if an error occurs while retrieving the group details and devices + */ + GroupDetailsDTO getGroupDetailsWithDeviceIds(String groupName, int tenantId) throws GroupManagementDAOException; + } \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractEnrollmentDAOImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractEnrollmentDAOImpl.java index 8bde335227..4bc6627b3f 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractEnrollmentDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractEnrollmentDAOImpl.java @@ -26,6 +26,7 @@ import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOExceptio import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.core.dao.EnrollmentDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.util.DeviceManagementDAOUtil; +import io.entgra.device.mgt.core.device.mgt.core.dto.OwnerWithDeviceDTO; import java.sql.Connection; import java.sql.PreparedStatement; @@ -33,9 +34,9 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; -import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.ArrayList; public abstract class AbstractEnrollmentDAOImpl implements EnrollmentDAO { @@ -557,4 +558,36 @@ public abstract class AbstractEnrollmentDAOImpl implements EnrollmentDAO { return enrolmentInfo; } + @Override + public OwnerWithDeviceDTO getOwnersWithDeviceIds(String owner, int tenantId) throws DeviceManagementDAOException { + + OwnerWithDeviceDTO ownerDetails = new OwnerWithDeviceDTO(); + List deviceIds = new ArrayList<>(); + int deviceCount = 0; + + String sql = "SELECT DEVICE_ID, OWNER FROM DM_ENROLMENT WHERE OWNER = ? AND TENANT_ID = ?"; + + try (Connection conn = this.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, owner); + stmt.setInt(2, tenantId); + + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + if (ownerDetails.getUserName() == null) { + ownerDetails.setUserName(rs.getString("OWNER")); + } + deviceIds.add(rs.getInt("DEVICE_ID")); + deviceCount++; + } + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving owners and device IDs for owner: " + owner, e); + } + + ownerDetails.setDeviceIds(deviceIds); + ownerDetails.setDeviceCount(deviceCount); + return ownerDetails; + } + } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java index c65692870d..476b447f1a 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java @@ -26,6 +26,7 @@ import io.entgra.device.mgt.core.device.mgt.common.Device; import io.entgra.device.mgt.core.device.mgt.common.GroupPaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroup; +import io.entgra.device.mgt.core.device.mgt.core.dto.GroupDetailsDTO; import io.entgra.device.mgt.core.device.mgt.core.dao.GroupDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.GroupManagementDAOException; import io.entgra.device.mgt.core.device.mgt.core.dao.GroupManagementDAOFactory; @@ -1437,4 +1438,43 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { } return groupUnassignedDeviceList; } + + @Override + public GroupDetailsDTO getGroupDetailsWithDeviceIds(String groupName, int tenantId) throws GroupManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get group details and device IDs for group: " + groupName); + } + + GroupDetailsDTO groupDetails = new GroupDetailsDTO(); + List deviceIds = new ArrayList<>(); + + String sql = "SELECT g.ID AS GROUP_ID, g.GROUP_NAME, g.OWNER, dgm.DEVICE_ID " + + "FROM DM_GROUP g " + + "JOIN DM_DEVICE_GROUP_MAP dgm ON g.ID = dgm.GROUP_ID " + + "WHERE g.GROUP_NAME = ? AND g.TENANT_ID = ?"; + + try (Connection conn = GroupManagementDAOFactory.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, groupName); + stmt.setInt(2, tenantId); + + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + if (groupDetails.getGroupId() == 0) { + groupDetails.setGroupId(rs.getInt("GROUP_ID")); + groupDetails.setGroupName(rs.getString("GROUP_NAME")); + groupDetails.setGroupOwner(rs.getString("OWNER")); + } + deviceIds.add(rs.getInt("DEVICE_ID")); + } + } + } catch (SQLException e) { + throw new GroupManagementDAOException("Error occurred while retrieving group details and device IDs for group: " + + groupName, e); + } + + groupDetails.setDeviceIds(deviceIds); + groupDetails.setDeviceCount(deviceIds.size()); + return groupDetails; + } } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/GroupDetailsDTO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/GroupDetailsDTO.java new file mode 100644 index 0000000000..333999aeeb --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/GroupDetailsDTO.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.device.mgt.core.dto; + +import java.util.List; + +public class GroupDetailsDTO { + private int groupId; + private String groupName; + private String groupOwner; + private List deviceIds; + private int deviceCount; + + public int getGroupId() { + return groupId; + } + + public void setGroupId(int groupId) { + this.groupId = groupId; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public String getGroupOwner() { + return groupOwner; + } + + public void setGroupOwner(String groupOwner) { + this.groupOwner = groupOwner; + } + + public List getDeviceIds() { + return deviceIds; + } + + public void setDeviceIds(List deviceIds) { + this.deviceIds = deviceIds; + } + + public int getDeviceCount() { + return deviceCount; + } + + public void setDeviceCount(int deviceCount) { + this.deviceCount = deviceCount; + } + +} diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OperationDTO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OperationDTO.java new file mode 100644 index 0000000000..b6ac94fc3c --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OperationDTO.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.device.mgt.core.dto; + +import org.json.JSONObject; + +import java.sql.Timestamp; + +public class OperationDTO { + private int deviceId; + private String uuid; + private String status; + private int operationId; + private String actionTriggeredFrom; + private Timestamp actionTriggeredAt; + private int appReleaseId; + private String operationCode; + private JSONObject operationDetails; + private JSONObject operationProperties; + + // Getters and Setters + + public int getDeviceId() { + return deviceId; + } + + public void setDeviceId(int deviceId) { + this.deviceId = deviceId; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public int getOperationId() { + return operationId; + } + + public void setOperationId(int operationId) { + this.operationId = operationId; + } + + public String getActionTriggeredFrom() { + return actionTriggeredFrom; + } + + public void setActionTriggeredFrom(String actionTriggeredFrom) { + this.actionTriggeredFrom = actionTriggeredFrom; + } + + public Timestamp getActionTriggeredAt() { + return actionTriggeredAt; + } + + public void setActionTriggeredAt(Timestamp actionTriggeredAt) { + this.actionTriggeredAt = actionTriggeredAt; + } + + public int getAppReleaseId() { + return appReleaseId; + } + + public void setAppReleaseId(int appReleaseId) { + this.appReleaseId = appReleaseId; + } + + public String getOperationCode() { + return operationCode; + } + + public void setOperationCode(String operationCode) { + this.operationCode = operationCode; + } + + public JSONObject getOperationDetails() { + return operationDetails; + } + + public void setOperationDetails(JSONObject operationDetails) { + this.operationDetails = operationDetails; + } + + public JSONObject getOperationProperties() { + return operationProperties; + } + + public void setOperationProperties(JSONObject operationProperties) { + this.operationProperties = operationProperties; + } +} diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OwnerWithDeviceDTO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OwnerWithDeviceDTO.java new file mode 100644 index 0000000000..cd3e26bfbc --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OwnerWithDeviceDTO.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.device.mgt.core.device.mgt.core.dto; + +import java.util.List; + +public class OwnerWithDeviceDTO { + + private String userName; + private List deviceIds; + private int deviceCount; + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public List getDeviceIds() { + return deviceIds; + } + + public void setDeviceIds(List deviceIds) { + this.deviceIds = deviceIds; + } + + public int getDeviceCount() { + return deviceCount; + } + + public void setDeviceCount(int deviceCount) { + this.deviceCount = deviceCount; + } +} diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/OperationDAO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/OperationDAO.java index 4abaf40022..5171b03b95 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/OperationDAO.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/OperationDAO.java @@ -23,6 +23,8 @@ import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.OperationResponse; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.DeviceActivity; +import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOException; +import io.entgra.device.mgt.core.device.mgt.core.dto.OperationDTO; import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.Operation; import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.OperationResponseMeta; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.OperationMapping; @@ -124,4 +126,6 @@ public interface OperationDAO { int getDeviceActivitiesCount(ActivityPaginationRequest activityPaginationRequest) throws OperationManagementDAOException; + + OperationDTO getOperationDetailsById(int operationId, int tenantId) throws OperationManagementDAOException; } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java index 8322905a5e..15751c3d89 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java @@ -17,32 +17,35 @@ */ package io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.impl; -import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.ProfileOperation; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.context.PrivilegedCarbonContext; import io.entgra.device.mgt.core.device.mgt.common.ActivityPaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier; import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity; -import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.DeviceActivity; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.ActivityHolder; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.ActivityStatus; +import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.DeviceActivity; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.OperationResponse; import io.entgra.device.mgt.core.device.mgt.core.DeviceManagementConstants; import io.entgra.device.mgt.core.device.mgt.core.dao.util.DeviceManagementDAOUtil; +import io.entgra.device.mgt.core.device.mgt.core.dto.OperationDTO; import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.Operation; import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.OperationResponseMeta; +import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.ProfileOperation; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.OperationMapping; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationDAO; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOException; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOUtil; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.util.OperationDAOUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.JSONObject; +import org.wso2.carbon.context.PrivilegedCarbonContext; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; +import java.sql.Blob; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -2774,4 +2777,43 @@ public class GenericOperationDAOImpl implements OperationDAO { } return 0; } + + @Override + public OperationDTO getOperationDetailsById(int operationId, int tenantId) throws OperationManagementDAOException { + OperationDTO operationDetails = new OperationDTO(); + + String sql = "SELECT ID, OPERATION_CODE, OPERATION_DETAILS, OPERATION_PROPERTIES " + + "FROM DM_OPERATION " + + "WHERE ID = ? AND TENANT_ID = ?"; + + try (Connection conn = OperationManagementDAOFactory.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, operationId); + stmt.setInt(2, tenantId); + + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + operationDetails.setOperationId(rs.getInt("ID")); + operationDetails.setOperationCode(rs.getString("OPERATION_CODE")); + + Blob detailsBlob = rs.getBlob("OPERATION_DETAILS"); + if (detailsBlob != null) { + JSONObject operationDetailsJson = OperationDAOUtil.convertBlobToJsonObject(detailsBlob); + operationDetails.setOperationDetails(operationDetailsJson); + } + + Blob propertiesBlob = rs.getBlob("OPERATION_PROPERTIES"); + if (propertiesBlob != null) { + JSONObject operationPropertiesJson = OperationDAOUtil.convertBlobToJsonObject(propertiesBlob); + operationDetails.setOperationProperties(operationPropertiesJson); + } + } + } + } catch (SQLException e) { + throw new OperationManagementDAOException("Error occurred while retrieving operation details for operation ID: " + + operationId, e); + } + + return operationDetails; + } } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/util/OperationDAOUtil.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/util/OperationDAOUtil.java index 6561868060..3d5dd193ca 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/util/OperationDAOUtil.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/util/OperationDAOUtil.java @@ -33,10 +33,14 @@ import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.Operation; import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.PolicyOperation; import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.ProfileOperation; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOException; +import org.json.JSONObject; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.ObjectInputStream; +import java.sql.Blob; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; @@ -387,4 +391,43 @@ public class OperationDAOUtil { return operation; } + public static JSONObject convertBlobToJsonObject(Blob blob) throws SQLException { + String jsonString; + try (InputStream inputStream = blob.getBinaryStream(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { + int bytesRead; + byte[] buffer = new byte[4096]; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + byte[] blobBytes = outputStream.toByteArray(); + + // Check if the blob data is a serialized Java object + if (blobBytes.length > 2 && (blobBytes[0] & 0xFF) == 0xAC && (blobBytes[1] & 0xFF) == 0xED) { + // Deserialize the object + try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(blobBytes))) { + Object obj = ois.readObject(); + if (obj instanceof String) { + jsonString = (String) obj; + } else { + jsonString = new JSONObject(obj).toString(); + } + } catch (ClassNotFoundException e) { + throw new SQLException("Failed to deserialize object from BLOB", e); + } + } else { + // If not serialized, treat it as plain JSON string + jsonString = new String(blobBytes, "UTF-8"); + } + } catch (IOException e) { + throw new SQLException("Failed to convert BLOB to JSON string", e); + } + + // Convert JSON string to JSONObject + if (jsonString == null || jsonString.isEmpty()) { + throw new SQLException("Converted JSON string is null or empty"); + } + return new JSONObject(jsonString); + } + } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderService.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderService.java index 689fc1b243..8e112addd3 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderService.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderService.java @@ -19,6 +19,8 @@ package io.entgra.device.mgt.core.device.mgt.core.service; import io.entgra.device.mgt.core.device.mgt.common.app.mgt.Application; +import io.entgra.device.mgt.core.device.mgt.core.dto.OperationDTO; +import io.entgra.device.mgt.core.device.mgt.core.dto.OwnerWithDeviceDTO; import org.apache.commons.collections.map.SingletonMap; import io.entgra.device.mgt.core.device.mgt.common.*; import io.entgra.device.mgt.core.device.mgt.common.app.mgt.ApplicationManagementException; @@ -1073,4 +1075,22 @@ public interface DeviceManagementProviderService { List getEnrolledDevicesSince(Date since) throws DeviceManagementException; List getEnrolledDevicesPriorTo(Date before) throws DeviceManagementException; void deleteDeviceDataByTenantDomain(String tenantDomain) throws DeviceManagementException; + + /** + * Get owner details and device IDs for a given owner and tenant. + * + * @param owner the name of the owner. + * @return a map containing owner details (Owner, DeviceIds, DeviceCount). + * @throws DeviceManagementException if an error occurs while fetching owner details. + */ + OwnerWithDeviceDTO getOwnersWithDeviceIds(String owner) throws DeviceManagementDAOException; + + /** + * Get operation details by operation code. + * + * @param operationId the id of the operation. + * @return Map containing operation ID, operation code, operation details, and operation properties. + * @throws OperationManagementException if an error occurs while fetching the operation details. + */ + OperationDTO getOperationDetailsById(int operationId) throws OperationManagementException; } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index 75f3836a34..3df333cbf2 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderServiceImpl.java @@ -22,6 +22,10 @@ import com.google.common.reflect.TypeToken; import com.google.gson.Gson; import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.DeviceStatusManagementService; import io.entgra.device.mgt.core.device.mgt.core.dao.TenantDAO; +import io.entgra.device.mgt.core.device.mgt.core.dto.OwnerWithDeviceDTO; +import io.entgra.device.mgt.core.device.mgt.core.dto.OperationDTO; +import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOException; +import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.extensions.logger.spi.EntgraLogger; import io.entgra.device.mgt.core.notification.logger.DeviceEnrolmentLogContext; import io.entgra.device.mgt.core.notification.logger.impl.EntgraDeviceEnrolmentLoggerImpl; @@ -120,6 +124,7 @@ import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceStatusDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceTypeDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.EnrollmentDAO; +import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.util.DeviceManagementDAOUtil; import io.entgra.device.mgt.core.device.mgt.core.device.details.mgt.DeviceDetailsMgtException; import io.entgra.device.mgt.core.device.mgt.core.device.details.mgt.DeviceInformationManager; @@ -173,6 +178,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv private final DeviceDAO deviceDAO; private final DeviceTypeDAO deviceTypeDAO; private final EnrollmentDAO enrollmentDAO; + private final OperationDAO operationDAO; private final ApplicationDAO applicationDAO; private MetadataDAO metadataDAO; private final DeviceStatusDAO deviceStatusDAO; @@ -185,6 +191,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv this.applicationDAO = DeviceManagementDAOFactory.getApplicationDAO(); this.deviceTypeDAO = DeviceManagementDAOFactory.getDeviceTypeDAO(); this.enrollmentDAO = DeviceManagementDAOFactory.getEnrollmentDAO(); + this.operationDAO = OperationManagementDAOFactory.getOperationDAO(); this.metadataDAO = MetadataManagementDAOFactory.getMetadataDAO(); this.deviceStatusDAO = DeviceManagementDAOFactory.getDeviceStatusDAO(); this.tenantDao = DeviceManagementDAOFactory.getTenantDAO(); @@ -5339,4 +5346,52 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv DeviceManagementDAOFactory.closeConnection(); } } + + @Override + public OwnerWithDeviceDTO getOwnersWithDeviceIds(String owner) throws DeviceManagementDAOException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + OwnerWithDeviceDTO ownerWithDeviceDTO; + + try { + DeviceManagementDAOFactory.openConnection(); + ownerWithDeviceDTO = this.enrollmentDAO.getOwnersWithDeviceIds(owner, tenantId); + } catch (DeviceManagementDAOException | SQLException e) { + String msg = "Error occurred while retrieving device IDs for owner: " + owner; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + + // Add device count to the DTO + if (ownerWithDeviceDTO != null) { + List deviceIds = ownerWithDeviceDTO.getDeviceIds(); + if (deviceIds != null) { + ownerWithDeviceDTO.setDeviceCount(deviceIds.size()); + } else { + ownerWithDeviceDTO.setDeviceCount(0); + } + } + + return ownerWithDeviceDTO; + } + + @Override + public OperationDTO getOperationDetailsById(int operationId) throws OperationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + OperationDTO operationDetails; + try { + OperationManagementDAOFactory.openConnection(); + operationDetails = this.operationDAO.getOperationDetailsById(operationId, tenantId); + } catch (SQLException | OperationManagementDAOException e) { + String msg = "Error occurred while retrieving operation details for operation ID: " + operationId; + log.error(msg, e); + throw new OperationManagementException(msg, e); + } finally { + OperationManagementDAOFactory.closeConnection(); + } + + return operationDetails; + } + } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderService.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderService.java index 2c741730bd..6c262ccf2d 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderService.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderService.java @@ -30,6 +30,7 @@ import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupAlreadyExistEx import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupManagementException; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupNotExistException; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.RoleDoesNotExistException; +import io.entgra.device.mgt.core.device.mgt.core.dto.GroupDetailsDTO; import org.wso2.carbon.user.api.AuthorizationManager; import org.wso2.carbon.user.api.UserStoreManager; @@ -371,4 +372,14 @@ public interface GroupManagementProviderService { DeviceTypesOfGroups getDeviceTypesOfGroups(List identifiers) throws GroupManagementException; DeviceGroup getUserOwnGroup(int groupId, boolean requireGroupProps, int depth) throws GroupManagementException; + + /** + * Get group details and device IDs for a given group name. + * + * @param groupName the name of the group. + * @return a map containing group details and device IDs. + * @throws GroupManagementException if an error occurs while fetching group details. + */ + GroupDetailsDTO getGroupDetailsWithDeviceIds(String groupName) throws GroupManagementException; + } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderServiceImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderServiceImpl.java index 88aad71dcd..43e2a8eecc 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderServiceImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderServiceImpl.java @@ -26,13 +26,13 @@ import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupAlreadyExistEx import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupManagementException; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.GroupNotExistException; import io.entgra.device.mgt.core.device.mgt.common.group.mgt.RoleDoesNotExistException; +import io.entgra.device.mgt.core.device.mgt.core.dto.GroupDetailsDTO; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOException; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.core.dao.GroupDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.GroupManagementDAOException; import io.entgra.device.mgt.core.device.mgt.core.dao.GroupManagementDAOFactory; -import io.entgra.device.mgt.core.device.mgt.core.permission.mgt.PermissionManagerServiceImpl; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -1629,6 +1629,7 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid createGroupWithChildren(nextParentGroup, childrenGroups, requireGroupProps, tenantId, depth, counter); } } + @Override public DeviceTypesOfGroups getDeviceTypesOfGroups(List identifiers) throws GroupManagementException { DeviceTypesOfGroups deviceTypesOfGroups = new DeviceTypesOfGroups(); @@ -1685,4 +1686,37 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid return deviceTypesOfGroups; } + + @Override + public GroupDetailsDTO getGroupDetailsWithDeviceIds(String groupName) throws GroupManagementException { + if (log.isDebugEnabled()) { + log.debug("Retrieving group details and device IDs for group: " + groupName); + } + int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId(); + GroupDetailsDTO groupDetailsWithDevices; + + try { + GroupManagementDAOFactory.openConnection(); + groupDetailsWithDevices = this.groupDAO.getGroupDetailsWithDeviceIds(groupName, tenantId); + } catch (GroupManagementDAOException | SQLException e) { + String msg = "Error occurred while retrieving group details and device IDs for group: " + groupName; + log.error(msg, e); + throw new GroupManagementException(msg, e); + } finally { + GroupManagementDAOFactory.closeConnection(); + } + + // Add device count + if (groupDetailsWithDevices != null) { + List deviceIds = (List) groupDetailsWithDevices.getDeviceIds(); + if (deviceIds != null) { + groupDetailsWithDevices.setDeviceCount(deviceIds.size()); + } else { + groupDetailsWithDevices.setDeviceCount(0); + } + } + + return groupDetailsWithDevices; + } + } From 74e52e46b78ef91185c442c70acfda3a1ae71232 Mon Sep 17 00:00:00 2001 From: nipuni Date: Mon, 10 Jun 2024 16:02:18 +0530 Subject: [PATCH 12/17] DAO and Services for APIs to populate the installation details static UI. --- .../mgt/common/DeviceSubscriptionData.java | 8 +- .../dto/CategorizedSubscriptionCountsDTO.java | 55 +++ .../mgt/common/dto/DeviceSubscriptionDTO.java | 82 +++- .../common/services/SubscriptionManager.java | 13 +- .../mgt/core/dao/SubscriptionDAO.java | 110 +++++ .../GenericSubscriptionDAOImpl.java | 390 ++++++++++++++++++ .../core/impl/SubscriptionManagerImpl.java | 60 +++ 7 files changed, 699 insertions(+), 19 deletions(-) create mode 100644 components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/CategorizedSubscriptionCountsDTO.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/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 5ea565af90..633b54ce73 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 @@ -75,9 +75,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; 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/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/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 9fa1defa8b..90c7099519 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 @@ -21,6 +21,7 @@ import io.entgra.device.mgt.core.application.mgt.common.ApplicationInstallRespon 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.GroupSubscriptionDetailDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.UserSubscriptionDTO; @@ -35,7 +36,6 @@ import io.entgra.device.mgt.core.device.mgt.common.app.mgt.App; import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity; import java.util.List; -import java.util.Map; import java.util.Properties; /** @@ -264,4 +264,15 @@ public interface SubscriptionManager { List getDeviceSubscriptionsOperationsByUUID(String uuid) 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 925bd9c231..a9b90375db 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 @@ -374,4 +374,114 @@ public interface SubscriptionDAO { */ List getDeviceSubscriptionsDetails(int appReleaseId, int tenantId) 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 2dca5ac0a0..c005100fd9 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 @@ -1892,5 +1892,395 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } } + @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 35f74f9c43..79c257319b 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java @@ -24,6 +24,7 @@ import io.entgra.device.mgt.core.application.mgt.common.ApplicationSubscriptionI import io.entgra.device.mgt.core.application.mgt.common.ApplicationType; import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; import io.entgra.device.mgt.core.application.mgt.common.DeviceSubscriptionData; +import io.entgra.device.mgt.core.application.mgt.common.dto.CategorizedSubscriptionCountsDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.GroupSubscriptionDetailDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.UserSubscriptionDTO; @@ -42,6 +43,7 @@ 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; @@ -143,12 +145,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(); } @@ -2132,4 +2136,60 @@ public class SubscriptionManagerImpl implements SubscriptionManager { 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(); + } + } } From 664c1e9e5acf57b66ab453d9993f180534c8c423 Mon Sep 17 00:00:00 2001 From: nipuni Date: Thu, 13 Jun 2024 05:56:07 +0530 Subject: [PATCH 13/17] Generalize application subscription APIs --- .../common/CategorizedSubscriptionResult.java | 26 +- .../mgt/common/DeviceSubscriptionData.java | 45 ++ .../dto/DeviceSubscriptionResponseDTO.java | 42 ++ .../dto/GroupSubscriptionDetailDTO.java | 18 + .../mgt/common/dto/UserSubscriptionDTO.java | 8 + .../common/services/SubscriptionManager.java | 58 +- .../mgt/core/dao/SubscriptionDAO.java | 102 ++-- .../GenericSubscriptionDAOImpl.java | 212 ++++++- .../core/impl/SubscriptionManagerImpl.java | 557 ++++++++++++++++-- .../device/mgt/core/dao/EnrollmentDAO.java | 27 +- .../core/device/mgt/core/dao/GroupDAO.java | 7 +- .../dao/impl/AbstractEnrollmentDAOImpl.java | 69 ++- .../core/dao/impl/AbstractGroupDAOImpl.java | 25 +- .../device/mgt/core/dto/DeviceDetailsDTO.java | 31 + .../device/mgt/core/dto/GroupDetailsDTO.java | 36 ++ .../mgt/core/dto/OwnerWithDeviceDTO.java | 9 + .../core/operation/mgt/dao/OperationDAO.java | 11 +- .../mgt/dao/impl/GenericOperationDAOImpl.java | 3 +- .../DeviceManagementProviderService.java | 22 +- .../DeviceManagementProviderServiceImpl.java | 52 +- .../GroupManagementProviderService.java | 6 +- .../GroupManagementProviderServiceImpl.java | 8 +- 22 files changed, 1229 insertions(+), 145 deletions(-) create mode 100644 components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/DeviceSubscriptionResponseDTO.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 diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java index 60531ac8aa..28cc436115 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/CategorizedSubscriptionResult.java @@ -25,8 +25,8 @@ public class CategorizedSubscriptionResult { private List pendingDevices; private List errorDevices; private List newDevices; + private List subscribedDevices; - // without newDevices public CategorizedSubscriptionResult(List installedDevices, List pendingDevices, List errorDevices) { @@ -34,9 +34,9 @@ public class CategorizedSubscriptionResult { this.pendingDevices = pendingDevices; this.errorDevices = errorDevices; this.newDevices = null; + this.subscribedDevices = null; } - // with newDevices public CategorizedSubscriptionResult(List installedDevices, List pendingDevices, List errorDevices, @@ -45,6 +45,19 @@ public class CategorizedSubscriptionResult { this.pendingDevices = pendingDevices; this.errorDevices = errorDevices; this.newDevices = newDevices; + this.subscribedDevices = null; + } + + public CategorizedSubscriptionResult(List installedDevices, + List pendingDevices, + List errorDevices, + List newDevices, + List subscribedDevices) { + this.installedDevices = installedDevices; + this.pendingDevices = pendingDevices; + this.errorDevices = errorDevices; + this.newDevices = newDevices; + this.subscribedDevices = subscribedDevices; } public List getInstalledDevices() { @@ -78,4 +91,13 @@ public class CategorizedSubscriptionResult { public void setNewDevices(List newDevices) { this.newDevices = newDevices; } + + public List getSubscribedDevices() { + return subscribedDevices; + } + + public void setSubscribedDevices(List subscribedDevices) { + this.subscribedDevices = subscribedDevices; + } } + diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/DeviceSubscriptionData.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/DeviceSubscriptionData.java index 633b54ce73..aadbfaca6a 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/DeviceSubscriptionData.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/DeviceSubscriptionData.java @@ -34,6 +34,11 @@ public class DeviceSubscriptionData { private Device device; private String currentInstalledVersion; private int deviceId; + private String deviceOwner; + private String deviceStatus; + private boolean unsubscribed; + private String unsubscribedBy; + private Timestamp unsubscribedTimestamp; public String getAction() { return action; @@ -114,4 +119,44 @@ public class DeviceSubscriptionData { public void setActionTriggeredTimestamp(Timestamp actionTriggeredTimestamp) { this.actionTriggeredTimestamp = actionTriggeredTimestamp; } + + public String getDeviceOwner() { + return deviceOwner; + } + + public void setDeviceOwner(String deviceOwner) { + this.deviceOwner = deviceOwner; + } + + public String getDeviceStatus() { + return deviceStatus; + } + + public void setDeviceStatus(String deviceStatus) { + this.deviceStatus = deviceStatus; + } + + public boolean isUnsubscribed() { + return unsubscribed; + } + + public void setUnsubscribed(boolean unsubscribed) { + this.unsubscribed = unsubscribed; + } + + public String getUnsubscribedBy() { + return unsubscribedBy; + } + + public void setUnsubscribedBy(String unsubscribedBy) { + this.unsubscribedBy = unsubscribedBy; + } + + public Timestamp getUnsubscribedTimestamp() { + return unsubscribedTimestamp; + } + + public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) { + this.unsubscribedTimestamp = unsubscribedTimestamp; + } } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/DeviceSubscriptionResponseDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/DeviceSubscriptionResponseDTO.java new file mode 100644 index 0000000000..ded2032521 --- /dev/null +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/DeviceSubscriptionResponseDTO.java @@ -0,0 +1,42 @@ +package io.entgra.device.mgt.core.application.mgt.common.dto; + +import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionResult; + +import java.util.Map; + +public class DeviceSubscriptionResponseDTO { + private int deviceCount; + private Map statusPercentages; + private CategorizedSubscriptionResult devices; + + public DeviceSubscriptionResponseDTO(int deviceCount, Map statusPercentages, + CategorizedSubscriptionResult devices) { + this.deviceCount = deviceCount; + this.statusPercentages = statusPercentages; + this.devices = devices; + } + + public int getDeviceCount() { + return deviceCount; + } + + public void setDeviceCount(int deviceCount) { + this.deviceCount = deviceCount; + } + + public Map getStatusPercentages() { + return statusPercentages; + } + + public void setStatusPercentages(Map statusPercentages) { + this.statusPercentages = statusPercentages; + } + + public CategorizedSubscriptionResult getDevices() { + return devices; + } + + public void setDevices(CategorizedSubscriptionResult devices) { + this.devices = devices; + } +} diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDetailDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDetailDTO.java index 442d82faed..bc215b1e30 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDetailDTO.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDetailDTO.java @@ -34,6 +34,8 @@ public class GroupSubscriptionDetailDTO { private Timestamp unsubscribedTimestamp; private int appReleaseId; private int deviceCount; + private String deviceOwner; + private String deviceStatus; private CategorizedSubscriptionResult devices; private Map statusPercentages; @@ -133,4 +135,20 @@ public class GroupSubscriptionDetailDTO { public void setStatusPercentages(Map statusPercentages) { this.statusPercentages = statusPercentages; } + + public String getDeviceOwner() { + return deviceOwner; + } + + public void setDeviceOwner(String deviceOwner) { + this.deviceOwner = deviceOwner; + } + + public String getDeviceStatus() { + return deviceStatus; + } + + public void setDeviceStatus(String deviceStatus) { + this.deviceStatus = deviceStatus; + } } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/UserSubscriptionDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/UserSubscriptionDTO.java index 7238f7ebba..d3fd89f004 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/UserSubscriptionDTO.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/UserSubscriptionDTO.java @@ -33,6 +33,7 @@ public class UserSubscriptionDTO { private Timestamp unsubscribedTimestamp; private int appReleaseId; private int deviceCount; + private String deviceStatus; private Map statusPercentages; private CategorizedSubscriptionResult devices; @@ -120,5 +121,12 @@ public class UserSubscriptionDTO { this.devices = devices; } + public String getDeviceStatus() { + return deviceStatus; + } + + public void setDeviceStatus(String deviceStatus) { + this.deviceStatus = deviceStatus; + } } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java index 90c7099519..fc0463add2 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java @@ -27,6 +27,7 @@ import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptio import io.entgra.device.mgt.core.application.mgt.common.dto.UserSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.RoleSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceOperationDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionResponseDTO; import io.entgra.device.mgt.core.application.mgt.common.exception.ApplicationManagementException; import io.entgra.device.mgt.core.application.mgt.common.exception.SubscriptionManagementException; import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier; @@ -228,40 +229,77 @@ public interface SubscriptionManager { * Retrieves the group details associated with a given app release UUID. * * @param uuid the UUID of the app release - * @return a list of maps containing group details and their associated devices + * @param subscriptionStatus the status of the subscription (subscribed or unsubscribed) + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link GroupSubscriptionDetailDTO} which contains the details of group subscriptions. * @throws ApplicationManagementException if an error occurs while fetching the group details */ - List getGroupsSubscriptionDetailsByUUID(String uuid, String subscriptionStatus) + List getGroupsSubscriptionDetailsByUUID(String uuid, String subscriptionStatus, int offset, int limit) throws ApplicationManagementException; /** * Retrieves the user details associated with a given app release UUID. * * @param uuid the UUID of the app release - * @return a list of maps containing user details and their associated devices - * @throws ApplicationManagementException if an error occurs while fetching the group details + * @param subscriptionStatus the status of the subscription (subscribed or unsubscribed) + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link UserSubscriptionDTO} which contains the details of user subscriptions. + * @throws ApplicationManagementException if an error occurs while fetching the user details */ - List getUserSubscriptionsByUUID(String uuid, String subscriptionStatus) + List getUserSubscriptionsByUUID(String uuid, String subscriptionStatus, int offset, int limit) throws ApplicationManagementException; /** * Retrieves the Role details associated with a given app release UUID. * * @param uuid the UUID of the app release - * @return a list of maps containing role details and their associated devices - * @throws ApplicationManagementException if an error occurs while fetching the group details + * @param subscriptionStatus the status of the subscription (subscribed or unsubscribed) + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link RoleSubscriptionDTO} which contains the details of role subscriptions. + * @throws ApplicationManagementException if an error occurs while fetching the role details + */ + List getRoleSubscriptionsByUUID(String uuid, String subscriptionStatus, int offset, int limit) + throws ApplicationManagementException; + + /** + * Retrieves the Device Subscription details associated with a given app release UUID. + * + * @param uuid the UUID of the app release + * @param subscriptionStatus the status of the subscription (subscribed or unsubscribed) + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link DeviceSubscriptionResponseDTO} which contains the details of device subscriptions. + * @throws ApplicationManagementException if an error occurs while fetching the device subscription details + */ + DeviceSubscriptionResponseDTO getDeviceSubscriptionsDetailsByUUID(String uuid, String subscriptionStatus, int offset, int limit) + throws ApplicationManagementException; + + /** + * Retrieves the All Device details associated with a given app release UUID. + * + * @param uuid the UUID of the app release + * @param subscriptionStatus the status of the subscription (subscribed or unsubscribed) + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link DeviceSubscriptionResponseDTO} which contains the details of device subscriptions. + * @throws ApplicationManagementException if an error occurs while fetching the subscription details */ - List getRoleSubscriptionsByUUID(String uuid, String subscriptionStatus) + DeviceSubscriptionResponseDTO getAllSubscriptionDetailsByUUID(String uuid, String subscriptionStatus, int offset, int limit) throws ApplicationManagementException; /** * This method is responsible for retrieving device subscription details related to the given UUID. * * @param uuid the UUID of the application release. - * @return List of device subscription details. + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link DeviceOperationDTO} which contains the details of device subscriptions. * @throws SubscriptionManagementException if there is an error while fetching the details. */ - List getDeviceSubscriptionsOperationsByUUID(String uuid) + List getDeviceSubscriptionsOperationsByUUID(String uuid, int offset, int limit) throws ApplicationManagementException; /** diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/SubscriptionDAO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/SubscriptionDAO.java index a9b90375db..a91d13eb06 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/SubscriptionDAO.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/SubscriptionDAO.java @@ -318,61 +318,99 @@ public interface SubscriptionDAO { void deleteScheduledSubscriptionByTenant(int tenantId) throws ApplicationManagementDAOException; /** - * This method is used to get the details of groups related to a UUID. + * This method is used to get the details of group subscriptions related to a appReleaseId. * - * @param uuid the UUID of the application release. + * @param appReleaseId the appReleaseId of the application release. * @param unsubscribe the Status of the subscription. * @param tenantId id of the current tenant. - * @return groupDetails - list of group details related to the UUID. + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link GroupSubscriptionDTO} which contains the details of group subscriptions. * @throws ApplicationManagementDAOException if connection establishment fails. */ - List getGroupsSubscriptionDetailsByUUID(String uuid, boolean unsubscribe, int tenantId) + List getGroupsSubscriptionDetailsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, int limit) throws ApplicationManagementDAOException; /** - * This method is used to get the details of user subscriptions related to a UUID. + * This method is used to get the details of user subscriptions related to a appReleaseId. * - * @param uuid the UUID of the application release. + * @param appReleaseId the appReleaseId of the application release. * @param unsubscribe the Status of the subscription. * @param tenantId id of the current tenant. - * @return userSubscriptions - list of user subscription details related to the UUID. + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link UserSubscriptionDTO} which contains the details of user subscriptions. * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - List getUserSubscriptionsByUUID(String uuid, boolean unsubscribe, int tenantId) + List getUserSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, + int offset, int limit) throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of role subscriptions related to a appReleaseId. + * + * @param appReleaseId the appReleaseId of the application release. + * @param unsubscribe the Status of the subscription. + * @param tenantId id of the current tenant. + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link RoleSubscriptionDTO} which contains the details of role subscriptions. + * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. + */ + List getRoleSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, int limit) throws ApplicationManagementDAOException; /** - * This method is used to get the details of role subscriptions related to a UUID. + * This method is used to get the details of device subscriptions related to a appReleaseId. * - * @param uuid the UUID of the application release. + * @param appReleaseId the appReleaseId of the application release. * @param unsubscribe the Status of the subscription. * @param tenantId id of the current tenant. - * @return roleSubscriptions - list of role subscription details related to the UUID. + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link DeviceSubscriptionDTO} which contains the details of device subscriptions. * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - List getRoleSubscriptionsByUUID(String uuid, boolean unsubscribe, int tenantId) + List getDeviceSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, int limit) throws ApplicationManagementDAOException; /** * This method is used to get the details of device subscriptions related to a UUID. * - * @param uuid the UUID of the application release. + * @param appReleaseId the appReleaseId of the application release. * @param tenantId id of the current tenant. - * @return deviceSubscriptions - list of device subscription details related to the UUID. + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link DeviceOperationDTO} which contains the details of device subscriptions. * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - List getDeviceSubscriptionsOperationsByUUID(String uuid, int tenantId) + List getDeviceSubscriptionsOperationsByAppReleaseID(int appReleaseId, int tenantId, int offset, int limit) throws ApplicationManagementDAOException; /** * This method is used to get the details of device subscriptions related to a UUID. * * @param appReleaseId the appReleaseId of the application release. + * @param unsubscribe the Status of the subscription. * @param tenantId id of the current tenant. - * @return deviceSubscriptions - list of device subscription details related to the UUID. + * @param deviceIds deviceIds deviceIds to retrieve data. + * @return {@link DeviceOperationDTO} which contains the details of device subscriptions. * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - List getDeviceSubscriptionsDetails(int appReleaseId, int tenantId) + List getSubscriptionDetailsByDeviceIds(int appReleaseId, boolean unsubscribe, int tenantId, List deviceIds) + throws ApplicationManagementDAOException; + + /** + * This method is used to get the details of device subscriptions related to a UUID. + * + * @param appReleaseId the appReleaseId of the application release. + * @param unsubscribe the Status of the subscription. + * @param tenantId id of the current tenant. + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link DeviceOperationDTO} which contains the details of device subscriptions. + * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. + */ + List getAllSubscriptionsDetails(int appReleaseId, boolean unsubscribe, int tenantId, int offset, int limit) throws ApplicationManagementDAOException; /** @@ -383,8 +421,7 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getAllSubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getAllSubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /** * This method is used to get the counts of all unsubscription types related to a UUID. @@ -394,8 +431,7 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getAllUnsubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getAllUnsubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /** * This method is used to get the counts of device subscriptions related to a UUID. @@ -405,8 +441,7 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getDeviceSubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getDeviceSubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /** * This method is used to get the counts of device unsubscription related to a UUID. @@ -416,8 +451,7 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getDeviceUnsubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getDeviceUnsubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /** * This method is used to get the counts of group subscriptions related to a UUID. @@ -427,8 +461,7 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getGroupSubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getGroupSubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /** * This method is used to get the counts of group unsubscription related to a UUID. @@ -438,8 +471,7 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getGroupUnsubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getGroupUnsubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /** * This method is used to get the counts of role subscriptions related to a UUID. @@ -449,8 +481,7 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getRoleSubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getRoleSubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /** * This method is used to get the counts of role unsubscription related to a UUID. @@ -460,8 +491,7 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getRoleUnsubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getRoleUnsubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /** * This method is used to get the counts of user subscriptions related to a UUID. @@ -471,8 +501,7 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getUserSubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getUserSubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /** * This method is used to get the counts of user unsubscription related to a UUID. @@ -482,6 +511,5 @@ public interface SubscriptionDAO { * @return {@link int} which contains the count of the subscription type * @throws ApplicationManagementDAOException if connection establishment or SQL execution fails. */ - int getUserUnsubscriptionCount(int appReleaseId, int tenantId) - throws ApplicationManagementDAOException; + int getUserUnsubscriptionCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; } diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java index c005100fd9..bf25c9c2b5 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/impl/subscription/GenericSubscriptionDAOImpl.java @@ -48,6 +48,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.StringJoiner; +import java.util.stream.Collectors; public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements SubscriptionDAO { private static final Log log = LogFactory.getLog(GenericSubscriptionDAOImpl.class); @@ -1641,23 +1642,29 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } @Override - public List getGroupsSubscriptionDetailsByUUID(String uuid, boolean unsubscribe, int tenantId) + public List getGroupsSubscriptionDetailsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, int limit) throws ApplicationManagementDAOException { if (log.isDebugEnabled()) { - log.debug("Request received in DAO Layer to get groups related to the given UUID."); + log.debug("Request received in DAO Layer to get groups related to the given AppReleaseID."); } try { Connection conn = this.getDBConnection(); List groupDetails = new ArrayList<>(); + + String subscriptionStatusTime = unsubscribe ? "GS.UNSUBSCRIBED_TIMESTAMP" : "GS.SUBSCRIBED_TIMESTAMP"; String sql = "SELECT GS.GROUP_NAME, GS.SUBSCRIBED_BY, GS.SUBSCRIBED_TIMESTAMP, GS.UNSUBSCRIBED, " + "GS.UNSUBSCRIBED_BY, GS.UNSUBSCRIBED_TIMESTAMP, GS.AP_APP_RELEASE_ID " + "FROM AP_GROUP_SUBSCRIPTION GS " + - "JOIN AP_APP_RELEASE AR ON GS.AP_APP_RELEASE_ID = AR.ID " + - "WHERE AR.UUID = ? AND GS.UNSUBSCRIBED = ? AND AR.TENANT_ID = ?"; + "WHERE GS.AP_APP_RELEASE_ID = ? AND GS.UNSUBSCRIBED = ? AND GS.TENANT_ID = ? " + + "ORDER BY " + subscriptionStatusTime + " DESC " + + "LIMIT ? OFFSET ?"; try (PreparedStatement ps = conn.prepareStatement(sql)) { - ps.setString(1, uuid); + ps.setInt(1, appReleaseId); ps.setBoolean(2, unsubscribe); ps.setInt(3, tenantId); + ps.setInt(4, limit); + ps.setInt(5, offset); + try (ResultSet rs = ps.executeQuery()) { GroupSubscriptionDTO groupDetail; while (rs.next()) { @@ -1687,23 +1694,28 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } @Override - public List getUserSubscriptionsByUUID(String uuid, boolean unsubscribe, int tenantId) - throws ApplicationManagementDAOException { + public List getUserSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, + int offset, int limit) throws ApplicationManagementDAOException { if (log.isDebugEnabled()) { log.debug("Request received in DAO Layer to get user subscriptions related to the given UUID."); } try { Connection conn = this.getDBConnection(); List userSubscriptions = new ArrayList<>(); + + String subscriptionStatusTime = unsubscribe ? "US.UNSUBSCRIBED_TIMESTAMP" : "US.SUBSCRIBED_TIMESTAMP"; String sql = "SELECT US.USER_NAME, US.SUBSCRIBED_BY, US.SUBSCRIBED_TIMESTAMP, US.UNSUBSCRIBED, " + - "US.UNSUBSCRIBED_BY, US.UNSUBSCRIBED_TIMESTAMP, US.AP_APP_RELEASE_ID, AR.UUID " + + "US.UNSUBSCRIBED_BY, US.UNSUBSCRIBED_TIMESTAMP, US.AP_APP_RELEASE_ID " + "FROM AP_USER_SUBSCRIPTION US " + - "JOIN AP_APP_RELEASE AR ON US.AP_APP_RELEASE_ID = AR.ID " + - "WHERE AR.UUID = ? AND US.UNSUBSCRIBED = ? AND AR.TENANT_ID = ?"; + "WHERE US.AP_APP_RELEASE_ID = ? AND US.UNSUBSCRIBED = ? AND US.TENANT_ID = ? " + + "ORDER BY " + subscriptionStatusTime + " DESC " + + "LIMIT ? OFFSET ?"; try (PreparedStatement ps = conn.prepareStatement(sql)) { - ps.setString(1, uuid); + ps.setInt(1, appReleaseId); ps.setBoolean(2, unsubscribe); ps.setInt(3, tenantId); + ps.setInt(4, limit); + ps.setInt(5, offset); try (ResultSet rs = ps.executeQuery()) { while (rs.next()) { UserSubscriptionDTO userSubscription; @@ -1733,23 +1745,28 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } @Override - public List getRoleSubscriptionsByUUID(String uuid, boolean unsubscribe, int tenantId) - throws ApplicationManagementDAOException { + public List getRoleSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, + int limit) throws ApplicationManagementDAOException { if (log.isDebugEnabled()) { - log.debug("Request received in DAO Layer to get role subscriptions related to the given UUID."); + log.debug("Request received in DAO Layer to get role subscriptions related to the given AppReleaseID."); } try { Connection conn = this.getDBConnection(); List roleSubscriptions = new ArrayList<>(); + + String subscriptionStatusTime = unsubscribe ? "ARS.UNSUBSCRIBED_TIMESTAMP" : "ARS.SUBSCRIBED_TIMESTAMP"; String sql = "SELECT ARS.ROLE_NAME, ARS.SUBSCRIBED_BY, ARS.SUBSCRIBED_TIMESTAMP, ARS.UNSUBSCRIBED, " + "ARS.UNSUBSCRIBED_BY, ARS.UNSUBSCRIBED_TIMESTAMP, ARS.AP_APP_RELEASE_ID " + "FROM AP_ROLE_SUBSCRIPTION ARS " + - "JOIN AP_APP_RELEASE AAR ON ARS.AP_APP_RELEASE_ID = AAR.ID " + - "WHERE AAR.UUID = ? AND ARS.UNSUBSCRIBED = ? AND AAR.TENANT_ID = ?"; + "WHERE ARS.AP_APP_RELEASE_ID = ? AND ARS.UNSUBSCRIBED = ? AND ARS.TENANT_ID = ? " + + "ORDER BY " + subscriptionStatusTime + " DESC " + + "LIMIT ? OFFSET ?"; try (PreparedStatement ps = conn.prepareStatement(sql)) { - ps.setString(1, uuid); + ps.setInt(1, appReleaseId); ps.setBoolean(2, unsubscribe); ps.setInt(3, tenantId); + ps.setInt(4, limit); + ps.setInt(5, offset); try (ResultSet rs = ps.executeQuery()) { RoleSubscriptionDTO roleSubscription; while (rs.next()) { @@ -1779,16 +1796,76 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } @Override - public List getDeviceSubscriptionsOperationsByUUID(String uuid, int tenantId) + public List getDeviceSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, int limit) throws ApplicationManagementDAOException { if (log.isDebugEnabled()) { - log.debug("Request received in DAO Layer to get device subscriptions related to the given UUID."); + log.debug("Request received in DAO Layer to get device subscriptions related to the given AppReleaseID."); + } + try { + Connection conn = this.getDBConnection(); + List deviceSubscriptions = new ArrayList<>(); + + String subscriptionStatusTime = unsubscribe ? "DS.UNSUBSCRIBED_TIMESTAMP" : "DS.SUBSCRIBED_TIMESTAMP"; + String sql = "SELECT DS.DM_DEVICE_ID, " + + "DS.SUBSCRIBED_BY, " + + "DS.SUBSCRIBED_TIMESTAMP, " + + "DS.STATUS, " + + "DS.UNSUBSCRIBED, " + + "DS.UNSUBSCRIBED_BY, " + + "DS.UNSUBSCRIBED_TIMESTAMP, " + + "DS.AP_APP_RELEASE_ID " + + "FROM AP_DEVICE_SUBSCRIPTION DS " + + "WHERE DS.AP_APP_RELEASE_ID = ? " + + "AND DS.UNSUBSCRIBED = ? " + + "AND DS.TENANT_ID = ? " + + "AND DS.ACTION_TRIGGERED_FROM = 'DEVICE' " + + "ORDER BY " + subscriptionStatusTime + " DESC " + + "LIMIT ? OFFSET ?"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setBoolean(2, unsubscribe); + ps.setInt(3, tenantId); + ps.setInt(4, limit); + ps.setInt(5, offset); + try (ResultSet rs = ps.executeQuery()) { + DeviceSubscriptionDTO deviceSubscription; + while (rs.next()) { + deviceSubscription = new DeviceSubscriptionDTO(); + deviceSubscription.setDeviceId(rs.getInt("DM_DEVICE_ID")); + deviceSubscription.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); + deviceSubscription.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_TIMESTAMP")); + deviceSubscription.setStatus(rs.getString("STATUS")); + deviceSubscription.setUnsubscribed(rs.getBoolean("UNSUBSCRIBED")); + deviceSubscription.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY")); + deviceSubscription.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_TIMESTAMP")); + deviceSubscription.setAppReleaseId(rs.getInt("AP_APP_RELEASE_ID")); + + deviceSubscriptions.add(deviceSubscription); + } + } + return deviceSubscriptions; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get device subscriptions for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "SQL Error occurred while getting device subscriptions for the given UUID."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public List getDeviceSubscriptionsOperationsByAppReleaseID( + int appReleaseId, int tenantId, int offset, int limit) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get device subscriptions related to the given AppReleaseID."); } try { Connection conn = this.getDBConnection(); List deviceSubscriptions = new ArrayList<>(); String sql = "SELECT " + - " aar.UUID, " + " ads.DM_DEVICE_ID, " + " aasom.OPERATION_ID, " + " ads.STATUS, " + @@ -1797,17 +1874,18 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc " ads.AP_APP_RELEASE_ID " + "FROM AP_APP_SUB_OP_MAPPING aasom " + "JOIN AP_DEVICE_SUBSCRIPTION ads ON aasom.AP_DEVICE_SUBSCRIPTION_ID = ads.ID " + - "JOIN AP_APP_RELEASE aar ON ads.AP_APP_RELEASE_ID = aar.ID " + - "WHERE aar.UUID = ? AND aar.TENANT_ID = ?"; + "WHERE ads.AP_APP_RELEASE_ID = ? AND ads.TENANT_ID = ? " + + "LIMIT ? OFFSET ?"; try (PreparedStatement ps = conn.prepareStatement(sql)) { - ps.setString(1, uuid); + ps.setInt(1, appReleaseId); ps.setInt(2, tenantId); + ps.setInt(3, limit); + ps.setInt(4, offset); try (ResultSet rs = ps.executeQuery()) { DeviceOperationDTO deviceSubscription; while (rs.next()) { deviceSubscription = new DeviceOperationDTO(); deviceSubscription.setDeviceId(rs.getInt("DM_DEVICE_ID")); - deviceSubscription.setUuid(rs.getString("UUID")); deviceSubscription.setStatus(rs.getString("STATUS")); deviceSubscription.setOperationId(rs.getInt("OPERATION_ID")); deviceSubscription.setActionTriggeredFrom(rs.getString("ACTION_TRIGGERED_FROM")); @@ -1831,12 +1909,82 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } @Override - public List getDeviceSubscriptionsDetails(int appReleaseId, int tenantId) throws - ApplicationManagementDAOException { + public List getSubscriptionDetailsByDeviceIds(int appReleaseId, boolean unsubscribe, int tenantId, List deviceIds) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting device subscriptions for the application release id " + appReleaseId + + " and device ids " + deviceIds + " from the database"); + } + try { + Connection conn = this.getDBConnection(); + String subscriptionStatusTime = unsubscribe ? "DS.UNSUBSCRIBED_TIMESTAMP" : "DS.SUBSCRIBED_TIMESTAMP"; + String sql = "SELECT " + + "DS.ID AS ID, " + + "DS.SUBSCRIBED_BY AS SUBSCRIBED_BY, " + + "DS.SUBSCRIBED_TIMESTAMP AS SUBSCRIBED_AT, " + + "DS.UNSUBSCRIBED AS IS_UNSUBSCRIBED, " + + "DS.UNSUBSCRIBED_BY AS UNSUBSCRIBED_BY, " + + "DS.UNSUBSCRIBED_TIMESTAMP AS UNSUBSCRIBED_AT, " + + "DS.ACTION_TRIGGERED_FROM AS ACTION_TRIGGERED_FROM, " + + "DS.STATUS AS STATUS, " + + "DS.DM_DEVICE_ID AS DEVICE_ID " + + "FROM AP_DEVICE_SUBSCRIPTION DS " + + "WHERE DS.AP_APP_RELEASE_ID = ? AND DS.UNSUBSCRIBED = ? AND DS.TENANT_ID = ? AND DS.DM_DEVICE_ID IN (" + + deviceIds.stream().map(id -> "?").collect(Collectors.joining(",")) + ") " + + "ORDER BY " + subscriptionStatusTime + " DESC"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, appReleaseId); + ps.setBoolean(2, unsubscribe); + ps.setInt(3, tenantId); + for (int i = 0; i < deviceIds.size(); i++) { + ps.setInt(4 + i, deviceIds.get(i)); + } + try (ResultSet rs = ps.executeQuery()) { + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved device subscriptions for application release id " + + appReleaseId + " and device ids " + deviceIds); + } + List subscriptions = new ArrayList<>(); + while (rs.next()) { + DeviceSubscriptionDTO subscription = new DeviceSubscriptionDTO(); + subscription.setId(rs.getInt("ID")); + subscription.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); + subscription.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_AT")); + subscription.setUnsubscribed(rs.getBoolean("IS_UNSUBSCRIBED")); + subscription.setUnsubscribedBy(rs.getString("UNSUBSCRIBED_BY")); + subscription.setUnsubscribedTimestamp(rs.getTimestamp("UNSUBSCRIBED_AT")); + subscription.setActionTriggeredFrom(rs.getString("ACTION_TRIGGERED_FROM")); + subscription.setStatus(rs.getString("STATUS")); + subscription.setDeviceId(rs.getInt("DEVICE_ID")); + subscriptions.add(subscription); + } + return subscriptions; + } + } catch (SQLException e) { + String msg = "Error occurred while running SQL to get device subscription data for application ID: " + appReleaseId + + " and device ids: " + deviceIds + "."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection for getting device subscriptions for " + + "application Id: " + appReleaseId + " and device ids: " + deviceIds + "."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + + } + + @Override + public List getAllSubscriptionsDetails(int appReleaseId, boolean unsubscribe, int tenantId, + int offset, int limit) throws ApplicationManagementDAOException { if (log.isDebugEnabled()) { log.debug("Getting device subscriptions for the application release id " + appReleaseId + " from the database"); } + + String subscriptionStatusTime = unsubscribe ? "DS.UNSUBSCRIBED_TIMESTAMP" : "DS.SUBSCRIBED_TIMESTAMP"; String sql = "SELECT " + "DS.ID AS ID, " + "DS.SUBSCRIBED_BY AS SUBSCRIBED_BY, " @@ -1848,13 +1996,18 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc + "DS.STATUS AS STATUS," + "DS.DM_DEVICE_ID AS DEVICE_ID " + "FROM AP_DEVICE_SUBSCRIPTION DS " - + "WHERE DS.AP_APP_RELEASE_ID = ? AND DS.TENANT_ID=?"; + + "WHERE DS.AP_APP_RELEASE_ID = ? AND DS.UNSUBSCRIBED = ? AND DS.TENANT_ID=? " + + "ORDER BY " + subscriptionStatusTime + " DESC " + + "LIMIT ? OFFSET ?"; try { Connection conn = this.getDBConnection(); try (PreparedStatement ps = conn.prepareStatement(sql)) { ps.setInt(1, appReleaseId); - ps.setInt(2, tenantId); + ps.setBoolean(2, unsubscribe); + ps.setInt(3, tenantId); + ps.setInt(4, limit); + ps.setInt(5, offset); try (ResultSet rs = ps.executeQuery()) { if (log.isDebugEnabled()) { log.debug("Successfully retrieved device subscriptions for application release id " @@ -1862,9 +2015,8 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } List deviceSubscriptions = new ArrayList<>(); - DeviceSubscriptionDTO subscription; while (rs.next()) { - subscription = new DeviceSubscriptionDTO(); + DeviceSubscriptionDTO subscription = new DeviceSubscriptionDTO(); subscription.setId(rs.getInt("ID")); subscription.setSubscribedBy(rs.getString("SUBSCRIBED_BY")); subscription.setSubscribedTimestamp(rs.getTimestamp("SUBSCRIBED_AT")); diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java index 79c257319b..401534e1d9 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/SubscriptionManagerImpl.java @@ -30,6 +30,7 @@ import io.entgra.device.mgt.core.application.mgt.common.dto.GroupSubscriptionDet import io.entgra.device.mgt.core.application.mgt.common.dto.UserSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.RoleSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceOperationDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceSubscriptionResponseDTO; import io.entgra.device.mgt.core.application.mgt.common.DeviceTypes; import io.entgra.device.mgt.core.application.mgt.common.ExecutionStatus; import io.entgra.device.mgt.core.application.mgt.common.SubAction; @@ -48,6 +49,7 @@ import io.entgra.device.mgt.core.application.mgt.core.dao.VppApplicationDAO; import io.entgra.device.mgt.core.application.mgt.core.exception.BadRequestException; import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.PaginationResult; +import io.entgra.device.mgt.core.device.mgt.core.dto.DeviceDetailsDTO; import io.entgra.device.mgt.core.device.mgt.core.dto.GroupDetailsDTO; import io.entgra.device.mgt.core.device.mgt.core.DeviceManagementConstants; import io.entgra.device.mgt.core.application.mgt.core.exception.UnexpectedServerErrorException; @@ -127,6 +129,7 @@ import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -134,6 +137,7 @@ import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; import java.util.stream.Collectors; /** @@ -1555,7 +1559,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } List deviceIdList = deviceSubscriptionDTOS.stream().map(DeviceSubscriptionDTO::getDeviceId) .collect(Collectors.toList()); - Map currentVersionsMap = subscriptionDAO.getCurrentInstalledAppVersion(applicationDTO.getId(), deviceIdList, installedVersion); + Map currentVersionsMap = + subscriptionDAO.getCurrentInstalledAppVersion(applicationDTO.getId(), deviceIdList, installedVersion); try { // Pass the device id list to device manager service method PaginationResult paginationResult = deviceManagementProviderService.getAppSubscribedDevices(request, deviceIdList); @@ -1701,8 +1706,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } @Override - public List getGroupsSubscriptionDetailsByUUID(String uuid, String subscriptionStatus) - throws ApplicationManagementException { + public List getGroupsSubscriptionDetailsByUUID(String uuid, String subscriptionStatus, int offset, + int limit) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); String groupName; @@ -1710,11 +1715,21 @@ public class SubscriptionManagerImpl implements SubscriptionManager { try { ConnectionManagerUtil.openDBConnection(); + + ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId); + if (applicationReleaseDTO == null) { + String msg = "Couldn't find an application release for application release UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + int appReleaseId = applicationReleaseDTO.getId(); + List groupDetailsWithDevices = new ArrayList<>(); - List groupDetails = subscriptionDAO.getGroupsSubscriptionDetailsByUUID(uuid, unsubscribe, tenantId); + List groupDetails = + subscriptionDAO.getGroupsSubscriptionDetailsByAppReleaseID(appReleaseId, unsubscribe, tenantId, offset, limit); if (groupDetails == null) { - throw new ApplicationManagementException("Group details not found for UUID: " + uuid); + throw new ApplicationManagementException("Group details not found for appReleaseId: " + appReleaseId); } GroupManagementProviderService groupManagementProviderService = HelperUtil.getGroupManagementProviderService(); @@ -1723,7 +1738,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager { groupName = groupDetail.getGroupName(); // Retrieve group details and device IDs for the group using the service layer - GroupDetailsDTO groupDetailWithDevices = groupManagementProviderService.getGroupDetailsWithDeviceIds(groupName); + GroupDetailsDTO groupDetailWithDevices = + groupManagementProviderService.getGroupDetailsWithDevices(groupName, offset, limit); GroupSubscriptionDetailDTO groupDetailDTO = new GroupSubscriptionDetailDTO(); groupDetailDTO.setGroupId(groupDetailWithDevices.getGroupId()); @@ -1742,6 +1758,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { List installedDevices = new ArrayList<>(); List errorDevices = new ArrayList<>(); List newDevices = new ArrayList<>(); + List subscribedDevices = new ArrayList<>(); List deviceIds = groupDetailWithDevices.getDeviceIds(); Map statusCounts = new HashMap<>(); @@ -1749,10 +1766,18 @@ public class SubscriptionManagerImpl implements SubscriptionManager { statusCounts.put("COMPLETED", 0); statusCounts.put("ERROR", 0); statusCounts.put("NEW", 0); + statusCounts.put("SUBSCRIBED", 0); + + // Get subscribed devices if unsubscribed devices are requested + List subscribedDeviceSubscriptions = new ArrayList<>(); + if (unsubscribe) { + subscribedDeviceSubscriptions = subscriptionDAO.getSubscriptionDetailsByDeviceIds( + appReleaseId, !unsubscribe, tenantId, deviceIds); + } for (Integer deviceId : deviceIds) { - List deviceSubscriptions = subscriptionDAO.getDeviceSubscriptionsDetails( - groupDetail.getAppReleaseId(), tenantId); + List deviceSubscriptions = subscriptionDAO.getSubscriptionDetailsByDeviceIds( + groupDetail.getAppReleaseId(), unsubscribe, tenantId, deviceIds); boolean isNewDevice = true; for (DeviceSubscriptionDTO subscription : deviceSubscriptions) { if (subscription.getDeviceId() == deviceId) { @@ -1760,9 +1785,14 @@ public class SubscriptionManagerImpl implements SubscriptionManager { deviceDetail.setDeviceId(subscription.getDeviceId()); deviceDetail.setStatus(subscription.getStatus()); deviceDetail.setActionType(subscription.getActionTriggeredFrom()); + deviceDetail.setDeviceOwner(groupDetailWithDevices.getDeviceOwners().get(deviceId)); + deviceDetail.setDeviceStatus(groupDetailWithDevices.getDeviceStatuses().get(deviceId)); deviceDetail.setSubId(subscription.getId()); deviceDetail.setActionTriggeredBy(subscription.getSubscribedBy()); deviceDetail.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); + deviceDetail.setUnsubscribed(subscription.isUnsubscribed()); + deviceDetail.setUnsubscribedBy(subscription.getUnsubscribedBy()); + deviceDetail.setUnsubscribedTimestamp(subscription.getUnsubscribedTimestamp()); status = subscription.getStatus(); switch (status) { @@ -1787,10 +1817,32 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } } if (isNewDevice) { - DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); - newDeviceDetail.setDeviceId(deviceId); - newDevices.add(newDeviceDetail); - statusCounts.put("NEW", statusCounts.get("NEW") + 1); + boolean isSubscribedDevice = false; + for (DeviceSubscriptionDTO subscribedDevice : subscribedDeviceSubscriptions) { + if (subscribedDevice.getDeviceId() == deviceId) { + DeviceSubscriptionData subscribedDeviceDetail = new DeviceSubscriptionData(); + subscribedDeviceDetail.setDeviceId(subscribedDevice.getDeviceId()); + subscribedDeviceDetail.setDeviceOwner(groupDetailWithDevices.getDeviceOwners().get(deviceId)); + subscribedDeviceDetail.setDeviceStatus(groupDetailWithDevices.getDeviceStatuses().get(deviceId)); + subscribedDeviceDetail.setSubId(subscribedDevice.getId()); + subscribedDeviceDetail.setActionTriggeredBy(subscribedDevice.getSubscribedBy()); + subscribedDeviceDetail.setActionTriggeredTimestamp(subscribedDevice.getSubscribedTimestamp()); + subscribedDeviceDetail.setActionType(subscribedDevice.getActionTriggeredFrom()); + subscribedDeviceDetail.setStatus(subscribedDevice.getStatus()); + subscribedDevices.add(subscribedDeviceDetail); + statusCounts.put("SUBSCRIBED", statusCounts.get("SUBSCRIBED") + 1); + isSubscribedDevice = true; + break; + } + } + if (!isSubscribedDevice) { + DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); + newDeviceDetail.setDeviceId(deviceId); + newDeviceDetail.setDeviceOwner(groupDetailWithDevices.getDeviceOwners().get(deviceId)); + newDeviceDetail.setDeviceStatus(groupDetailWithDevices.getDeviceStatuses().get(deviceId)); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } } } @@ -1801,8 +1853,14 @@ public class SubscriptionManagerImpl implements SubscriptionManager { statusPercentages.put(entry.getKey(), percentage); } - CategorizedSubscriptionResult categorizedSubscriptionResult = - new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + CategorizedSubscriptionResult categorizedSubscriptionResult; + if (subscribedDevices.isEmpty()) { + categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + } else { + categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices, subscribedDevices); + } groupDetailDTO.setDevices(categorizedSubscriptionResult); groupDetailDTO.setStatusPercentages(statusPercentages); @@ -1828,7 +1886,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } @Override - public List getUserSubscriptionsByUUID(String uuid, String subscriptionStatus) + public List getUserSubscriptionsByUUID(String uuid, String subscriptionStatus, int offset, int limit) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); @@ -1837,11 +1895,21 @@ public class SubscriptionManagerImpl implements SubscriptionManager { try { ConnectionManagerUtil.openDBConnection(); + + ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId); + if (applicationReleaseDTO == null) { + String msg = "Couldn't find an application release for application release UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + int appReleaseId = applicationReleaseDTO.getId(); + List userSubscriptionsWithDevices = new ArrayList<>(); - List userSubscriptions = subscriptionDAO.getUserSubscriptionsByUUID(uuid, unsubscribe, tenantId); + List userSubscriptions = + subscriptionDAO.getUserSubscriptionsByAppReleaseID(appReleaseId, unsubscribe, tenantId, offset, limit); if (userSubscriptions == null) { - throw new ApplicationManagementException("User details not found for UUID: " + uuid); + throw new ApplicationManagementException("User details not found for appReleaseId: " + appReleaseId); } DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); @@ -1850,7 +1918,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager { userName = userSubscription.getUserName(); // Retrieve owner details and device IDs for the user using the service layer - OwnerWithDeviceDTO ownerDetailsWithDevices = deviceManagementProviderService.getOwnersWithDeviceIds(userName); + OwnerWithDeviceDTO ownerDetailsWithDevices = + deviceManagementProviderService.getOwnersWithDeviceIds(userName); UserSubscriptionDTO userSubscriptionDTO = new UserSubscriptionDTO(); userSubscriptionDTO.setUserName(userSubscription.getUserName()); @@ -1868,6 +1937,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { List installedDevices = new ArrayList<>(); List errorDevices = new ArrayList<>(); List newDevices = new ArrayList<>(); + List subscribedDevices = new ArrayList<>(); List deviceIds = ownerDetailsWithDevices.getDeviceIds(); Map statusCounts = new HashMap<>(); @@ -1875,21 +1945,33 @@ public class SubscriptionManagerImpl implements SubscriptionManager { statusCounts.put("COMPLETED", 0); statusCounts.put("ERROR", 0); statusCounts.put("NEW", 0); + statusCounts.put("SUBSCRIBED", 0); + + List subscribedDeviceSubscriptions = new ArrayList<>(); + if (unsubscribe) { + subscribedDeviceSubscriptions = subscriptionDAO.getSubscriptionDetailsByDeviceIds( + appReleaseId, !unsubscribe, tenantId, deviceIds); + } for (Integer deviceId : deviceIds) { - List deviceSubscriptions = subscriptionDAO.getDeviceSubscriptionsDetails( - userSubscription.getAppReleaseId(), tenantId); + List deviceSubscriptions = subscriptionDAO.getSubscriptionDetailsByDeviceIds( + userSubscription.getAppReleaseId(), unsubscribe, tenantId, deviceIds); boolean isNewDevice = true; for (DeviceSubscriptionDTO subscription : deviceSubscriptions) { if (subscription.getDeviceId() == deviceId) { DeviceSubscriptionData deviceDetail = new DeviceSubscriptionData(); deviceDetail.setDeviceId(subscription.getDeviceId()); + deviceDetail.setSubId(subscription.getId()); + deviceDetail.setDeviceOwner(ownerDetailsWithDevices.getUserName()); + deviceDetail.setDeviceStatus(ownerDetailsWithDevices.getDeviceStatus()); deviceDetail.setActionType(subscription.getActionTriggeredFrom()); deviceDetail.setStatus(subscription.getStatus()); deviceDetail.setActionType(subscription.getActionTriggeredFrom()); deviceDetail.setActionTriggeredBy(subscription.getSubscribedBy()); - deviceDetail.setSubId(subscription.getId()); deviceDetail.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); + deviceDetail.setUnsubscribed(subscription.isUnsubscribed()); + deviceDetail.setUnsubscribedBy(subscription.getUnsubscribedBy()); + deviceDetail.setUnsubscribedTimestamp(subscription.getUnsubscribedTimestamp()); status = subscription.getStatus(); switch (status) { @@ -1914,10 +1996,32 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } } if (isNewDevice) { - DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); - newDeviceDetail.setDeviceId(deviceId); - newDevices.add(newDeviceDetail); - statusCounts.put("NEW", statusCounts.get("NEW") + 1); + boolean isSubscribedDevice = false; + for (DeviceSubscriptionDTO subscribedDevice : subscribedDeviceSubscriptions) { + if (subscribedDevice.getDeviceId() == deviceId) { + DeviceSubscriptionData subscribedDeviceDetail = new DeviceSubscriptionData(); + subscribedDeviceDetail.setDeviceId(subscribedDevice.getDeviceId()); + subscribedDeviceDetail.setDeviceOwner(ownerDetailsWithDevices.getUserName()); + subscribedDeviceDetail.setDeviceStatus(ownerDetailsWithDevices.getDeviceStatus()); + subscribedDeviceDetail.setSubId(subscribedDevice.getId()); + subscribedDeviceDetail.setActionTriggeredBy(subscribedDevice.getSubscribedBy()); + subscribedDeviceDetail.setActionTriggeredTimestamp(subscribedDevice.getSubscribedTimestamp()); + subscribedDeviceDetail.setActionType(subscribedDevice.getActionTriggeredFrom()); + subscribedDeviceDetail.setStatus(subscribedDevice.getStatus()); + subscribedDevices.add(subscribedDeviceDetail); + statusCounts.put("SUBSCRIBED", statusCounts.get("SUBSCRIBED") + 1); + isSubscribedDevice = true; + break; + } + } + if (!isSubscribedDevice) { + DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); + newDeviceDetail.setDeviceId(deviceId); + newDeviceDetail.setDeviceOwner(ownerDetailsWithDevices.getUserName()); + newDeviceDetail.setDeviceStatus(ownerDetailsWithDevices.getDeviceStatus()); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } } } @@ -1928,8 +2032,14 @@ public class SubscriptionManagerImpl implements SubscriptionManager { statusPercentages.put(entry.getKey(), percentage); } - CategorizedSubscriptionResult categorizedSubscriptionResult = - new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + CategorizedSubscriptionResult categorizedSubscriptionResult; + if (subscribedDevices.isEmpty()) { + categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + } else { + categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices, subscribedDevices); + } userSubscriptionDTO.setDevices(categorizedSubscriptionResult); userSubscriptionDTO.setStatusPercentages(statusPercentages); @@ -1953,7 +2063,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } @Override - public List getRoleSubscriptionsByUUID(String uuid, String subscriptionStatus) + public List getRoleSubscriptionsByUUID(String uuid, String subscriptionStatus, int offset, int limit) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); @@ -1962,11 +2072,21 @@ public class SubscriptionManagerImpl implements SubscriptionManager { try { ConnectionManagerUtil.openDBConnection(); + + ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId); + if (applicationReleaseDTO == null) { + String msg = "Couldn't find an application release for application release UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + int appReleaseId = applicationReleaseDTO.getId(); + List roleSubscriptionsWithDevices = new ArrayList<>(); - List roleSubscriptions = subscriptionDAO.getRoleSubscriptionsByUUID(uuid, unsubscribe, tenantId); + List roleSubscriptions = + subscriptionDAO.getRoleSubscriptionsByAppReleaseID(appReleaseId, unsubscribe, tenantId, offset, limit); if (roleSubscriptions == null) { - throw new ApplicationManagementException("Role details not found for UUID: " + uuid); + throw new ApplicationManagementException("Role details not found for appReleaseId: " + appReleaseId); } DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); @@ -1987,12 +2107,14 @@ public class SubscriptionManagerImpl implements SubscriptionManager { List installedDevices = new ArrayList<>(); List errorDevices = new ArrayList<>(); List newDevices = new ArrayList<>(); + List subscribedDevices = new ArrayList<>(); Map statusCounts = new HashMap<>(); statusCounts.put("PENDING", 0); statusCounts.put("COMPLETED", 0); statusCounts.put("ERROR", 0); statusCounts.put("NEW", 0); + statusCounts.put("SUBSCRIBED", 0); List users = this.getUsersForRole(roleName); @@ -2006,10 +2128,17 @@ public class SubscriptionManagerImpl implements SubscriptionManager { List deviceIds = ownerDetailsWithDevices.getDeviceIds(); for (Integer deviceId : deviceIds) { + + List subscribedDeviceSubscriptions = new ArrayList<>(); + if (unsubscribe) { + subscribedDeviceSubscriptions = subscriptionDAO.getSubscriptionDetailsByDeviceIds( + appReleaseId, !unsubscribe, tenantId, deviceIds); + } + List deviceSubscriptions; try { - deviceSubscriptions = subscriptionDAO.getDeviceSubscriptionsDetails( - roleSubscription.getAppReleaseId(), tenantId); + deviceSubscriptions = subscriptionDAO.getSubscriptionDetailsByDeviceIds( + roleSubscription.getAppReleaseId(), unsubscribe, tenantId, deviceIds); } catch (ApplicationManagementDAOException e) { throw new ApplicationManagementException("Error retrieving device subscriptions", e); } @@ -2019,12 +2148,17 @@ public class SubscriptionManagerImpl implements SubscriptionManager { if (deviceSubscription.getDeviceId() == deviceId) { DeviceSubscriptionData deviceDetail = new DeviceSubscriptionData(); deviceDetail.setDeviceId(deviceSubscription.getDeviceId()); + deviceDetail.setDeviceOwner(ownerDetailsWithDevices.getUserName()); + deviceDetail.setDeviceStatus(ownerDetailsWithDevices.getDeviceStatus()); deviceDetail.setActionType(deviceSubscription.getActionTriggeredFrom()); deviceDetail.setStatus(deviceSubscription.getStatus()); deviceDetail.setActionType(deviceSubscription.getActionTriggeredFrom()); deviceDetail.setActionTriggeredBy(deviceSubscription.getSubscribedBy()); deviceDetail.setSubId(deviceSubscription.getId()); deviceDetail.setActionTriggeredTimestamp(deviceSubscription.getSubscribedTimestamp()); + deviceDetail.setUnsubscribed(deviceSubscription.isUnsubscribed()); + deviceDetail.setUnsubscribedBy(deviceSubscription.getUnsubscribedBy()); + deviceDetail.setUnsubscribedTimestamp(deviceSubscription.getUnsubscribedTimestamp()); status = deviceSubscription.getStatus(); switch (status) { @@ -2049,23 +2183,52 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } } if (isNewDevice) { - DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); - newDeviceDetail.setDeviceId(deviceId); - newDevices.add(newDeviceDetail); - statusCounts.put("NEW", statusCounts.get("NEW") + 1); + boolean isSubscribedDevice = false; + for (DeviceSubscriptionDTO subscribedDevice : subscribedDeviceSubscriptions) { + if (subscribedDevice.getDeviceId() == deviceId) { + DeviceSubscriptionData subscribedDeviceDetail = new DeviceSubscriptionData(); + subscribedDeviceDetail.setDeviceId(subscribedDevice.getDeviceId()); + subscribedDeviceDetail.setDeviceOwner(ownerDetailsWithDevices.getUserName()); + subscribedDeviceDetail.setDeviceStatus(ownerDetailsWithDevices.getDeviceStatus()); + subscribedDeviceDetail.setSubId(subscribedDevice.getId()); + subscribedDeviceDetail.setActionTriggeredBy(subscribedDevice.getSubscribedBy()); + subscribedDeviceDetail.setActionTriggeredTimestamp(subscribedDevice.getSubscribedTimestamp()); + subscribedDeviceDetail.setActionType(subscribedDevice.getActionTriggeredFrom()); + subscribedDeviceDetail.setStatus(subscribedDevice.getStatus()); + subscribedDevices.add(subscribedDeviceDetail); + statusCounts.put("SUBSCRIBED", statusCounts.get("SUBSCRIBED") + 1); + isSubscribedDevice = true; + break; + } + } + if (!isSubscribedDevice) { + DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); + newDeviceDetail.setDeviceId(deviceId); + newDeviceDetail.setDeviceOwner(ownerDetailsWithDevices.getUserName()); + newDeviceDetail.setDeviceStatus(ownerDetailsWithDevices.getDeviceStatus()); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } } } } - int totalDevices = pendingDevices.size() + installedDevices.size() + errorDevices.size() + newDevices.size(); + int totalDevices = + pendingDevices.size() + installedDevices.size() + errorDevices.size() + newDevices.size() + subscribedDevices.size(); Map statusPercentages = new HashMap<>(); for (Map.Entry entry : statusCounts.entrySet()) { double percentage = totalDevices == 0 ? 0.0 : ((double) entry.getValue() / totalDevices) * 100; statusPercentages.put(entry.getKey(), percentage); } - CategorizedSubscriptionResult categorizedSubscriptionResult = - new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + CategorizedSubscriptionResult categorizedSubscriptionResult; + if (subscribedDevices.isEmpty()) { + categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + } else { + categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices, subscribedDevices); + } roleSubscriptionDTO.setDevices(categorizedSubscriptionResult); roleSubscriptionDTO.setStatusPercentages(statusPercentages); roleSubscriptionDTO.setDeviceCount(totalDevices); @@ -2101,15 +2264,327 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } @Override - public List getDeviceSubscriptionsOperationsByUUID(String uuid) throws ApplicationManagementException { + public DeviceSubscriptionResponseDTO getDeviceSubscriptionsDetailsByUUID(String uuid, String subscriptionStatus, int offset, + int limit) throws ApplicationManagementException { + + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); + + try { + ConnectionManagerUtil.openDBConnection(); + + ApplicationReleaseDTO applicationReleaseDTO = applicationReleaseDAO.getReleaseByUUID(uuid, tenantId); + if (applicationReleaseDTO == null) { + String msg = "Couldn't find an application release for application release UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + int appReleaseId = applicationReleaseDTO.getId(); + + DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); + List deviceSubscriptions = + subscriptionDAO.getDeviceSubscriptionsByAppReleaseID(appReleaseId, unsubscribe, tenantId, offset, limit); + + // empty response for no device subscriptions + if (deviceSubscriptions.isEmpty()) { + return new DeviceSubscriptionResponseDTO(0, Collections.emptyMap(), + new CategorizedSubscriptionResult(Collections.emptyList(), + Collections.emptyList(), Collections.emptyList(), Collections.emptyList())); + } + + List allDevices = + deviceManagementProviderService.getDevicesByTenantId(tenantId); + + List deviceIds = allDevices.stream() + .map(DeviceDetailsDTO::getDeviceId) + .collect(Collectors.toList()); + + Map statusCounts = new HashMap<>(); + statusCounts.put("PENDING", 0); + statusCounts.put("COMPLETED", 0); + statusCounts.put("ERROR", 0); + statusCounts.put("NEW", 0); + statusCounts.put("SUBSCRIBED", 0); + + List installedDevices = new ArrayList<>(); + List pendingDevices = new ArrayList<>(); + List errorDevices = new ArrayList<>(); + List newDevices = new ArrayList<>(); + List subscribedDevices = new ArrayList<>(); + + Map deviceSubscriptionMap = deviceSubscriptions.stream() + .collect(Collectors.toMap(DeviceSubscriptionDTO::getDeviceId, Function.identity())); + Map allDevicesMap = allDevices.stream() + .collect(Collectors.toMap(DeviceDetailsDTO::getDeviceId, Function.identity())); + + List allSubscriptionsForUnSubscribed = + subscriptionDAO.getSubscriptionDetailsByDeviceIds(appReleaseId, !unsubscribe, tenantId, deviceIds); + List allSubscriptionsForSubscribed = + subscriptionDAO.getSubscriptionDetailsByDeviceIds(appReleaseId, unsubscribe, tenantId, deviceIds); + Map allSubscriptionForUnSubscribedMap = allSubscriptionsForUnSubscribed.stream() + .collect(Collectors.toMap(DeviceSubscriptionDTO::getDeviceId, Function.identity())); + Map allSubscriptionForSubscribedMap = allSubscriptionsForSubscribed.stream() + .collect(Collectors.toMap(DeviceSubscriptionDTO::getDeviceId, Function.identity())); + + for (DeviceDetailsDTO device : allDevices) { + Integer deviceId = device.getDeviceId(); + OwnerWithDeviceDTO ownerWithDevice = + deviceManagementProviderService.getOwnerWithDeviceByDeviceId(deviceId); + if (ownerWithDevice == null) { + continue; + } + + if (deviceSubscriptionMap.containsKey(deviceId)) { + DeviceSubscriptionDTO subscription = deviceSubscriptionMap.get(deviceId); + DeviceSubscriptionData deviceDetail = new DeviceSubscriptionData(); + deviceDetail.setDeviceId(subscription.getDeviceId()); + deviceDetail.setSubId(subscription.getId()); + deviceDetail.setDeviceOwner(ownerWithDevice.getUserName()); + deviceDetail.setDeviceStatus(ownerWithDevice.getDeviceStatus()); + deviceDetail.setActionType(subscription.getActionTriggeredFrom()); + deviceDetail.setStatus(subscription.getStatus()); + deviceDetail.setActionTriggeredBy(subscription.getSubscribedBy()); + deviceDetail.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); + deviceDetail.setUnsubscribed(subscription.isUnsubscribed()); + deviceDetail.setUnsubscribedBy(subscription.getUnsubscribedBy()); + deviceDetail.setUnsubscribedTimestamp(subscription.getUnsubscribedTimestamp()); + + String status = subscription.getStatus(); + switch (status) { + case "COMPLETED": + installedDevices.add(deviceDetail); + statusCounts.put("COMPLETED", statusCounts.get("COMPLETED") + 1); + break; + case "ERROR": + case "INVALID": + case "UNAUTHORIZED": + errorDevices.add(deviceDetail); + statusCounts.put("ERROR", statusCounts.get("ERROR") + 1); + break; + case "IN_PROGRESS": + case "PENDING": + case "REPEATED": + pendingDevices.add(deviceDetail); + statusCounts.put("PENDING", statusCounts.get("PENDING") + 1); + break; + } + } else if (unsubscribe && allSubscriptionForUnSubscribedMap.containsKey(deviceId) && !deviceSubscriptionMap.containsKey(deviceId)) { + // Check if the device subscription has unsubscribed status set to false + DeviceSubscriptionDTO allSubscription = allSubscriptionForUnSubscribedMap.get(deviceId); + if (!allSubscription.isUnsubscribed()) { + DeviceSubscriptionData subscribedDeviceDetail = new DeviceSubscriptionData(); + subscribedDeviceDetail.setDeviceId(allSubscription.getDeviceId()); + subscribedDeviceDetail.setDeviceOwner(ownerWithDevice.getUserName()); + subscribedDeviceDetail.setDeviceStatus(ownerWithDevice.getDeviceStatus()); + subscribedDeviceDetail.setSubId(allSubscription.getId()); + subscribedDeviceDetail.setActionTriggeredBy(allSubscription.getSubscribedBy()); + subscribedDeviceDetail.setActionTriggeredTimestamp(allSubscription.getSubscribedTimestamp()); + subscribedDeviceDetail.setActionType(allSubscription.getActionTriggeredFrom()); + subscribedDeviceDetail.setStatus(allSubscription.getStatus()); + subscribedDevices.add(subscribedDeviceDetail); + statusCounts.put("SUBSCRIBED", statusCounts.get("SUBSCRIBED") + 1); + } + } else if (unsubscribe && !allSubscriptionForUnSubscribedMap.containsKey(deviceId) && !deviceSubscriptionMap.containsKey(deviceId) + && (allDevicesMap.containsKey(deviceId))) { + DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); + newDeviceDetail.setDeviceId(deviceId); + newDeviceDetail.setDeviceOwner(ownerWithDevice.getUserName()); + newDeviceDetail.setDeviceStatus(ownerWithDevice.getDeviceStatus()); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } else if (!unsubscribe && !allSubscriptionForSubscribedMap.containsKey(deviceId) && !deviceSubscriptionMap.containsKey(deviceId) + && (allDevicesMap.containsKey(deviceId))) { + DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); + newDeviceDetail.setDeviceId(deviceId); + newDeviceDetail.setDeviceOwner(ownerWithDevice.getUserName()); + newDeviceDetail.setDeviceStatus(ownerWithDevice.getDeviceStatus()); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } + } + + int totalDevices = allDevices.size(); + Map statusPercentages = new HashMap<>(); + for (Map.Entry entry : statusCounts.entrySet()) { + double percentage = ((double) entry.getValue() / totalDevices) * 100; + statusPercentages.put(entry.getKey(), percentage); + } + + CategorizedSubscriptionResult categorizedSubscriptionResult; + if (subscribedDevices.isEmpty()) { + categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + } else { + categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices, subscribedDevices); + } + DeviceSubscriptionResponseDTO deviceSubscriptionResponse = + new DeviceSubscriptionResponseDTO(totalDevices, statusPercentages, categorizedSubscriptionResult); + + return deviceSubscriptionResponse; + + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while getting device subscriptions for the application release UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "DB Connection error occurred while getting device subscriptions for UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DeviceManagementDAOException e) { + throw new RuntimeException(e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public DeviceSubscriptionResponseDTO getAllSubscriptionDetailsByUUID(String uuid, String subscriptionStatus, int offset, int limit) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); + + try { + ConnectionManagerUtil.openDBConnection(); + + ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId); + if (applicationReleaseDTO == null) { + String msg = "Couldn't find an application release for application release UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + int appReleaseId = applicationReleaseDTO.getId(); + + List allSubscriptions = + subscriptionDAO.getAllSubscriptionsDetails(appReleaseId, unsubscribe, tenantId, offset, limit); + + // empty response for no subscriptions + if (allSubscriptions.isEmpty()) { + return new DeviceSubscriptionResponseDTO(0, Collections.emptyMap(), + new CategorizedSubscriptionResult(Collections.emptyList(), + Collections.emptyList(), Collections.emptyList(), Collections.emptyList())); + } + + DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); + + Map allSubscriptionMap = allSubscriptions.stream() + .collect(Collectors.toMap(DeviceSubscriptionDTO::getDeviceId, Function.identity())); + + List pendingDevices = new ArrayList<>(); + List installedDevices = new ArrayList<>(); + List errorDevices = new ArrayList<>(); + List newDevices = new ArrayList<>(); + + Map statusCounts = new HashMap<>(); + statusCounts.put("PENDING", 0); + statusCounts.put("COMPLETED", 0); + statusCounts.put("ERROR", 0); + statusCounts.put("NEW", 0); + + List allDevices = + deviceManagementProviderService.getDevicesByTenantId(tenantId); + + for (DeviceDetailsDTO device : allDevices) { + Integer deviceId = device.getDeviceId(); + OwnerWithDeviceDTO ownerWithDevice = + deviceManagementProviderService.getOwnerWithDeviceByDeviceId(deviceId); + if (ownerWithDevice == null) { + continue; + } + + if (allSubscriptionMap.containsKey(deviceId)) { + DeviceSubscriptionDTO subscription = allSubscriptionMap.get(deviceId); + DeviceSubscriptionData deviceDetail = new DeviceSubscriptionData(); + deviceDetail.setDeviceId(subscription.getDeviceId()); + deviceDetail.setSubId(subscription.getId()); + deviceDetail.setDeviceOwner(ownerWithDevice.getUserName()); + deviceDetail.setDeviceStatus(ownerWithDevice.getDeviceStatus()); + deviceDetail.setActionType(subscription.getActionTriggeredFrom()); + deviceDetail.setStatus(subscription.getStatus()); + deviceDetail.setActionTriggeredBy(subscription.getSubscribedBy()); + deviceDetail.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); + deviceDetail.setUnsubscribed(subscription.isUnsubscribed()); + deviceDetail.setUnsubscribedBy(subscription.getUnsubscribedBy()); + deviceDetail.setUnsubscribedTimestamp(subscription.getUnsubscribedTimestamp()); + + String status = subscription.getStatus(); + switch (status) { + case "COMPLETED": + installedDevices.add(deviceDetail); + statusCounts.put("COMPLETED", statusCounts.get("COMPLETED") + 1); + break; + case "ERROR": + case "INVALID": + case "UNAUTHORIZED": + errorDevices.add(deviceDetail); + statusCounts.put("ERROR", statusCounts.get("ERROR") + 1); + break; + case "IN_PROGRESS": + case "PENDING": + case "REPEATED": + pendingDevices.add(deviceDetail); + statusCounts.put("PENDING", statusCounts.get("PENDING") + 1); + break; + } + } else { + DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); + newDeviceDetail.setDeviceId(deviceId); + newDeviceDetail.setDeviceOwner(ownerWithDevice.getUserName()); + newDeviceDetail.setDeviceStatus(ownerWithDevice.getDeviceStatus()); + newDevices.add(newDeviceDetail); + statusCounts.put("NEW", statusCounts.get("NEW") + 1); + } + } + + int totalDevices = allDevices.size(); + Map statusPercentages = new HashMap<>(); + for (Map.Entry entry : statusCounts.entrySet()) { + double percentage = ((double) entry.getValue() / totalDevices) * 100; + statusPercentages.put(entry.getKey(), percentage); + } + + CategorizedSubscriptionResult categorizedSubscriptionResult = + new CategorizedSubscriptionResult(installedDevices, pendingDevices, errorDevices, newDevices); + DeviceSubscriptionResponseDTO result = + new DeviceSubscriptionResponseDTO(totalDevices, statusPercentages, categorizedSubscriptionResult); + + return result; + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while getting user subscriptions for the application release UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "DB Connection error occurred while getting user subscriptions for UUID: " + uuid; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (DeviceManagementDAOException e) { + throw new RuntimeException(e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public List getDeviceSubscriptionsOperationsByUUID(String uuid, int offset, int limit) + throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); if (uuid == null || uuid.isEmpty()) { throw new IllegalArgumentException("UUID cannot be null or empty."); } try { ConnectionManagerUtil.openDBConnection(); + + ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId); + if (applicationReleaseDTO == null) { + String msg = "Couldn't find an application release for application release UUID: " + uuid; + log.error(msg); + throw new NotFoundException(msg); + } + int appReleaseId = applicationReleaseDTO.getId(); + DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); - List deviceSubscriptions = subscriptionDAO.getDeviceSubscriptionsOperationsByUUID(uuid, tenantId); + List deviceSubscriptions = + subscriptionDAO.getDeviceSubscriptionsOperationsByAppReleaseID(appReleaseId, tenantId, offset, limit); for (DeviceOperationDTO deviceSubscription : deviceSubscriptions) { Integer operationId = deviceSubscription.getOperationId(); if (operationId != null) { diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/EnrollmentDAO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/EnrollmentDAO.java index 5b2b35a29e..93c456f929 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/EnrollmentDAO.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/EnrollmentDAO.java @@ -21,6 +21,7 @@ import io.entgra.device.mgt.core.device.mgt.common.Device; import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier; import io.entgra.device.mgt.core.device.mgt.common.EnrolmentInfo; import io.entgra.device.mgt.core.device.mgt.common.EnrolmentInfo.Status; +import io.entgra.device.mgt.core.device.mgt.core.dto.DeviceDetailsDTO; import io.entgra.device.mgt.core.device.mgt.core.dto.OwnerWithDeviceDTO; import java.sql.Timestamp; @@ -99,10 +100,30 @@ public interface EnrollmentDAO { /** * Retrieves owners and the list of device IDs related to an owner. * - * @param owner the owner whose device IDs need to be retrieved + * @param owner the owner whose device IDs need to be retrieved * @param tenantId the ID of the tenant - * @return a map containing owner details, device IDs, and device count + * @return {@link OwnerWithDeviceDTO} which contains a list of devices related to a user * @throws DeviceManagementDAOException if an error occurs while fetching the data */ - OwnerWithDeviceDTO getOwnersWithDeviceIds(String owner, int tenantId) throws DeviceManagementDAOException; + OwnerWithDeviceDTO getOwnersWithDevices(String owner, int tenantId) throws DeviceManagementDAOException; + + /** + * Retrieves a list of device IDs with owners and device status. + * + * @param deviceId the deviceId of the device which user need to be retrieved + * @param tenantId the ID of the tenant + * @return {@link OwnerWithDeviceDTO} which contains a list of devices + * @throws DeviceManagementDAOException if an error occurs while fetching the data + */ + OwnerWithDeviceDTO getOwnerWithDeviceByDeviceId(int deviceId, int tenantId) + throws DeviceManagementDAOException; + + /** + * Retrieves owners and the list of device IDs with device status. + * + * @param tenantId the ID of the tenant + * @return {@link OwnerWithDeviceDTO} which contains a list of devices related to a user + * @throws DeviceManagementDAOException if an error occurs while fetching the data + */ + List getDevicesByTenantId(int tenantId) throws DeviceManagementDAOException; } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/GroupDAO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/GroupDAO.java index 34dc3213df..5071f7a400 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/GroupDAO.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/GroupDAO.java @@ -474,9 +474,12 @@ public interface GroupDAO { * * @param groupName Group name * @param tenantId Tenant ID - * @return A map containing group details and a list of device IDs + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link GroupDetailsDTO} which containing group details and a list of device IDs * @throws GroupManagementDAOException if an error occurs while retrieving the group details and devices */ - GroupDetailsDTO getGroupDetailsWithDeviceIds(String groupName, int tenantId) throws GroupManagementDAOException; + GroupDetailsDTO getGroupDetailsWithDevices(String groupName, int tenantId, int offset, int limit) + throws GroupManagementDAOException; } \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractEnrollmentDAOImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractEnrollmentDAOImpl.java index 4bc6627b3f..7f43707259 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractEnrollmentDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractEnrollmentDAOImpl.java @@ -27,6 +27,7 @@ import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.core.dao.EnrollmentDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.util.DeviceManagementDAOUtil; import io.entgra.device.mgt.core.device.mgt.core.dto.OwnerWithDeviceDTO; +import io.entgra.device.mgt.core.device.mgt.core.dto.DeviceDetailsDTO; import java.sql.Connection; import java.sql.PreparedStatement; @@ -559,13 +560,16 @@ public abstract class AbstractEnrollmentDAOImpl implements EnrollmentDAO { } @Override - public OwnerWithDeviceDTO getOwnersWithDeviceIds(String owner, int tenantId) throws DeviceManagementDAOException { + public OwnerWithDeviceDTO getOwnersWithDevices(String owner, int tenantId) + throws DeviceManagementDAOException { OwnerWithDeviceDTO ownerDetails = new OwnerWithDeviceDTO(); List deviceIds = new ArrayList<>(); int deviceCount = 0; - String sql = "SELECT DEVICE_ID, OWNER FROM DM_ENROLMENT WHERE OWNER = ? AND TENANT_ID = ?"; + String sql = "SELECT DEVICE_ID, OWNER, STATUS AS DEVICE_STATUS " + + "FROM DM_ENROLMENT " + + "WHERE OWNER = ? AND TENANT_ID = ?"; try (Connection conn = this.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { @@ -586,8 +590,69 @@ public abstract class AbstractEnrollmentDAOImpl implements EnrollmentDAO { } ownerDetails.setDeviceIds(deviceIds); + ownerDetails.setDeviceStatus("DEVICE_STATUS"); ownerDetails.setDeviceCount(deviceCount); return ownerDetails; } + @Override + public OwnerWithDeviceDTO getOwnerWithDeviceByDeviceId(int deviceId, int tenantId) + throws DeviceManagementDAOException { + OwnerWithDeviceDTO deviceOwnerWithStatus = new OwnerWithDeviceDTO(); + + String sql = "SELECT DEVICE_ID, OWNER, STATUS AS DEVICE_STATUS " + + "FROM DM_ENROLMENT " + + "WHERE DEVICE_ID = ? AND TENANT_ID = ?"; + + try (Connection conn = this.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, deviceId); + stmt.setInt(2, tenantId); + + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + deviceOwnerWithStatus.setUserName(rs.getString("OWNER")); + deviceOwnerWithStatus.setDeviceStatus(rs.getString("DEVICE_STATUS")); + List deviceIds = new ArrayList<>(); + deviceIds.add(rs.getInt("DEVICE_ID")); + deviceOwnerWithStatus.setDeviceIds(deviceIds); + } + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving owner and status for device ID: " + + deviceId, e); + } + + return deviceOwnerWithStatus; + } + + @Override + public List getDevicesByTenantId(int tenantId) + throws DeviceManagementDAOException { + List devices = new ArrayList<>(); + String sql = "SELECT DEVICE_ID, OWNER, STATUS " + + "FROM DM_ENROLMENT " + + "WHERE TENANT_ID = ?"; + + try (Connection conn = this.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + + stmt.setInt(1, tenantId); + + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + DeviceDetailsDTO device = new DeviceDetailsDTO(); + device.setDeviceId(rs.getInt("DEVICE_ID")); + device.setOwner(rs.getString("OWNER")); + device.setStatus(rs.getString("STATUS")); + devices.add(device); + } + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving devices for tenant ID: " + + tenantId, e); + } + + return devices; + } } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java index 476b447f1a..858df67b3c 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java @@ -1440,23 +1440,31 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { } @Override - public GroupDetailsDTO getGroupDetailsWithDeviceIds(String groupName, int tenantId) throws GroupManagementDAOException { + public GroupDetailsDTO getGroupDetailsWithDevices(String groupName, int tenantId, int offset, int limit) + throws GroupManagementDAOException { if (log.isDebugEnabled()) { log.debug("Request received in DAO Layer to get group details and device IDs for group: " + groupName); } GroupDetailsDTO groupDetails = new GroupDetailsDTO(); List deviceIds = new ArrayList<>(); + Map deviceOwners = new HashMap<>(); + Map deviceStatuses = new HashMap<>(); - String sql = "SELECT g.ID AS GROUP_ID, g.GROUP_NAME, g.OWNER, dgm.DEVICE_ID " - + "FROM DM_GROUP g " - + "JOIN DM_DEVICE_GROUP_MAP dgm ON g.ID = dgm.GROUP_ID " - + "WHERE g.GROUP_NAME = ? AND g.TENANT_ID = ?"; + String sql = + "SELECT g.ID AS GROUP_ID, g.GROUP_NAME, g.OWNER, e.OWNER AS DEVICE_OWNER, e.STATUS AS DEVICE_STATUS, dgm.DEVICE_ID " + + "FROM DM_GROUP g " + + "JOIN DM_DEVICE_GROUP_MAP dgm ON g.ID = dgm.GROUP_ID " + + "JOIN DM_ENROLMENT e ON dgm.DEVICE_ID = e.DEVICE_ID " + + "WHERE g.GROUP_NAME = ? AND g.TENANT_ID = ? " + + "LIMIT ? OFFSET ?"; try (Connection conn = GroupManagementDAOFactory.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setString(1, groupName); stmt.setInt(2, tenantId); + stmt.setInt(3, limit); + stmt.setInt(4, offset); try (ResultSet rs = stmt.executeQuery()) { while (rs.next()) { @@ -1465,7 +1473,10 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { groupDetails.setGroupName(rs.getString("GROUP_NAME")); groupDetails.setGroupOwner(rs.getString("OWNER")); } - deviceIds.add(rs.getInt("DEVICE_ID")); + int deviceId = rs.getInt("DEVICE_ID"); + deviceIds.add(deviceId); + deviceOwners.put(deviceId, rs.getString("DEVICE_OWNER")); + deviceStatuses.put(deviceId, rs.getString("DEVICE_STATUS")); } } } catch (SQLException e) { @@ -1475,6 +1486,8 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { groupDetails.setDeviceIds(deviceIds); groupDetails.setDeviceCount(deviceIds.size()); + groupDetails.setDeviceOwners(deviceOwners); + groupDetails.setDeviceStatuses(deviceStatuses); return groupDetails; } } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/DeviceDetailsDTO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/DeviceDetailsDTO.java new file mode 100644 index 0000000000..2cc5838571 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/DeviceDetailsDTO.java @@ -0,0 +1,31 @@ +package io.entgra.device.mgt.core.device.mgt.core.dto; + +public class DeviceDetailsDTO { + private int deviceId; + private String owner; + private String status; + + public int getDeviceId() { + return deviceId; + } + + public void setDeviceId(int deviceId) { + this.deviceId = deviceId; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } +} diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/GroupDetailsDTO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/GroupDetailsDTO.java index 333999aeeb..4882bcbd3a 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/GroupDetailsDTO.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/GroupDetailsDTO.java @@ -19,6 +19,7 @@ package io.entgra.device.mgt.core.device.mgt.core.dto; import java.util.List; +import java.util.Map; public class GroupDetailsDTO { private int groupId; @@ -26,6 +27,10 @@ public class GroupDetailsDTO { private String groupOwner; private List deviceIds; private int deviceCount; + private String deviceOwner; + private String deviceStatus; + private Map deviceOwners; + private Map deviceStatuses; public int getGroupId() { return groupId; @@ -67,4 +72,35 @@ public class GroupDetailsDTO { this.deviceCount = deviceCount; } + public String getDeviceOwner() { + return deviceOwner; + } + + public void setDeviceOwner(String deviceOwner) { + this.deviceOwner = deviceOwner; + } + + public String getDeviceStatus() { + return deviceStatus; + } + + public void setDeviceStatus(String deviceStatus) { + this.deviceStatus = deviceStatus; + } + + public Map getDeviceOwners() { + return deviceOwners; + } + + public void setDeviceOwners(Map deviceOwners) { + this.deviceOwners = deviceOwners; + } + + public Map getDeviceStatuses() { + return deviceStatuses; + } + + public void setDeviceStatuses(Map deviceStatuses) { + this.deviceStatuses = deviceStatuses; + } } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OwnerWithDeviceDTO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OwnerWithDeviceDTO.java index cd3e26bfbc..5445069e8b 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OwnerWithDeviceDTO.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OwnerWithDeviceDTO.java @@ -25,6 +25,7 @@ public class OwnerWithDeviceDTO { private String userName; private List deviceIds; private int deviceCount; + private String deviceStatus; public String getUserName() { return userName; @@ -49,4 +50,12 @@ public class OwnerWithDeviceDTO { public void setDeviceCount(int deviceCount) { this.deviceCount = deviceCount; } + + public String getDeviceStatus() { + return deviceStatus; + } + + public void setDeviceStatus(String deviceStatus) { + this.deviceStatus = deviceStatus; + } } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/OperationDAO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/OperationDAO.java index 5171b03b95..c874283a76 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/OperationDAO.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/OperationDAO.java @@ -127,5 +127,14 @@ public interface OperationDAO { int getDeviceActivitiesCount(ActivityPaginationRequest activityPaginationRequest) throws OperationManagementDAOException; - OperationDTO getOperationDetailsById(int operationId, int tenantId) throws OperationManagementDAOException; + /** + * This method is used to get the details of device subscriptions related to a UUID. + * + * @param operationId the operationId of the operation to be retrieved. + * @param tenantId id of the current tenant. + * @return {@link OperationDTO} which contains the details of device operations. + * @throws OperationManagementDAOException if connection establishment or SQL execution fails. + */ + OperationDTO getOperationDetailsById(int operationId, int tenantId) + throws OperationManagementDAOException; } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java index 15751c3d89..b220cb8b77 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java @@ -2779,7 +2779,8 @@ public class GenericOperationDAOImpl implements OperationDAO { } @Override - public OperationDTO getOperationDetailsById(int operationId, int tenantId) throws OperationManagementDAOException { + public OperationDTO getOperationDetailsById(int operationId, int tenantId) + throws OperationManagementDAOException { OperationDTO operationDetails = new OperationDTO(); String sql = "SELECT ID, OPERATION_CODE, OPERATION_DETAILS, OPERATION_PROPERTIES " + diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderService.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderService.java index 8e112addd3..f7b72f0275 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderService.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderService.java @@ -19,6 +19,7 @@ package io.entgra.device.mgt.core.device.mgt.core.service; import io.entgra.device.mgt.core.device.mgt.common.app.mgt.Application; +import io.entgra.device.mgt.core.device.mgt.core.dto.DeviceDetailsDTO; import io.entgra.device.mgt.core.device.mgt.core.dto.OperationDTO; import io.entgra.device.mgt.core.device.mgt.core.dto.OwnerWithDeviceDTO; import org.apache.commons.collections.map.SingletonMap; @@ -1080,16 +1081,33 @@ public interface DeviceManagementProviderService { * Get owner details and device IDs for a given owner and tenant. * * @param owner the name of the owner. - * @return a map containing owner details (Owner, DeviceIds, DeviceCount). + * @return {@link OwnerWithDeviceDTO} which contains a list of devices related to a user. * @throws DeviceManagementException if an error occurs while fetching owner details. */ OwnerWithDeviceDTO getOwnersWithDeviceIds(String owner) throws DeviceManagementDAOException; + /** + * Get owner details and device IDs for a given owner and tenant. + * + * @param deviceId the deviceId of the device. + * @return {@link OwnerWithDeviceDTO} which contains a list of devices related to a user. + * @throws DeviceManagementException if an error occurs while fetching owner details. + */ + OwnerWithDeviceDTO getOwnerWithDeviceByDeviceId(int deviceId) throws DeviceManagementDAOException; + + /** + * Get owner details and device IDs for a given owner and tenant. + * @param tenantId the tenant id which devices need to be retried + * @return {@link DeviceDetailsDTO} which contains devices details. + * @throws DeviceManagementException if an error occurs while fetching owner details. + */ + List getDevicesByTenantId(int tenantId) throws DeviceManagementDAOException; + /** * Get operation details by operation code. * * @param operationId the id of the operation. - * @return Map containing operation ID, operation code, operation details, and operation properties. + * @return {@link OperationDTO} which contains operation details. * @throws OperationManagementException if an error occurs while fetching the operation details. */ OperationDTO getOperationDetailsById(int operationId) throws OperationManagementException; diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index 3df333cbf2..31be10ed8a 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/DeviceManagementProviderServiceImpl.java @@ -22,6 +22,7 @@ import com.google.common.reflect.TypeToken; import com.google.gson.Gson; import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.DeviceStatusManagementService; import io.entgra.device.mgt.core.device.mgt.core.dao.TenantDAO; +import io.entgra.device.mgt.core.device.mgt.core.dto.DeviceDetailsDTO; import io.entgra.device.mgt.core.device.mgt.core.dto.OwnerWithDeviceDTO; import io.entgra.device.mgt.core.device.mgt.core.dto.OperationDTO; import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOException; @@ -5354,7 +5355,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv try { DeviceManagementDAOFactory.openConnection(); - ownerWithDeviceDTO = this.enrollmentDAO.getOwnersWithDeviceIds(owner, tenantId); + ownerWithDeviceDTO = this.enrollmentDAO.getOwnersWithDevices(owner, tenantId); } catch (DeviceManagementDAOException | SQLException e) { String msg = "Error occurred while retrieving device IDs for owner: " + owner; log.error(msg, e); @@ -5363,7 +5364,6 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv DeviceManagementDAOFactory.closeConnection(); } - // Add device count to the DTO if (ownerWithDeviceDTO != null) { List deviceIds = ownerWithDeviceDTO.getDeviceIds(); if (deviceIds != null) { @@ -5376,6 +5376,54 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv return ownerWithDeviceDTO; } + @Override + public OwnerWithDeviceDTO getOwnerWithDeviceByDeviceId(int deviceId) + throws DeviceManagementDAOException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + OwnerWithDeviceDTO deviceOwnerWithStatus; + + try { + DeviceManagementDAOFactory.openConnection(); + deviceOwnerWithStatus = enrollmentDAO.getOwnerWithDeviceByDeviceId(deviceId, tenantId); + } catch (DeviceManagementDAOException | SQLException e) { + String msg = "Error occurred while retrieving owner and status for device ID: " + deviceId; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + + if (deviceOwnerWithStatus != null) { + List deviceIds = deviceOwnerWithStatus.getDeviceIds(); + if (deviceIds != null) { + deviceOwnerWithStatus.setDeviceCount(deviceIds.size()); + } else { + deviceOwnerWithStatus.setDeviceCount(0); + } + } + + return deviceOwnerWithStatus; + } + + @Override + public List getDevicesByTenantId(int tenantId) + throws DeviceManagementDAOException { + List devices; + + try { + DeviceManagementDAOFactory.openConnection(); + devices = enrollmentDAO.getDevicesByTenantId(tenantId); + } catch (DeviceManagementDAOException | SQLException e) { + String msg = "Error occurred while retrieving devices for tenant ID: " + tenantId; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + + return devices; + } + @Override public OperationDTO getOperationDetailsById(int operationId) throws OperationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderService.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderService.java index 6c262ccf2d..fac06bfccf 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderService.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderService.java @@ -377,9 +377,11 @@ public interface GroupManagementProviderService { * Get group details and device IDs for a given group name. * * @param groupName the name of the group. - * @return a map containing group details and device IDs. + * @param offset the offset for the data set + * @param limit the limit for the data set + * @return {@link GroupDetailsDTO} which containing group details and a list of device IDs * @throws GroupManagementException if an error occurs while fetching group details. */ - GroupDetailsDTO getGroupDetailsWithDeviceIds(String groupName) throws GroupManagementException; + GroupDetailsDTO getGroupDetailsWithDevices(String groupName, int offset, int limit) throws GroupManagementException; } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderServiceImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderServiceImpl.java index 43e2a8eecc..c42feed9b8 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderServiceImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/service/GroupManagementProviderServiceImpl.java @@ -1688,7 +1688,8 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid } @Override - public GroupDetailsDTO getGroupDetailsWithDeviceIds(String groupName) throws GroupManagementException { + public GroupDetailsDTO getGroupDetailsWithDevices(String groupName, int offset, int limit) + throws GroupManagementException { if (log.isDebugEnabled()) { log.debug("Retrieving group details and device IDs for group: " + groupName); } @@ -1697,7 +1698,7 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid try { GroupManagementDAOFactory.openConnection(); - groupDetailsWithDevices = this.groupDAO.getGroupDetailsWithDeviceIds(groupName, tenantId); + groupDetailsWithDevices = this.groupDAO.getGroupDetailsWithDevices(groupName, tenantId, offset, limit); } catch (GroupManagementDAOException | SQLException e) { String msg = "Error occurred while retrieving group details and device IDs for group: " + groupName; log.error(msg, e); @@ -1706,9 +1707,8 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid GroupManagementDAOFactory.closeConnection(); } - // Add device count if (groupDetailsWithDevices != null) { - List deviceIds = (List) groupDetailsWithDevices.getDeviceIds(); + List deviceIds = groupDetailsWithDevices.getDeviceIds(); if (deviceIds != null) { groupDetailsWithDevices.setDeviceCount(deviceIds.size()); } else { From 332b2f2f91b2585d873fec09921aade309729b2e Mon Sep 17 00:00:00 2001 From: prathabanKavin Date: Tue, 18 Jun 2024 08:51:05 +0530 Subject: [PATCH 14/17] Change subscriptionType format --- .../mgt/core/impl/SubscriptionManagerImpl.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 401534e1d9..aeebeb2c50 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 @@ -2634,23 +2634,23 @@ public class SubscriptionManagerImpl implements SubscriptionManager { List subscriptionCounts = new ArrayList<>(); subscriptionCounts.add(new CategorizedSubscriptionCountsDTO( - "ALL", + "All", subscriptionDAO.getAllSubscriptionCount(appReleaseId, tenantId), subscriptionDAO.getAllUnsubscriptionCount(appReleaseId, tenantId))); subscriptionCounts.add(new CategorizedSubscriptionCountsDTO( - "DEVICE", + "Device", subscriptionDAO.getDeviceSubscriptionCount(appReleaseId, tenantId), subscriptionDAO.getDeviceUnsubscriptionCount(appReleaseId, tenantId))); subscriptionCounts.add(new CategorizedSubscriptionCountsDTO( - "GROUP", + "Group", subscriptionDAO.getGroupSubscriptionCount(appReleaseId, tenantId), subscriptionDAO.getGroupUnsubscriptionCount(appReleaseId, tenantId))); subscriptionCounts.add(new CategorizedSubscriptionCountsDTO( - "ROLE", + "Role", subscriptionDAO.getRoleSubscriptionCount(appReleaseId, tenantId), subscriptionDAO.getRoleUnsubscriptionCount(appReleaseId, tenantId))); subscriptionCounts.add(new CategorizedSubscriptionCountsDTO( - "USER", + "User", subscriptionDAO.getUserSubscriptionCount(appReleaseId, tenantId), subscriptionDAO.getUserUnsubscriptionCount(appReleaseId, tenantId))); From b95c795606279ccc727241c9a8a5722b6a66818b Mon Sep 17 00:00:00 2001 From: nipuni Date: Tue, 18 Jun 2024 08:57:58 +0530 Subject: [PATCH 15/17] Generalize JSON keys of application subscription APIs. --- .../mgt/common/DeviceSubscriptionData.java | 9 ++ .../common/dto/SubscriptionResponseDTO.java | 36 ++--- ...onDetailDTO.java => SubscriptionsDTO.java} | 86 ++++++------ .../mgt/common/dto/UserSubscriptionDTO.java | 132 ------------------ .../common/services/SubscriptionManager.java | 16 +-- .../mgt/core/dao/SubscriptionDAO.java | 11 +- .../GenericSubscriptionDAOImpl.java | 25 ++-- .../core/impl/SubscriptionManagerImpl.java | 60 ++++---- .../dao/impl/AbstractEnrollmentDAOImpl.java | 16 ++- .../core/dao/impl/AbstractGroupDAOImpl.java | 26 +++- .../device/mgt/core/dto/GroupDetailsDTO.java | 9 ++ .../mgt/core/dto/OwnerWithDeviceDTO.java | 9 ++ 12 files changed, 173 insertions(+), 262 deletions(-) rename components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/{GroupSubscriptionDetailDTO.java => SubscriptionsDTO.java} (80%) delete 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/UserSubscriptionDTO.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/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 aadbfaca6a..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 @@ -39,6 +39,7 @@ public class DeviceSubscriptionData { private boolean unsubscribed; private String unsubscribedBy; private Timestamp unsubscribedTimestamp; + private String deviceName; public String getAction() { return action; @@ -159,4 +160,12 @@ public class DeviceSubscriptionData { 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/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 index aecee2460f..3db74aeae4 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/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 @@ -5,9 +5,7 @@ import java.util.List; public class SubscriptionResponseDTO { private String UUID; - private List GroupsSubscriptions; - private List UserSubscriptions; - private List RolesSubscriptions; + private List subscriptions; private List DevicesOperations; public String getUUID() { @@ -18,30 +16,6 @@ public class SubscriptionResponseDTO { this.UUID = UUID; } - public List getGroupsSubscriptions() { - return GroupsSubscriptions; - } - - public void setGroupsSubscriptions(List groupsSubscriptions) { - GroupsSubscriptions = groupsSubscriptions; - } - - public List getUserSubscriptions() { - return UserSubscriptions; - } - - public void setUserSubscriptions(List userSubscriptions) { - UserSubscriptions = userSubscriptions; - } - - public List getRolesSubscriptions() { - return RolesSubscriptions; - } - - public void setRolesSubscriptions(List rolesSubscriptions) { - RolesSubscriptions = rolesSubscriptions; - } - public List getDevicesOperations() { return DevicesOperations; } @@ -49,4 +23,12 @@ public class SubscriptionResponseDTO { 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/GroupSubscriptionDetailDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/SubscriptionsDTO.java similarity index 80% 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/GroupSubscriptionDetailDTO.java rename to 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 index bc215b1e30..cb127696e3 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/GroupSubscriptionDetailDTO.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/SubscriptionsDTO.java @@ -23,45 +23,45 @@ import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionR import java.sql.Timestamp; import java.util.Map; -public class GroupSubscriptionDetailDTO { - private int groupId; - private String groupName; - private String groupOwner; +public class SubscriptionsDTO { + private int id; + private String owner; + private String name; private String subscribedBy; private Timestamp subscribedTimestamp; - private boolean isUnsubscribed; + 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 CategorizedSubscriptionResult devices; private Map statusPercentages; + private CategorizedSubscriptionResult devices; - // Getters and Setters - public int getGroupId() { - return groupId; + public int getId() { + return id; } - public void setGroupId(int groupId) { - this.groupId = groupId; + public void setId(int id) { + this.id = id; } - public String getGroupName() { - return groupName; + public String getOwner() { + return owner; } - public void setGroupName(String groupName) { - this.groupName = groupName; + public void setOwner(String owner) { + this.owner = owner; } - public String getGroupOwner() { - return groupOwner; + public String getName() { + return name; } - public void setGroupOwner(String groupOwner) { - this.groupOwner = groupOwner; + public void setName(String name) { + this.name = name; } public String getSubscribedBy() { @@ -80,14 +80,6 @@ public class GroupSubscriptionDetailDTO { this.subscribedTimestamp = subscribedTimestamp; } - public boolean isUnsubscribed() { - return isUnsubscribed; - } - - public void setUnsubscribed(boolean unsubscribed) { - isUnsubscribed = unsubscribed; - } - public String getUnsubscribedBy() { return unsubscribedBy; } @@ -104,6 +96,14 @@ public class GroupSubscriptionDetailDTO { this.unsubscribedTimestamp = unsubscribedTimestamp; } + public String getSubscribedFrom() { + return subscribedFrom; + } + + public void setSubscribedFrom(String subscribedFrom) { + this.subscribedFrom = subscribedFrom; + } + public int getAppReleaseId() { return appReleaseId; } @@ -120,12 +120,20 @@ public class GroupSubscriptionDetailDTO { this.deviceCount = deviceCount; } - public CategorizedSubscriptionResult getDevices() { - return devices; + public String getDeviceOwner() { + return deviceOwner; } - public void setDevices(CategorizedSubscriptionResult devices) { - this.devices = devices; + public void setDeviceOwner(String deviceOwner) { + this.deviceOwner = deviceOwner; + } + + public String getDeviceStatus() { + return deviceStatus; + } + + public void setDeviceStatus(String deviceStatus) { + this.deviceStatus = deviceStatus; } public Map getStatusPercentages() { @@ -136,19 +144,19 @@ public class GroupSubscriptionDetailDTO { this.statusPercentages = statusPercentages; } - public String getDeviceOwner() { - return deviceOwner; + public CategorizedSubscriptionResult getDevices() { + return devices; } - public void setDeviceOwner(String deviceOwner) { - this.deviceOwner = deviceOwner; + public void setDevices(CategorizedSubscriptionResult devices) { + this.devices = devices; } - public String getDeviceStatus() { - return deviceStatus; + public boolean getUnsubscribed() { + return unsubscribed; } - public void setDeviceStatus(String deviceStatus) { - this.deviceStatus = deviceStatus; + 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/dto/UserSubscriptionDTO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/dto/UserSubscriptionDTO.java deleted file mode 100644 index d3fd89f004..0000000000 --- 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 +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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 UserSubscriptionDTO { - - private String userName; - private String subscribedBy; - private Timestamp subscribedTimestamp; - private boolean unsubscribed; - private String unsubscribedBy; - private Timestamp unsubscribedTimestamp; - private int appReleaseId; - private int deviceCount; - private String deviceStatus; - private Map statusPercentages; - private CategorizedSubscriptionResult devices; - - public String getUserName() { - return userName; - } - - public void setUserName(String userName) { - this.userName = userName; - } - - public String getSubscribedBy() { - return subscribedBy; - } - - public void setSubscribedBy(String subscribedBy) { - this.subscribedBy = subscribedBy; - } - - public Timestamp getSubscribedTimestamp() { - return subscribedTimestamp; - } - - public void setSubscribedTimestamp(Timestamp subscribedTimestamp) { - this.subscribedTimestamp = subscribedTimestamp; - } - - public boolean isUnsubscribed() { - return unsubscribed; - } - - public boolean getUnsubscribed() { - return unsubscribed; - } - - public void setUnsubscribed(boolean unsubscribed) { - this.unsubscribed = unsubscribed; - } - - public String getUnsubscribedBy() { - return unsubscribedBy; - } - - public void setUnsubscribedBy(String unsubscribedBy) { - this.unsubscribedBy = unsubscribedBy; - } - - public Timestamp getUnsubscribedTimestamp() { - return unsubscribedTimestamp; - } - - public void setUnsubscribedTimestamp(Timestamp unsubscribedTimestamp) { - this.unsubscribedTimestamp = unsubscribedTimestamp; - } - - public int getAppReleaseId() { - return appReleaseId; - } - - public void setAppReleaseId(int appReleaseId) { - this.appReleaseId = appReleaseId; - } - - public int getDeviceCount() { - return deviceCount; - } - - public void setDeviceCount(int deviceCount) { - this.deviceCount = deviceCount; - } - - public Map getStatusPercentages() { - return statusPercentages; - } - - public void setStatusPercentages(Map statusPercentages) { - this.statusPercentages = statusPercentages; - } - - public CategorizedSubscriptionResult getDevices() { - return devices; - } - - public void setDevices(CategorizedSubscriptionResult devices) { - this.devices = devices; - } - - public String getDeviceStatus() { - return deviceStatus; - } - - public void setDeviceStatus(String deviceStatus) { - this.deviceStatus = deviceStatus; - } -} - diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.common/src/main/java/io/entgra/device/mgt/core/application/mgt/common/services/SubscriptionManager.java index fc0463add2..500c324cd0 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 @@ -22,10 +22,8 @@ import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionR 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.GroupSubscriptionDetailDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.UserSubscriptionDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.RoleSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.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; @@ -232,10 +230,10 @@ public interface SubscriptionManager { * @param subscriptionStatus the status of the subscription (subscribed or unsubscribed) * @param offset the offset for the data set * @param limit the limit for the data set - * @return {@link GroupSubscriptionDetailDTO} which contains the details of group subscriptions. + * @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) + List getGroupsSubscriptionDetailsByUUID(String uuid, String subscriptionStatus, int offset, int limit) throws ApplicationManagementException; /** @@ -245,10 +243,10 @@ public interface SubscriptionManager { * @param subscriptionStatus the status of the subscription (subscribed or unsubscribed) * @param offset the offset for the data set * @param limit the limit for the data set - * @return {@link UserSubscriptionDTO} which contains the details of user subscriptions. + * @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) + List getUserSubscriptionsByUUID(String uuid, String subscriptionStatus, int offset, int limit) throws ApplicationManagementException; /** @@ -258,10 +256,10 @@ public interface SubscriptionManager { * @param subscriptionStatus the status of the subscription (subscribed or unsubscribed) * @param offset the offset for the data set * @param limit the limit for the data set - * @return {@link RoleSubscriptionDTO} which contains the details of role subscriptions. + * @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) + List getRoleSubscriptionsByUUID(String uuid, String subscriptionStatus, int offset, int limit) throws ApplicationManagementException; /** diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/SubscriptionDAO.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/dao/SubscriptionDAO.java index a91d13eb06..cb32453082 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 @@ -19,11 +19,10 @@ 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.GroupSubscriptionDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.UserSubscriptionDTO; +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.RoleSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.ScheduledSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.exception.SubscriptionManagementException; import io.entgra.device.mgt.core.application.mgt.core.exception.ApplicationManagementDAOException; @@ -339,10 +338,10 @@ public interface SubscriptionDAO { * @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 UserSubscriptionDTO} which contains the details of user subscriptions. + * @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, + List getUserSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, int limit) throws ApplicationManagementDAOException; /** @@ -353,10 +352,10 @@ public interface SubscriptionDAO { * @param tenantId id of the current tenant. * @param offset the offset for the data set * @param limit the limit for the data set - * @return {@link RoleSubscriptionDTO} which contains the details of role subscriptions. + * @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) + List getRoleSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, int limit) 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 bf25c9c2b5..ad10bde91d 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 @@ -19,8 +19,7 @@ package io.entgra.device.mgt.core.application.mgt.core.dao.impl.subscription; import io.entgra.device.mgt.core.application.mgt.common.dto.GroupSubscriptionDTO; import io.entgra.device.mgt.core.application.mgt.common.dto.DeviceOperationDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.RoleSubscriptionDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.UserSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.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; @@ -1694,14 +1693,14 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } @Override - public List getUserSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, - int offset, int limit) throws ApplicationManagementDAOException { + public List getUserSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, + int offset, int limit) throws ApplicationManagementDAOException { if (log.isDebugEnabled()) { log.debug("Request received in DAO Layer to get user subscriptions related to the given UUID."); } try { Connection conn = this.getDBConnection(); - List userSubscriptions = new ArrayList<>(); + 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, " + @@ -1718,9 +1717,9 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc ps.setInt(5, offset); try (ResultSet rs = ps.executeQuery()) { while (rs.next()) { - UserSubscriptionDTO userSubscription; - userSubscription = new UserSubscriptionDTO(); - userSubscription.setUserName(rs.getString("USER_NAME")); + 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")); @@ -1745,14 +1744,14 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc } @Override - public List getRoleSubscriptionsByAppReleaseID(int appReleaseId, boolean unsubscribe, int tenantId, int offset, + 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<>(); + 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, " + @@ -1768,10 +1767,10 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc ps.setInt(4, limit); ps.setInt(5, offset); try (ResultSet rs = ps.executeQuery()) { - RoleSubscriptionDTO roleSubscription; + SubscriptionsDTO roleSubscription; while (rs.next()) { - roleSubscription = new RoleSubscriptionDTO(); - roleSubscription.setRoleName(rs.getString("ROLE_NAME")); + 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")); 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 aeebeb2c50..81c3f2d680 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 @@ -26,9 +26,7 @@ import io.entgra.device.mgt.core.application.mgt.common.CategorizedSubscriptionR 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.GroupSubscriptionDetailDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.UserSubscriptionDTO; -import io.entgra.device.mgt.core.application.mgt.common.dto.RoleSubscriptionDTO; +import io.entgra.device.mgt.core.application.mgt.common.dto.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; @@ -1706,8 +1704,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } @Override - public List getGroupsSubscriptionDetailsByUUID(String uuid, String subscriptionStatus, int offset, - int limit) throws ApplicationManagementException { + public List getGroupsSubscriptionDetailsByUUID(String uuid, String subscriptionStatus, int offset, + int limit) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); String groupName; @@ -1724,7 +1722,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } int appReleaseId = applicationReleaseDTO.getId(); - List groupDetailsWithDevices = new ArrayList<>(); + List groupDetailsWithDevices = new ArrayList<>(); List groupDetails = subscriptionDAO.getGroupsSubscriptionDetailsByAppReleaseID(appReleaseId, unsubscribe, tenantId, offset, limit); @@ -1741,10 +1739,10 @@ public class SubscriptionManagerImpl implements SubscriptionManager { GroupDetailsDTO groupDetailWithDevices = groupManagementProviderService.getGroupDetailsWithDevices(groupName, offset, limit); - GroupSubscriptionDetailDTO groupDetailDTO = new GroupSubscriptionDetailDTO(); - groupDetailDTO.setGroupId(groupDetailWithDevices.getGroupId()); - groupDetailDTO.setGroupName(groupDetail.getGroupName()); - groupDetailDTO.setGroupOwner(groupDetailWithDevices.getGroupOwner()); + 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()); @@ -1787,6 +1785,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { 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()); @@ -1824,6 +1823,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { 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()); @@ -1840,6 +1840,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { 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); } @@ -1886,7 +1887,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } @Override - public List getUserSubscriptionsByUUID(String uuid, String subscriptionStatus, int offset, int limit) + public List getUserSubscriptionsByUUID(String uuid, String subscriptionStatus, int offset, int limit) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); @@ -1904,9 +1905,9 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } int appReleaseId = applicationReleaseDTO.getId(); - List userSubscriptionsWithDevices = new ArrayList<>(); + List userSubscriptionsWithDevices = new ArrayList<>(); - List userSubscriptions = + List userSubscriptions = subscriptionDAO.getUserSubscriptionsByAppReleaseID(appReleaseId, unsubscribe, tenantId, offset, limit); if (userSubscriptions == null) { throw new ApplicationManagementException("User details not found for appReleaseId: " + appReleaseId); @@ -1914,15 +1915,15 @@ public class SubscriptionManagerImpl implements SubscriptionManager { DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); - for (UserSubscriptionDTO userSubscription : userSubscriptions) { - userName = userSubscription.getUserName(); + 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); - UserSubscriptionDTO userSubscriptionDTO = new UserSubscriptionDTO(); - userSubscriptionDTO.setUserName(userSubscription.getUserName()); + SubscriptionsDTO userSubscriptionDTO = new SubscriptionsDTO(); + userSubscriptionDTO.setName(userSubscription.getName()); userSubscriptionDTO.setSubscribedBy(userSubscription.getSubscribedBy()); userSubscriptionDTO.setSubscribedTimestamp(userSubscription.getSubscribedTimestamp()); userSubscriptionDTO.setUnsubscribed(userSubscription.getUnsubscribed()); @@ -1964,6 +1965,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { 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()); @@ -2001,6 +2003,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { 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()); @@ -2019,6 +2022,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { 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); } @@ -2063,7 +2067,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } @Override - public List getRoleSubscriptionsByUUID(String uuid, String subscriptionStatus, int offset, int limit) + public List getRoleSubscriptionsByUUID(String uuid, String subscriptionStatus, int offset, int limit) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); boolean unsubscribe = subscriptionStatus.equals("unsubscribed"); @@ -2081,9 +2085,9 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } int appReleaseId = applicationReleaseDTO.getId(); - List roleSubscriptionsWithDevices = new ArrayList<>(); + List roleSubscriptionsWithDevices = new ArrayList<>(); - List roleSubscriptions = + List roleSubscriptions = subscriptionDAO.getRoleSubscriptionsByAppReleaseID(appReleaseId, unsubscribe, tenantId, offset, limit); if (roleSubscriptions == null) { throw new ApplicationManagementException("Role details not found for appReleaseId: " + appReleaseId); @@ -2091,11 +2095,11 @@ public class SubscriptionManagerImpl implements SubscriptionManager { DeviceManagementProviderService deviceManagementProviderService = HelperUtil.getDeviceManagementProviderService(); - for (RoleSubscriptionDTO roleSubscription : roleSubscriptions) { - roleName = roleSubscription.getRoleName(); + for (SubscriptionsDTO roleSubscription : roleSubscriptions) { + roleName = roleSubscription.getName(); - RoleSubscriptionDTO roleSubscriptionDTO = new RoleSubscriptionDTO(); - roleSubscriptionDTO.setRoleName(roleSubscription.getRoleName()); + SubscriptionsDTO roleSubscriptionDTO = new SubscriptionsDTO(); + roleSubscriptionDTO.setName(roleSubscription.getName()); roleSubscriptionDTO.setSubscribedBy(roleSubscription.getSubscribedBy()); roleSubscriptionDTO.setSubscribedTimestamp(roleSubscription.getSubscribedTimestamp()); roleSubscriptionDTO.setUnsubscribed(roleSubscription.getUnsubscribed()); @@ -2148,6 +2152,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { 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()); @@ -2188,6 +2193,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { 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()); @@ -2204,6 +2210,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { if (!isSubscribedDevice) { DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); newDeviceDetail.setDeviceId(deviceId); + newDeviceDetail.setDeviceName(ownerDetailsWithDevices.getDeviceNames()); newDeviceDetail.setDeviceOwner(ownerDetailsWithDevices.getUserName()); newDeviceDetail.setDeviceStatus(ownerDetailsWithDevices.getDeviceStatus()); newDevices.add(newDeviceDetail); @@ -2339,6 +2346,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { 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()); @@ -2374,6 +2382,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { 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()); @@ -2396,6 +2405,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { && (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); @@ -2496,6 +2506,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { 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()); @@ -2529,6 +2540,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } else { DeviceSubscriptionData newDeviceDetail = new DeviceSubscriptionData(); newDeviceDetail.setDeviceId(deviceId); + newDeviceDetail.setDeviceName(ownerWithDevice.getDeviceNames()); newDeviceDetail.setDeviceOwner(ownerWithDevice.getUserName()); newDeviceDetail.setDeviceStatus(ownerWithDevice.getDeviceStatus()); newDevices.add(newDeviceDetail); 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 7f43707259..6612564fa6 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 @@ -567,9 +567,10 @@ public abstract class AbstractEnrollmentDAOImpl implements EnrollmentDAO { List deviceIds = new ArrayList<>(); int deviceCount = 0; - String sql = "SELECT DEVICE_ID, OWNER, STATUS AS DEVICE_STATUS " + - "FROM DM_ENROLMENT " + - "WHERE OWNER = ? AND TENANT_ID = ?"; + 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 (Connection conn = this.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { @@ -591,6 +592,7 @@ public abstract class AbstractEnrollmentDAOImpl implements EnrollmentDAO { ownerDetails.setDeviceIds(deviceIds); ownerDetails.setDeviceStatus("DEVICE_STATUS"); + ownerDetails.setDeviceNames("DEVICE_NAME"); ownerDetails.setDeviceCount(deviceCount); return ownerDetails; } @@ -600,9 +602,10 @@ public abstract class AbstractEnrollmentDAOImpl implements EnrollmentDAO { throws DeviceManagementDAOException { OwnerWithDeviceDTO deviceOwnerWithStatus = new OwnerWithDeviceDTO(); - String sql = "SELECT DEVICE_ID, OWNER, STATUS AS DEVICE_STATUS " + - "FROM DM_ENROLMENT " + - "WHERE DEVICE_ID = ? AND TENANT_ID = ?"; + 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 (Connection conn = this.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { @@ -616,6 +619,7 @@ public abstract class AbstractEnrollmentDAOImpl implements EnrollmentDAO { List deviceIds = new ArrayList<>(); deviceIds.add(rs.getInt("DEVICE_ID")); deviceOwnerWithStatus.setDeviceIds(deviceIds); + deviceOwnerWithStatus.setDeviceNames(rs.getString("DEVICE_NAME")); } } } catch (SQLException e) { diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/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 858df67b3c..8794e268b7 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 @@ -1450,13 +1450,25 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { List deviceIds = new ArrayList<>(); Map deviceOwners = new HashMap<>(); Map deviceStatuses = new HashMap<>(); + Map deviceNames = new HashMap<>(); // New map for device names String sql = - "SELECT g.ID AS GROUP_ID, g.GROUP_NAME, g.OWNER, e.OWNER AS DEVICE_OWNER, e.STATUS AS DEVICE_STATUS, dgm.DEVICE_ID " - + "FROM DM_GROUP g " - + "JOIN DM_DEVICE_GROUP_MAP dgm ON g.ID = dgm.GROUP_ID " - + "JOIN DM_ENROLMENT e ON dgm.DEVICE_ID = e.DEVICE_ID " - + "WHERE g.GROUP_NAME = ? AND g.TENANT_ID = ? " + + "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 ?"; try (Connection conn = GroupManagementDAOFactory.getConnection(); @@ -1471,12 +1483,13 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { if (groupDetails.getGroupId() == 0) { groupDetails.setGroupId(rs.getInt("GROUP_ID")); groupDetails.setGroupName(rs.getString("GROUP_NAME")); - groupDetails.setGroupOwner(rs.getString("OWNER")); + 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) { @@ -1488,6 +1501,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO { groupDetails.setDeviceCount(deviceIds.size()); groupDetails.setDeviceOwners(deviceOwners); groupDetails.setDeviceStatuses(deviceStatuses); + groupDetails.setDeviceNames(deviceNames); return groupDetails; } } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/GroupDetailsDTO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/GroupDetailsDTO.java index 4882bcbd3a..289fcfd472 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/GroupDetailsDTO.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/GroupDetailsDTO.java @@ -31,6 +31,7 @@ public class GroupDetailsDTO { private String deviceStatus; private Map deviceOwners; private Map deviceStatuses; + private Map deviceNames; public int getGroupId() { return groupId; @@ -103,4 +104,12 @@ public class GroupDetailsDTO { 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/OwnerWithDeviceDTO.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OwnerWithDeviceDTO.java index 5445069e8b..9d644b1930 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OwnerWithDeviceDTO.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dto/OwnerWithDeviceDTO.java @@ -26,6 +26,7 @@ public class OwnerWithDeviceDTO { private List deviceIds; private int deviceCount; private String deviceStatus; + private String deviceNames; public String getUserName() { return userName; @@ -58,4 +59,12 @@ public class OwnerWithDeviceDTO { public void setDeviceStatus(String deviceStatus) { this.deviceStatus = deviceStatus; } + + public String getDeviceNames() { + return deviceNames; + } + + public void setDeviceNames(String deviceNames) { + this.deviceNames = deviceNames; + } } From 6e4dbee81f5117a4cb356d152744c3c6ba7a37ff Mon Sep 17 00:00:00 2001 From: nipuni Date: Wed, 19 Jun 2024 07:36:51 +0530 Subject: [PATCH 16/17] Initialize OperationManagementDAOFactory with data source --- .../device/mgt/core/application/mgt/core/BaseTestCase.java | 2 ++ .../mgt/extensions/device/type/template/BaseExtensionsTest.java | 2 ++ 2 files changed, 4 insertions(+) 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.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 { From e1216d898a6b954a1e5b48a612e25e3429fd5fc4 Mon Sep 17 00:00:00 2001 From: prathabanKavin Date: Tue, 25 Jun 2024 09:12:24 +0530 Subject: [PATCH 17/17] Limit device percentages to two decimals --- .../mgt/core/impl/SubscriptionManagerImpl.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) 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 81c3f2d680..a55ea7126f 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 @@ -1851,7 +1851,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager { Map statusPercentages = new HashMap<>(); for (Map.Entry entry : statusCounts.entrySet()) { double percentage = ((double) entry.getValue() / totalDevices) * 100; - statusPercentages.put(entry.getKey(), percentage); + String formattedPercentage = String.format("%.2f", percentage); + statusPercentages.put(entry.getKey(), Double.valueOf(formattedPercentage)); } CategorizedSubscriptionResult categorizedSubscriptionResult; @@ -2033,7 +2034,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager { Map statusPercentages = new HashMap<>(); for (Map.Entry entry : statusCounts.entrySet()) { double percentage = ((double) entry.getValue() / totalDevices) * 100; - statusPercentages.put(entry.getKey(), percentage); + String formattedPercentage = String.format("%.2f", percentage); + statusPercentages.put(entry.getKey(), Double.valueOf(formattedPercentage)); } CategorizedSubscriptionResult categorizedSubscriptionResult; @@ -2225,7 +2227,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager { Map statusPercentages = new HashMap<>(); for (Map.Entry entry : statusCounts.entrySet()) { double percentage = totalDevices == 0 ? 0.0 : ((double) entry.getValue() / totalDevices) * 100; - statusPercentages.put(entry.getKey(), percentage); + String formattedPercentage = String.format("%.2f", percentage); + statusPercentages.put(entry.getKey(), Double.valueOf(formattedPercentage)); } CategorizedSubscriptionResult categorizedSubscriptionResult; @@ -2417,7 +2420,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager { Map statusPercentages = new HashMap<>(); for (Map.Entry entry : statusCounts.entrySet()) { double percentage = ((double) entry.getValue() / totalDevices) * 100; - statusPercentages.put(entry.getKey(), percentage); + String formattedPercentage = String.format("%.2f", percentage); + statusPercentages.put(entry.getKey(), Double.valueOf(formattedPercentage)); } CategorizedSubscriptionResult categorizedSubscriptionResult; @@ -2552,7 +2556,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager { Map statusPercentages = new HashMap<>(); for (Map.Entry entry : statusCounts.entrySet()) { double percentage = ((double) entry.getValue() / totalDevices) * 100; - statusPercentages.put(entry.getKey(), percentage); + String formattedPercentage = String.format("%.2f", percentage); + statusPercentages.put(entry.getKey(), Double.valueOf(formattedPercentage)); } CategorizedSubscriptionResult categorizedSubscriptionResult =