From b53cb5cb76e34f76ce4250bbc444425773fcdf92 Mon Sep 17 00:00:00 2001 From: pramilaniroshan Date: Wed, 26 Jun 2024 14:41:15 +0530 Subject: [PATCH] Refactor DeviceTaskConfigurationService with caching handling for improved performance --- .../mgt/DeviceTaskConfigurationService.java | 11 +- .../mgt/MetadataManagementService.java | 11 ++ .../DeviceTaskConfigurationServiceImpl.java | 163 ++++++++---------- .../mgt/MetadataManagementServiceImpl.java | 12 +- .../mgt/core/task/DeviceTaskManagerTest.java | 2 +- 5 files changed, 104 insertions(+), 95 deletions(-) diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/metadata/mgt/DeviceTaskConfigurationService.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/metadata/mgt/DeviceTaskConfigurationService.java index f0520351cc..3e9a4ed88d 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/metadata/mgt/DeviceTaskConfigurationService.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/metadata/mgt/DeviceTaskConfigurationService.java @@ -33,14 +33,17 @@ public interface DeviceTaskConfigurationService { /** * This method is useful to add custom Task Frequency for device types * - * @throws MetadataManagementException if error while adding default TaskFrequency + * @throws MetadataManagementException if error while adding TaskFrequency */ - void addTaskFrequency(int tenantId, int frequency) throws MetadataManagementException; + void addTaskFrequency(int tenantId, int frequency, String deviceType) throws MetadataManagementException; /** - * This method is useful to get existing Task Frequency by device type and tenant id + * Retrieves the task frequency for a specific device type and tenant from the cache or metadata service. * - * @throws MetadataManagementException if error while getting existing TaskFrequency + * @param deviceType the type of the device for which the task frequency is being retrieved. + * @param tenantId the ID of the tenant associated with the device. + * @return the task frequency for the specified device type and tenant. + * @throws MetadataManagementException if there is an error managing the metadata. */ int getTaskFrequency(String deviceType, int tenantId) throws MetadataManagementException; diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/metadata/mgt/MetadataManagementService.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/metadata/mgt/MetadataManagementService.java index d02614ce2c..ee3018b606 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/metadata/mgt/MetadataManagementService.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/metadata/mgt/MetadataManagementService.java @@ -40,6 +40,17 @@ public interface MetadataManagementService { */ Metadata createMetadata(Metadata metadata) throws MetadataManagementException, MetadataKeyAlreadyExistsException; + /** + * Persist the provided Metadata entry. + * + * @param metadata the Metadata entry to be persisted + * @param tenantId the Metadata entry to be persisted in given tenantId + * @return the Metadata entry along with the updated Metadata.id + * @throws MetadataManagementException If a data source related exception occurred + * @throws MetadataKeyAlreadyExistsException If the provided Metadata.metaKey already exist + */ + Metadata createMetadata(Metadata metadata, int tenantId) throws MetadataManagementException, MetadataKeyAlreadyExistsException; + /** * Get the specified Metadata entry. * 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/metadata/mgt/DeviceTaskConfigurationServiceImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/metadata/mgt/DeviceTaskConfigurationServiceImpl.java index 31d36384f8..295df337f7 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/metadata/mgt/DeviceTaskConfigurationServiceImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/metadata/mgt/DeviceTaskConfigurationServiceImpl.java @@ -18,55 +18,52 @@ package io.entgra.device.mgt.core.device.mgt.core.metadata.mgt; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import com.google.gson.Gson; import com.google.gson.JsonObject; import io.entgra.device.mgt.core.device.mgt.common.OperationMonitoringTaskConfig; import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException; +import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataKeyAlreadyExistsException; import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException; -import io.entgra.device.mgt.core.device.mgt.common.exceptions.TransactionManagementException; import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.DeviceFrequencyMap; import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.DeviceTaskConfigurationService; import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata; +import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService; import io.entgra.device.mgt.core.device.mgt.core.dto.DeviceType; import io.entgra.device.mgt.core.device.mgt.core.internal.DeviceManagementDataHolder; -import io.entgra.device.mgt.core.device.mgt.core.metadata.mgt.dao.MetadataDAO; -import io.entgra.device.mgt.core.device.mgt.core.metadata.mgt.dao.MetadataManagementDAOException; -import io.entgra.device.mgt.core.device.mgt.core.metadata.mgt.dao.MetadataManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.core.metadata.mgt.dao.util.MetadataConstants; import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; public class DeviceTaskConfigurationServiceImpl implements DeviceTaskConfigurationService { private static final Log log = LogFactory.getLog(DeviceTaskConfigurationServiceImpl.class); - private final MetadataDAO metadataDAO; + private final MetadataManagementService metadataManagementService; - public DeviceTaskConfigurationServiceImpl() { - this.metadataDAO = MetadataManagementDAOFactory.getMetadataDAO(); - } + private final Cache cache; - private void addMetadataEntry(int tenantId, Metadata metadata, String key) throws MetadataManagementDAOException { - metadataDAO.addMetadata(tenantId, metadata); - if (log.isDebugEnabled()) { - log.debug(key + " metadata entry has been inserted successfully"); - } + public DeviceTaskConfigurationServiceImpl() { + this.metadataManagementService = new MetadataManagementServiceImpl(); + this.cache = CacheBuilder.newBuilder() + .expireAfterWrite(1, TimeUnit.HOURS) + .build(); } private Metadata constructTaskFrequencyMetadata(Map deviceFrequencies) { JsonObject jsonObject = new JsonObject(); - + int frequency; for (Map.Entry entry : deviceFrequencies.entrySet()) { String deviceType = entry.getKey(); - int frequency = entry.getValue(); - // Create a JsonObject for the current device type + frequency = entry.getValue(); JsonObject deviceObject = new JsonObject(); deviceObject.addProperty("frequency", String.valueOf(frequency)); jsonObject.add(deviceType, deviceObject); @@ -77,9 +74,20 @@ public class DeviceTaskConfigurationServiceImpl implements DeviceTaskConfigurati return metadata; } - - private int getDefaultTaskFrequency(DeviceManagementProviderService dms, String deviceType) { + /** + * Retrieves the default task frequency for a specific device type using device type xml. + * + * @param dms the DeviceManagementProviderService used to fetch the device monitoring configuration. + * @param deviceType the type of the device for which the frequency is being retrieved. + * @return the task frequency for the specified device type. + * @throws DeviceManagementException if the frequency configuration is not found for the specified device type. + */ + private int getDefaultTaskFrequency(DeviceManagementProviderService dms, String deviceType) throws DeviceManagementException { OperationMonitoringTaskConfig operationMonitoringTaskConfig = dms.getDeviceMonitoringConfig(deviceType); + if (operationMonitoringTaskConfig == null) { + log.error("Frequency configuration not found for device type: " + deviceType); + throw new DeviceManagementException("Frequency configuration not found for device type: " + deviceType); + } return operationMonitoringTaskConfig.getFrequency(); } @@ -92,87 +100,64 @@ public class DeviceTaskConfigurationServiceImpl implements DeviceTaskConfigurati for (DeviceType deviceType : deviceTypes) { deviceFrequencies.put(deviceType.getName(), getDefaultTaskFrequency(dms, deviceType.getName())); } - MetadataManagementDAOFactory.beginTransaction(); - if (!metadataDAO.isExist(tenantId, MetadataConstants.DEVICE_TASK_FREQUENCY)) { - Metadata defaultTaskFrequencyMetadata = constructTaskFrequencyMetadata(deviceFrequencies); - // Add default TaskFrequency - addMetadataEntry(tenantId, defaultTaskFrequencyMetadata, MetadataConstants.DEVICE_TASK_FREQUENCY); - } - MetadataManagementDAOFactory.commitTransaction(); - } catch (MetadataManagementDAOException e) { - MetadataManagementDAOFactory.rollbackTransaction(); - String msg = "Error occurred while inserting default task frequency metadata entry."; - log.error(msg, e); - throw new MetadataManagementException(msg, e); - } catch (TransactionManagementException e) { - String msg = "Error occurred while opening a connection to the data source"; - log.error(msg, e); - throw new MetadataManagementException(msg, e); + addMetaData(deviceFrequencies, tenantId); } catch (DeviceManagementException e) { - String msg = "Error occurred while trying to obtain device types."; - log.error(msg, e); - } finally { - MetadataManagementDAOFactory.closeConnection(); + log.error("Error occurred while trying to obtain device types.", e); + } catch (MetadataKeyAlreadyExistsException e) { + log.error("Specified metaKey is already exist.", e); } } + @Override - public void addTaskFrequency(int tenantId, int frequency) throws MetadataManagementException { + public void addTaskFrequency(int tenantId, int frequency, String deviceType) throws MetadataManagementException { try { Map deviceFrequencies = new HashMap<>(); - DeviceManagementProviderService dms = DeviceManagementDataHolder.getInstance().getDeviceManagementProvider(); - List deviceTypes = dms.getDeviceTypes(); - for (DeviceType deviceType : deviceTypes) { - deviceFrequencies.put(deviceType.getName(), frequency); - } - MetadataManagementDAOFactory.beginTransaction(); - if (!metadataDAO.isExist(tenantId, MetadataConstants.DEVICE_TASK_FREQUENCY)) { - Metadata defaultTaskFrequencyMetadata = constructTaskFrequencyMetadata(deviceFrequencies); - // Add Task Frequency entry for given Frequency - addMetadataEntry(tenantId, defaultTaskFrequencyMetadata, MetadataConstants.DEVICE_TASK_FREQUENCY); - } - MetadataManagementDAOFactory.commitTransaction(); - } catch (MetadataManagementDAOException e) { - MetadataManagementDAOFactory.rollbackTransaction(); - String msg = "Error occurred while inserting default task frequency metadata entry."; - log.error(msg, e); - throw new MetadataManagementException(msg, e); - } catch (TransactionManagementException e) { - String msg = "Error occurred while opening a connection to the data source"; - log.error(msg, e); - throw new MetadataManagementException(msg, e); - } catch (DeviceManagementException e) { - String msg = "Error occurred while trying to obtain device types."; - log.error(msg, e); - } finally { - MetadataManagementDAOFactory.closeConnection(); + deviceFrequencies.put(deviceType, frequency); + addMetaData(deviceFrequencies, tenantId); + } catch (MetadataKeyAlreadyExistsException e) { + log.error("Specified metaKey is already exist.", e); } } + /** + * Loads the device frequency map from the metadata management service. + * + * @return the device frequency map parsed from the stored metadata. + * @throws MetadataManagementException if an error occurs while retrieving the metadata. + */ + private DeviceFrequencyMap loadDeviceFrequencyMap() throws MetadataManagementException { + Metadata metadata = metadataManagementService.retrieveMetadata(MetadataConstants.DEVICE_TASK_FREQUENCY); + String metaValue = metadata.getMetaValue(); + Gson gson = new Gson(); + return gson.fromJson(metaValue, DeviceFrequencyMap.class); + } + + /** + * Adds metadata for device frequencies to the metadata management service. + * + * @param deviceFrequencies a map containing device types as keys and their corresponding frequencies as values. + * @param tenantId the tenant ID for which the metadata is being added. + * @throws MetadataManagementException if there is an error managing the metadata. + * @throws MetadataKeyAlreadyExistsException if the metadata key already exists. + */ + private void addMetaData(Map deviceFrequencies, int tenantId) throws MetadataManagementException, MetadataKeyAlreadyExistsException { + Metadata taskFrequencyMetadata = constructTaskFrequencyMetadata(deviceFrequencies); + taskFrequencyMetadata.setMetaKey(MetadataConstants.DEVICE_TASK_FREQUENCY); + metadataManagementService.createMetadata(taskFrequencyMetadata, tenantId); + } + @Override public int getTaskFrequency(String deviceType, int tenantId) throws MetadataManagementException { - try { - MetadataManagementDAOFactory.openConnection(); - Metadata metadata = metadataDAO.getMetadata(tenantId, MetadataConstants.DEVICE_TASK_FREQUENCY); - String metaValue = metadata.getMetaValue(); - Gson gson = new Gson(); - DeviceFrequencyMap deviceFrequencyMap = gson.fromJson(metaValue, DeviceFrequencyMap.class); - // Check if the device type exists in the map - if (deviceFrequencyMap.containsKey(deviceType)) { - // Retrieve the frequency for the given device type - return deviceFrequencyMap.get(deviceType).getFrequency(); - } else { - throw new MetadataManagementException("Device type not found: " + deviceType); - } - } catch (MetadataManagementDAOException e) { - String msg = "Error occurred while retrieving device task frequency metadata for tenant:" + tenantId; - log.error(msg, e); - throw new MetadataManagementException(msg, e); - } catch (SQLException e) { - String msg = "Error occurred while opening a connection to the data source"; - log.error(msg, e); - throw new MetadataManagementException(msg, e); - } finally { - MetadataManagementDAOFactory.closeConnection(); + DeviceFrequencyMap deviceFrequencyMap = cache.getIfPresent(Integer.toString(tenantId)); + if (deviceFrequencyMap == null) { + deviceFrequencyMap = loadDeviceFrequencyMap(); + cache.put(Integer.toString(tenantId), deviceFrequencyMap); + } + if (deviceFrequencyMap.containsKey(deviceType)) { + return deviceFrequencyMap.get(deviceType).getFrequency(); + } else { + log.error("Device type not found: " + deviceType); + throw new MetadataManagementException("Device type not found: " + deviceType); } } } 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/metadata/mgt/MetadataManagementServiceImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/metadata/mgt/MetadataManagementServiceImpl.java index 121caf5ba3..e833cafbaf 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/metadata/mgt/MetadataManagementServiceImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/metadata/mgt/MetadataManagementServiceImpl.java @@ -53,10 +53,20 @@ public class MetadataManagementServiceImpl implements MetadataManagementService @Override public Metadata createMetadata(Metadata metadata) throws MetadataManagementException, MetadataKeyAlreadyExistsException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + return createMetadata(tenantId, metadata); + } + + @Override + public Metadata createMetadata(Metadata metadata, int tenantId) + throws MetadataManagementException, MetadataKeyAlreadyExistsException { + return createMetadata(tenantId, metadata); + } + + private Metadata createMetadata (int tenantId, Metadata metadata) throws MetadataManagementException, MetadataKeyAlreadyExistsException { if (log.isDebugEnabled()) { log.debug("Creating Metadata : [" + metadata.toString() + "]"); } - int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); try { MetadataManagementDAOFactory.beginTransaction(); if (metadataDAO.isExist(tenantId, metadata.getMetaKey())) { 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/task/DeviceTaskManagerTest.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/test/java/io/entgra/device/mgt/core/device/mgt/core/task/DeviceTaskManagerTest.java index 1884e7a772..c19eb3ac75 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/test/java/io/entgra/device/mgt/core/device/mgt/core/task/DeviceTaskManagerTest.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/test/java/io/entgra/device/mgt/core/device/mgt/core/task/DeviceTaskManagerTest.java @@ -157,7 +157,7 @@ public class DeviceTaskManagerTest extends BaseDeviceManagementTest { public void testDeviceDetailRetrieverTaskExecute() throws OperationManagementException, MetadataManagementException { DeviceDetailsRetrieverTask deviceDetailsRetrieverTask = new DeviceDetailsRetrieverTask(); DeviceTaskConfigurationService deviceTaskConfigurationService = new DeviceTaskConfigurationServiceImpl(); - deviceTaskConfigurationService.addTaskFrequency(MultitenantConstants.SUPER_TENANT_ID, FREQUENCY); + deviceTaskConfigurationService.addTaskFrequency(MultitenantConstants.SUPER_TENANT_ID, FREQUENCY,TestDataHolder.TEST_DEVICE_TYPE); Map map = new HashMap<>(); map.put("DEVICE_TYPE", TestDataHolder.TEST_DEVICE_TYPE); deviceDetailsRetrieverTask.setProperties(map);