Refactor DeviceTaskConfigurationService with caching handling for improved performance

pull/370/head
Pramila Niroshan 5 months ago
parent 1dd398532c
commit b53cb5cb76

@ -33,14 +33,17 @@ public interface DeviceTaskConfigurationService {
/** /**
* This method is useful to add custom Task Frequency for device types * 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; int getTaskFrequency(String deviceType, int tenantId) throws MetadataManagementException;

@ -40,6 +40,17 @@ public interface MetadataManagementService {
*/ */
Metadata createMetadata(Metadata metadata) throws MetadataManagementException, MetadataKeyAlreadyExistsException; 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. * Get the specified Metadata entry.
* *

@ -18,55 +18,52 @@
package io.entgra.device.mgt.core.device.mgt.core.metadata.mgt; 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.Gson;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import io.entgra.device.mgt.core.device.mgt.common.OperationMonitoringTaskConfig; 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.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.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.DeviceFrequencyMap;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.DeviceTaskConfigurationService; 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.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.dto.DeviceType;
import io.entgra.device.mgt.core.device.mgt.core.internal.DeviceManagementDataHolder; 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.metadata.mgt.dao.util.MetadataConstants;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService; import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import java.sql.SQLException;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit;
public class DeviceTaskConfigurationServiceImpl implements DeviceTaskConfigurationService { public class DeviceTaskConfigurationServiceImpl implements DeviceTaskConfigurationService {
private static final Log log = LogFactory.getLog(DeviceTaskConfigurationServiceImpl.class); private static final Log log = LogFactory.getLog(DeviceTaskConfigurationServiceImpl.class);
private final MetadataDAO metadataDAO; private final MetadataManagementService metadataManagementService;
public DeviceTaskConfigurationServiceImpl() { private final Cache<String, DeviceFrequencyMap> cache;
this.metadataDAO = MetadataManagementDAOFactory.getMetadataDAO();
}
private void addMetadataEntry(int tenantId, Metadata metadata, String key) throws MetadataManagementDAOException { public DeviceTaskConfigurationServiceImpl() {
metadataDAO.addMetadata(tenantId, metadata); this.metadataManagementService = new MetadataManagementServiceImpl();
if (log.isDebugEnabled()) { this.cache = CacheBuilder.newBuilder()
log.debug(key + " metadata entry has been inserted successfully"); .expireAfterWrite(1, TimeUnit.HOURS)
} .build();
} }
private Metadata constructTaskFrequencyMetadata(Map<String, Integer> deviceFrequencies) { private Metadata constructTaskFrequencyMetadata(Map<String, Integer> deviceFrequencies) {
JsonObject jsonObject = new JsonObject(); JsonObject jsonObject = new JsonObject();
int frequency;
for (Map.Entry<String, Integer> entry : deviceFrequencies.entrySet()) { for (Map.Entry<String, Integer> entry : deviceFrequencies.entrySet()) {
String deviceType = entry.getKey(); String deviceType = entry.getKey();
int frequency = entry.getValue(); frequency = entry.getValue();
// Create a JsonObject for the current device type
JsonObject deviceObject = new JsonObject(); JsonObject deviceObject = new JsonObject();
deviceObject.addProperty("frequency", String.valueOf(frequency)); deviceObject.addProperty("frequency", String.valueOf(frequency));
jsonObject.add(deviceType, deviceObject); jsonObject.add(deviceType, deviceObject);
@ -77,9 +74,20 @@ public class DeviceTaskConfigurationServiceImpl implements DeviceTaskConfigurati
return metadata; 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); 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(); return operationMonitoringTaskConfig.getFrequency();
} }
@ -92,87 +100,64 @@ public class DeviceTaskConfigurationServiceImpl implements DeviceTaskConfigurati
for (DeviceType deviceType : deviceTypes) { for (DeviceType deviceType : deviceTypes) {
deviceFrequencies.put(deviceType.getName(), getDefaultTaskFrequency(dms, deviceType.getName())); deviceFrequencies.put(deviceType.getName(), getDefaultTaskFrequency(dms, deviceType.getName()));
} }
MetadataManagementDAOFactory.beginTransaction(); addMetaData(deviceFrequencies, tenantId);
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);
} catch (DeviceManagementException e) { } catch (DeviceManagementException e) {
String msg = "Error occurred while trying to obtain device types."; log.error("Error occurred while trying to obtain device types.", e);
log.error(msg, e); } catch (MetadataKeyAlreadyExistsException e) {
} finally { log.error("Specified metaKey is already exist.", e);
MetadataManagementDAOFactory.closeConnection();
} }
} }
@Override @Override
public void addTaskFrequency(int tenantId, int frequency) throws MetadataManagementException { public void addTaskFrequency(int tenantId, int frequency, String deviceType) throws MetadataManagementException {
try { try {
Map<String, Integer> deviceFrequencies = new HashMap<>(); Map<String, Integer> deviceFrequencies = new HashMap<>();
DeviceManagementProviderService dms = DeviceManagementDataHolder.getInstance().getDeviceManagementProvider(); deviceFrequencies.put(deviceType, frequency);
List<DeviceType> deviceTypes = dms.getDeviceTypes(); addMetaData(deviceFrequencies, tenantId);
for (DeviceType deviceType : deviceTypes) { } catch (MetadataKeyAlreadyExistsException e) {
deviceFrequencies.put(deviceType.getName(), frequency); log.error("Specified metaKey is already exist.", e);
}
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();
} }
} }
@Override /**
public int getTaskFrequency(String deviceType, int tenantId) throws MetadataManagementException { * Loads the device frequency map from the metadata management service.
try { *
MetadataManagementDAOFactory.openConnection(); * @return the device frequency map parsed from the stored metadata.
Metadata metadata = metadataDAO.getMetadata(tenantId, MetadataConstants.DEVICE_TASK_FREQUENCY); * @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(); String metaValue = metadata.getMetaValue();
Gson gson = new Gson(); Gson gson = new Gson();
DeviceFrequencyMap deviceFrequencyMap = gson.fromJson(metaValue, DeviceFrequencyMap.class); return gson.fromJson(metaValue, DeviceFrequencyMap.class);
// Check if the device type exists in the map }
/**
* 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<String, Integer> 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 {
DeviceFrequencyMap deviceFrequencyMap = cache.getIfPresent(Integer.toString(tenantId));
if (deviceFrequencyMap == null) {
deviceFrequencyMap = loadDeviceFrequencyMap();
cache.put(Integer.toString(tenantId), deviceFrequencyMap);
}
if (deviceFrequencyMap.containsKey(deviceType)) { if (deviceFrequencyMap.containsKey(deviceType)) {
// Retrieve the frequency for the given device type
return deviceFrequencyMap.get(deviceType).getFrequency(); return deviceFrequencyMap.get(deviceType).getFrequency();
} else { } else {
log.error("Device type not found: " + deviceType);
throw new MetadataManagementException("Device type not found: " + deviceType); 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();
}
} }
} }

@ -53,10 +53,20 @@ public class MetadataManagementServiceImpl implements MetadataManagementService
@Override @Override
public Metadata createMetadata(Metadata metadata) public Metadata createMetadata(Metadata metadata)
throws MetadataManagementException, MetadataKeyAlreadyExistsException { 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()) { if (log.isDebugEnabled()) {
log.debug("Creating Metadata : [" + metadata.toString() + "]"); log.debug("Creating Metadata : [" + metadata.toString() + "]");
} }
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
try { try {
MetadataManagementDAOFactory.beginTransaction(); MetadataManagementDAOFactory.beginTransaction();
if (metadataDAO.isExist(tenantId, metadata.getMetaKey())) { if (metadataDAO.isExist(tenantId, metadata.getMetaKey())) {

@ -157,7 +157,7 @@ public class DeviceTaskManagerTest extends BaseDeviceManagementTest {
public void testDeviceDetailRetrieverTaskExecute() throws OperationManagementException, MetadataManagementException { public void testDeviceDetailRetrieverTaskExecute() throws OperationManagementException, MetadataManagementException {
DeviceDetailsRetrieverTask deviceDetailsRetrieverTask = new DeviceDetailsRetrieverTask(); DeviceDetailsRetrieverTask deviceDetailsRetrieverTask = new DeviceDetailsRetrieverTask();
DeviceTaskConfigurationService deviceTaskConfigurationService = new DeviceTaskConfigurationServiceImpl(); DeviceTaskConfigurationService deviceTaskConfigurationService = new DeviceTaskConfigurationServiceImpl();
deviceTaskConfigurationService.addTaskFrequency(MultitenantConstants.SUPER_TENANT_ID, FREQUENCY); deviceTaskConfigurationService.addTaskFrequency(MultitenantConstants.SUPER_TENANT_ID, FREQUENCY,TestDataHolder.TEST_DEVICE_TYPE);
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
map.put("DEVICE_TYPE", TestDataHolder.TEST_DEVICE_TYPE); map.put("DEVICE_TYPE", TestDataHolder.TEST_DEVICE_TYPE);
deviceDetailsRetrieverTask.setProperties(map); deviceDetailsRetrieverTask.setProperties(map);

Loading…
Cancel
Save