WIP: Add Tenanted Device Task Configurations #370
Draft
pramilaniroshan
wants to merge 7 commits from pramilaniroshan/device-mgt-core:device-tenant-task-configuration
into master
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.common.metadata.mgt;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class DeviceFrequencyMap extends HashMap<String, DeviceFrequencyMap.Device> {
|
||||
public static class Device {
|
||||
private int frequency;
|
||||
|
||||
public int getFrequency() {
|
||||
return frequency;
|
||||
}
|
||||
|
||||
public void setFrequency(int frequency) {
|
||||
this.frequency = frequency;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.common.metadata.mgt;
|
||||
|
||||
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException;
|
||||
|
||||
|
||||
public interface DeviceTaskConfigurationService {
|
||||
|
||||
/**
|
||||
* This method is useful to add Default Task Frequency from device type xml
|
||||
*
|
||||
* @throws MetadataManagementException if error while adding default TaskFrequency
|
||||
*/
|
||||
void addDefaultTaskFrequency(int tenantId) throws MetadataManagementException;
|
||||
|
||||
/**
|
||||
* This method is useful to add custom Task Frequency for device types
|
||||
*
|
||||
* @throws MetadataManagementException if error while adding TaskFrequency
|
||||
*/
|
||||
void addTaskFrequency(int tenantId, int frequency, String deviceType) throws MetadataManagementException;
|
||||
|
||||
/**
|
||||
* Retrieves the task frequency for a specific device type and tenant from the cache or metadata service.
|
||||
*
|
||||
* @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;
|
||||
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2018 - 2024 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
|
||||
*
|
||||
* Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
|
||||
*
|
||||
* Licensed under the Entgra Commercial License, Version 1.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://entgra.io/licenses/entgra-commercial/1.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 io.entgra.device.mgt.core.device.mgt.common.OperationMonitoringTaskConfig;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
|
||||
@ApiModel(
|
||||
value = "DeviceTaskManagerWrapper",
|
||||
description = "DeviceTaskManagerWrapper represents request payload of scheduling device details retriever task")
|
||||
public class DeviceTaskManagerWrapper {
|
||||
|
||||
@ApiModelProperty(name = "cron",
|
||||
value = "Cron to be scheduled",
|
||||
example = "0 0 * * * ? *, 0 0 0/8 * * ? *",
|
||||
required = true)
|
||||
private String cron;
|
||||
|
||||
@ApiModelProperty(name = "payload",
|
||||
value = "Operation payload")
|
||||
private Object payload;
|
||||
|
||||
@ApiModelProperty(name = "deviceType",
|
||||
value = "Device type")
|
||||
private String deviceType;
|
||||
|
||||
public OperationMonitoringTaskConfig getOperationMonitoringTaskConfig() {
|
||||
return operationMonitoringTaskConfig;
|
||||
}
|
||||
|
||||
public void setOperationMonitoringTaskConfig(OperationMonitoringTaskConfig operationMonitoringTaskConfig) {
|
||||
this.operationMonitoringTaskConfig = operationMonitoringTaskConfig;
|
||||
}
|
||||
|
||||
private OperationMonitoringTaskConfig operationMonitoringTaskConfig;
|
||||
|
||||
|
||||
public String getDeviceType() {
|
||||
return deviceType;
|
||||
}
|
||||
|
||||
public void setDeviceType(String deviceType) {
|
||||
this.deviceType = deviceType;
|
||||
}
|
||||
|
||||
public String getCron() {
|
||||
return cron;
|
||||
}
|
||||
|
||||
public void setCron(String cron) {
|
||||
this.cron = cron;
|
||||
}
|
||||
|
||||
public Object getPayload() {
|
||||
return payload;
|
||||
}
|
||||
|
||||
public void setPayload(Object payload) {
|
||||
this.payload = payload;
|
||||
}
|
||||
}
|
@ -0,0 +1,171 @@
|
|||||||
/*
|
|||||||
* 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.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.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.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.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 MetadataManagementService metadataManagementService;
|
|||||||
|
|||||||
private static DeviceTaskConfigurationServiceImpl instance;
|
|||||||
|
|||||||
|
|||||||
private static final Cache<String, DeviceFrequencyMap> cache = CacheBuilder.newBuilder()
|
|||||||
.expireAfterWrite(1, TimeUnit.HOURS)
|
|||||||
.build();
|
|||||||
|
|||||||
private DeviceTaskConfigurationServiceImpl() {
|
|||||||
this.metadataManagementService = new MetadataManagementServiceImpl();
|
|||||||
}
|
|||||||
|
|||||||
public static synchronized DeviceTaskConfigurationServiceImpl getInstance() {
|
|||||||
if (instance == null) {
|
|||||||
instance = new DeviceTaskConfigurationServiceImpl();
|
|||||||
}
|
|||||||
return instance;
|
|||||||
}
|
|||||||
|
|||||||
private Metadata constructTaskFrequencyMetadata(Map<String, Integer> deviceFrequencies) {
|
|||||||
JsonObject jsonObject = new JsonObject();
|
|||||||
pramilaniroshan marked this conversation as resolved
|
|||||||
int frequency;
|
|||||||
for (Map.Entry<String, Integer> entry : deviceFrequencies.entrySet()) {
|
|||||||
String deviceType = entry.getKey();
|
|||||||
frequency = entry.getValue();
|
|||||||
JsonObject deviceObject = new JsonObject();
|
|||||||
deviceObject.addProperty("frequency", String.valueOf(frequency));
|
|||||||
jsonObject.add(deviceType, deviceObject);
|
|||||||
}
|
|||||||
Metadata metadata = new Metadata();
|
|||||||
metadata.setMetaKey(MetadataConstants.DEVICE_TASK_FREQUENCY);
|
|||||||
metadata.setMetaValue(jsonObject.toString());
|
|||||||
return metadata;
|
|||||||
}
|
|||||||
|
|||||||
/**
|
|||||||
* 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();
|
|||||||
}
|
|||||||
|
|||||||
@Override
|
|||||||
public void addDefaultTaskFrequency(int tenantId) throws MetadataManagementException {
|
|||||||
try {
|
|||||||
Map<String, Integer> deviceFrequencies = new HashMap<>();
|
|||||||
DeviceManagementProviderService dms = DeviceManagementDataHolder.getInstance().getDeviceManagementProvider();
|
|||||||
List<DeviceType> deviceTypes = dms.getDeviceTypes();
|
|||||||
for (DeviceType deviceType : deviceTypes) {
|
|||||||
deviceFrequencies.put(deviceType.getName(), getDefaultTaskFrequency(dms, deviceType.getName()));
|
|||||||
}
|
|||||||
addMetaData(deviceFrequencies, tenantId);
|
|||||||
} catch (DeviceManagementException e) {
|
|||||||
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, String deviceType) throws MetadataManagementException {
|
|||||||
try {
|
|||||||
Map<String, Integer> deviceFrequencies = new HashMap<>();
|
|||||||
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<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)) {
|
|||||||
return deviceFrequencyMap.get(deviceType).getFrequency();
|
|||||||
} else {
|
|||||||
log.error("Device type not found: " + deviceType);
|
|||||||
throw new MetadataManagementException("Device type not found: " + deviceType);
|
|||||||
}
|
|||||||
}
|
|||||||
}
|
@ -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.metadata.mgt;
|
|||||||
|
|||||||
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException;
|
|||||||
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.DeviceTaskConfigurationService;
|
|||||||
import io.entgra.device.mgt.core.device.mgt.core.internal.DeviceManagementDataHolder;
|
|||||||
import org.apache.commons.logging.Log;
|
|||||||
import org.apache.commons.logging.LogFactory;
|
|||||||
import org.wso2.carbon.core.ServerStartupObserver;
|
|||||||
import org.wso2.carbon.user.api.Tenant;
|
|||||||
import org.wso2.carbon.user.api.UserStoreException;
|
|||||||
import org.wso2.carbon.user.core.service.RealmService;
|
|||||||
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
|
|||||||
|
|||||||
public class TaskConfigurationStartupHandler implements ServerStartupObserver {
|
|||||||
|
|||||||
private static final Log log = LogFactory.getLog(TaskConfigurationStartupHandler.class);
|
|||||||
|
|||||||
@Override
|
|||||||
public void completingServerStartup() {
|
|||||||
|
|||||||
}
|
|||||||
|
|||||||
@Override
|
|||||||
public void completedServerStartup() {
|
|||||||
rajitha marked this conversation as resolved
|
|||||||
Thread t = new Thread(new Runnable() {
|
|||||||
@Override
|
|||||||
public void run() {
|
|||||||
DeviceTaskConfigurationService deviceTaskConfigurationService = DeviceTaskConfigurationServiceImpl.getInstance();
|
|||||||
RealmService realmService = DeviceManagementDataHolder.getInstance().getRealmService();
|
|||||||
if (log.isDebugEnabled()) {
|
|||||||
log.debug("Server has just started, hence started adding default task frequencies");
|
|||||||
}
|
|||||||
try {
|
|||||||
deviceTaskConfigurationService.addDefaultTaskFrequency(MultitenantConstants.SUPER_TENANT_ID);
|
|||||||
Tenant[] tenantArray = realmService.getTenantManager().getAllTenants();
|
|||||||
pramilaniroshan marked this conversation as resolved
|
|||||||
if (tenantArray != null) {
|
|||||||
for (Tenant tenant : tenantArray) {
|
|||||||
deviceTaskConfigurationService.addDefaultTaskFrequency(tenant.getId());
|
|||||||
}
|
|||||||
}
|
|||||||
} catch (MetadataManagementException e) {
|
|||||||
String msg = "Error occurred while adding default task frequency metadata entry.";
|
|||||||
pramilaniroshan marked this conversation as resolved
|
|||||||
log.error(msg, e);
|
|||||||
} catch (UserStoreException e) {
|
|||||||
log.error("Error occurred while trying to get the available tenants.", e);
|
|||||||
}
|
|||||||
log.info("Finish adding default task frequencies");
|
|||||||
}
|
|||||||
});
|
|||||||
t.start();
|
|||||||
}
|
|||||||
}
|
Loading…
Reference in new issue
Make volatile