Changed the device-status-task to use optimized queries which Resolves harshanl/product-iots#518

4.x.x
Harshan Liyanage 8 years ago
parent 4ec139608e
commit d3cb7ba70b

@ -20,8 +20,12 @@ package org.wso2.carbon.device.mgt.extensions.device.type.deployer.template;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.*;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.DeviceManager;
import org.wso2.carbon.device.mgt.common.InitialOperationConfig;
import org.wso2.carbon.device.mgt.common.MonitoringOperation;
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
import org.wso2.carbon.device.mgt.common.DeviceStatusTaskPluginConfig;
import org.wso2.carbon.device.mgt.common.ProvisioningConfig;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
@ -29,7 +33,12 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration
import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.*;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.ConfigProperties;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.DeviceTypeConfiguration;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.Property;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.PushNotificationProvider;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.TaskConfiguration;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.DeviceStatusTaskConfiguration;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.template.policy.mgt.DefaultPolicyMonitoringManager;
import java.util.ArrayList;

@ -32,6 +32,7 @@ import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationProvi
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementServiceComponent;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagerStartupListener;
@ -73,23 +74,19 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
throw new DeviceManagementException("No tenant available for tenant domain " + tenantDomain);
}
synchronized (providers) {
try {
if (isInitiated) {
/* Initializing Device Management Service Provider */
provider.init();
DeviceManagerUtil.registerDeviceType(deviceType, tenantId, isSharedWithAllTenants);
DeviceManagementDataHolder.getInstance().setRequireDeviceAuthorization(deviceType,
provider.getDeviceManager().
requireDeviceAuthorization());
registerPushNotificationStrategy(provider);
registerMonitoringTask(provider);
if (deviceManagementConfig != null && deviceManagementConfig.getDeviceStatusTaskConfig().isEnabled()) {
registerDeviceStatusMonitoringTask(provider);
}
if (isInitiated) {
/* Initializing Device Management Service Provider */
provider.init();
DeviceManagerUtil.registerDeviceType(deviceType, tenantId, isSharedWithAllTenants);
DeviceManagementDataHolder.getInstance().setRequireDeviceAuthorization(deviceType,
provider.getDeviceManager().
requireDeviceAuthorization());
registerPushNotificationStrategy(provider);
registerMonitoringTask(provider);
if (deviceManagementConfig != null && deviceManagementConfig.getDeviceStatusTaskConfig().isEnabled()) {
DeviceType deviceTypeObj = DeviceManagerUtil.getDeviceType(deviceType, tenantId);
registerDeviceStatusMonitoringTask(deviceTypeObj, provider);
}
} catch (DeviceManagementException e) {
throw new DeviceManagementException("Error occurred while adding device management provider '" +
deviceType + "'", e);
}
if (isSharedWithAllTenants) {
DeviceTypeIdentifier deviceTypeIdentifier = new DeviceTypeIdentifier(deviceType);
@ -118,7 +115,9 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
unregisterPushNotificationStrategy(deviceTypeIdentifier);
unregisterMonitoringTask(provider);
if (deviceManagementConfig != null && deviceManagementConfig.getDeviceStatusTaskConfig().isEnabled()) {
unregisterDeviceStatusMonitoringTask(provider);
DeviceType deviceTypeObj = DeviceManagerUtil.getDeviceType(deviceTypeIdentifier.getDeviceType(),
deviceTypeIdentifier.getTenantId());
unregisterDeviceStatusMonitoringTask(deviceTypeObj, provider);
}
}
@ -162,30 +161,30 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
deviceManagementService.getProvisioningConfig().getProviderTenantDomain(), true);
try {
boolean isSharedWithAllTenants = deviceManagementService.getProvisioningConfig().isSharedWithAllTenants();
DeviceTypeIdentifier deviceTypeIdentifier;
if (isSharedWithAllTenants) {
deviceTypeIdentifier = new DeviceTypeIdentifier(deviceManagementService.getType());
} else {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
deviceTypeIdentifier = new DeviceTypeIdentifier(deviceManagementService.getType(), tenantId);
}
boolean isSharedWithAllTenants = deviceManagementService.getProvisioningConfig().isSharedWithAllTenants();
DeviceTypeIdentifier deviceTypeIdentifier;
if (isSharedWithAllTenants) {
deviceTypeIdentifier = new DeviceTypeIdentifier(deviceManagementService.getType());
} else {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
deviceTypeIdentifier = new DeviceTypeIdentifier(deviceManagementService.getType(), tenantId);
}
if (pushNoteConfig != null) {
PushNotificationProvider provider = DeviceManagementDataHolder.getInstance()
.getPushNotificationProviderRepository().getProvider(pushNoteConfig.getType());
if (provider == null) {
throw new DeviceManagementException(
"No registered push notification provider found for the type: '" +
pushNoteConfig.getType() + "'.");
if (pushNoteConfig != null) {
PushNotificationProvider provider = DeviceManagementDataHolder.getInstance()
.getPushNotificationProviderRepository().getProvider(pushNoteConfig.getType());
if (provider == null) {
throw new DeviceManagementException(
"No registered push notification provider found for the type: '" +
pushNoteConfig.getType() + "'.");
}
NotificationStrategy notificationStrategy = provider.getNotificationStrategy(pushNoteConfig);
operationManagerRepository.addOperationManager(deviceTypeIdentifier,
new OperationManagerImpl(deviceTypeIdentifier.getDeviceType(), notificationStrategy));
} else {
operationManagerRepository.addOperationManager(deviceTypeIdentifier,
new OperationManagerImpl(deviceTypeIdentifier.getDeviceType()));
}
NotificationStrategy notificationStrategy = provider.getNotificationStrategy(pushNoteConfig);
operationManagerRepository.addOperationManager(deviceTypeIdentifier,
new OperationManagerImpl(deviceTypeIdentifier.getDeviceType(), notificationStrategy));
} else {
operationManagerRepository.addOperationManager(deviceTypeIdentifier,
new OperationManagerImpl(deviceTypeIdentifier.getDeviceType()));
}
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
@ -231,18 +230,18 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
}
}
private void registerDeviceStatusMonitoringTask(DeviceManagementService deviceManagementService) throws
private void registerDeviceStatusMonitoringTask(DeviceType deviceType, DeviceManagementService deviceManagementService) throws
DeviceManagementException {
DeviceTaskManagerService deviceTaskManagerService = DeviceManagementDataHolder.getInstance().
getDeviceTaskManagerService();
DeviceStatusTaskPluginConfig deviceStatusTaskPluginConfig = deviceManagementService.getDeviceStatusTaskPluginConfig();
if (deviceStatusTaskPluginConfig != null && deviceStatusTaskPluginConfig.isRequireStatusMonitoring()) {
if (deviceTaskManagerService == null) {
DeviceManagementDataHolder.getInstance().addDeviceStatusTaskPluginConfig(deviceManagementService.getType(),
DeviceManagementDataHolder.getInstance().addDeviceStatusTaskPluginConfig(deviceType,
deviceStatusTaskPluginConfig);
} else {
try {
new DeviceStatusTaskManagerServiceImpl().startTask(deviceManagementService.getType(), deviceStatusTaskPluginConfig);
new DeviceStatusTaskManagerServiceImpl().startTask(deviceType, deviceStatusTaskPluginConfig);
} catch (DeviceStatusTaskException e) {
throw new DeviceManagementException("Error occurred while adding Device Status task service for '" +
deviceManagementService.getType() + "'", e);
@ -251,21 +250,21 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
}
}
private void unregisterDeviceStatusMonitoringTask(DeviceManagementService deviceManagementService) throws
private void unregisterDeviceStatusMonitoringTask(DeviceType deviceType, DeviceManagementService deviceManagementService) throws
DeviceManagementException {
DeviceStatusTaskManagerService deviceStatusTaskManagerService = DeviceManagementDataHolder.getInstance().
getDeviceStatusTaskManagerService();
DeviceStatusTaskPluginConfig deviceStatusTaskPluginConfig = deviceManagementService.getDeviceStatusTaskPluginConfig();
if (deviceStatusTaskPluginConfig != null && deviceStatusTaskPluginConfig.isRequireStatusMonitoring()) {
try {
DeviceManagementDataHolder.getInstance().removeDeviceStatusTaskPluginConfig(deviceManagementService.getType());
deviceStatusTaskManagerService.stopTask(deviceManagementService.getType(), deviceStatusTaskPluginConfig);
DeviceManagementDataHolder.getInstance().removeDeviceStatusTaskPluginConfig(deviceType);
deviceStatusTaskManagerService.stopTask(deviceType, deviceStatusTaskPluginConfig);
} catch (DeviceStatusTaskException e) {
throw new DeviceManagementException("Error occurred while stopping Device Status task service for '" +
deviceManagementService.getType() + "'", e);
}
}
}
}
public OperationManager getOperationManager(String deviceType, int tenantId) {
//Priority need to be given to the tenant before public.
@ -289,7 +288,7 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
ProvisioningConfig provisioningConfig = provider.getProvisioningConfig();
int tenantId = DeviceManagerUtil.getTenantId(provisioningConfig.getProviderTenantDomain());
DeviceManagerUtil.registerDeviceType(deviceTypeName, tenantId,
provisioningConfig.isSharedWithAllTenants());
provisioningConfig.isSharedWithAllTenants());
registerPushNotificationStrategy(provider);
registerMonitoringTask(provider);
@ -299,13 +298,13 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
//until fix that, use following variable to enable and disable of checking user authorization.
DeviceManagementDataHolder.getInstance().setRequireDeviceAuthorization(provider.getType(),
provider.getDeviceManager()
.requireDeviceAuthorization());
provider.getDeviceManager()
.requireDeviceAuthorization());
} catch (Throwable e) {
/* Throwable is caught intentionally as failure of one plugin - due to invalid start up parameters,
etc - should not block the initialization of other device management providers */
log.error("Error occurred while initializing device management provider '" +
provider.getType() + "'", e);
provider.getType() + "'", e);
}
}
this.isInitiated = true;

@ -19,6 +19,7 @@
package org.wso2.carbon.device.mgt.core.internal;
import org.wso2.carbon.device.mgt.common.DeviceStatusTaskPluginConfig;
import org.wso2.carbon.device.mgt.common.DeviceTypeIdentifier;
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService;
@ -26,6 +27,7 @@ import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManager;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager;
import org.wso2.carbon.device.mgt.core.app.mgt.config.AppManagementConfig;
import org.wso2.carbon.device.mgt.core.config.license.LicenseConfig;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.push.notification.mgt.PushNotificationProviderRepository;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService;
@ -63,8 +65,8 @@ public class DeviceManagementDataHolder {
private PushNotificationProviderRepository pushNotificationProviderRepository;
private DeviceTaskManagerService deviceTaskManagerService;
private DeviceStatusTaskManagerService deviceStatusTaskManagerService;
private Map<String, DeviceStatusTaskPluginConfig> deviceStatusTaskPluginConfigs = Collections.synchronizedMap(
new HashMap<String, DeviceStatusTaskPluginConfig>());
private Map<DeviceType, DeviceStatusTaskPluginConfig> deviceStatusTaskPluginConfigs = Collections.synchronizedMap(
new HashMap<DeviceType, DeviceStatusTaskPluginConfig>());
private Map<String, OperationMonitoringTaskConfig> map = new HashMap<>();
@ -238,19 +240,19 @@ public class DeviceManagementDataHolder {
this.deviceStatusTaskManagerService = deviceStatusTaskManagerService;
}
public void addDeviceStatusTaskPluginConfig(String deviceType, DeviceStatusTaskPluginConfig deviceStatusTaskPluginConfig) {
public void addDeviceStatusTaskPluginConfig(DeviceType deviceType, DeviceStatusTaskPluginConfig deviceStatusTaskPluginConfig) {
this.deviceStatusTaskPluginConfigs.put(deviceType, deviceStatusTaskPluginConfig);
}
public DeviceStatusTaskPluginConfig getDeviceStatusTaskPluginConfig(String deviceType) {
public DeviceStatusTaskPluginConfig getDeviceStatusTaskPluginConfig(DeviceTypeIdentifier deviceType) {
return this.deviceStatusTaskPluginConfigs.get(deviceType);
}
public Map<String, DeviceStatusTaskPluginConfig> getDeviceStatusTaskPluginConfigs() {
public Map<DeviceType, DeviceStatusTaskPluginConfig> getDeviceStatusTaskPluginConfigs() {
return this.deviceStatusTaskPluginConfigs;
}
public void removeDeviceStatusTaskPluginConfig(String deviceType) {
public void removeDeviceStatusTaskPluginConfig(DeviceType deviceType) {
this.deviceStatusTaskPluginConfigs.remove(deviceType);
}
}

@ -28,6 +28,7 @@ import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig;
import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManager;
import org.wso2.carbon.device.mgt.core.device.details.mgt.impl.DeviceInformationManagerImpl;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.search.mgt.SearchManagerService;
import org.wso2.carbon.device.mgt.core.search.mgt.impl.SearchManagerServiceImpl;
import org.wso2.carbon.device.mgt.core.status.task.DeviceStatusTaskException;
@ -95,12 +96,11 @@ public class DeviceTaskManagerServiceComponent {
private void startDeviceStatusMonitoringTask() {
DeviceStatusTaskManagerService deviceStatusTaskManagerService = new DeviceStatusTaskManagerServiceImpl();
Map<String, DeviceStatusTaskPluginConfig> deviceStatusTaskPluginConfigs = DeviceManagementDataHolder.
Map<DeviceType, DeviceStatusTaskPluginConfig> deviceStatusTaskPluginConfigs = DeviceManagementDataHolder.
getInstance().getDeviceStatusTaskPluginConfigs();
for (String deviceType : new ArrayList<>(deviceStatusTaskPluginConfigs.keySet())) {
for (DeviceType deviceType : new ArrayList<>(deviceStatusTaskPluginConfigs.keySet())) {
try {
deviceStatusTaskManagerService.startTask(deviceType, deviceStatusTaskPluginConfigs.get(deviceType));
} catch (DeviceStatusTaskException e) {
log.error("Exception occurred while starting the DeviceStatusMonitoring Task for deviceType '" +
deviceType + "'", e);

@ -26,10 +26,10 @@ import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
public class OperationEnrolmentMapping {
int enrolmentId;
int deviceId;
int tenantId;
long createdTime;
String owner;
String deviceType;
String deviceId;
EnrolmentInfo.Status deviceStatus;
public int getTenantId() {
@ -48,11 +48,11 @@ public class OperationEnrolmentMapping {
this.enrolmentId = enrolmentId;
}
public int getDeviceId() {
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(int deviceId) {
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
@ -64,14 +64,6 @@ public class OperationEnrolmentMapping {
this.createdTime = createdTime;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public EnrolmentInfo.Status getDeviceStatus() {
return deviceStatus;
}
@ -79,4 +71,12 @@ public class OperationEnrolmentMapping {
public void setDeviceStatus(String deviceStatus) {
this.deviceStatus = EnrolmentInfo.Status.valueOf(deviceStatus);
}
public String getDeviceType() {
return deviceType;
}
public void setDeviceType(String deviceType) {
this.deviceType = deviceType;
}
}

@ -18,11 +18,12 @@
*/
package org.wso2.carbon.device.mgt.core.operation.mgt.dao;
import org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.core.operation.mgt.OperationEnrolmentMapping;
import org.wso2.carbon.device.mgt.core.operation.mgt.OperationMapping;
import org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation;
import java.util.List;
import java.util.Map;
public interface OperationMappingDAO {
@ -36,13 +37,29 @@ public interface OperationMappingDAO {
OperationManagementDAOException;
/**
* This method returns first pending/repeated operation available for each active enrolment where the operation was
* created after the given timestamp.
* This method returns first pending/repeated operation available for each active enrolment of given device-type
* where the operation was created after the given timestamp.
*
* @param minDuration - Upper limit of Operation created time
* @param maxDuration - Lower limit of Operation created time
* @param deviceTypeId - Device Type Id of required devices
* @return List<OperationEnrolmentMapping> - List of OperationEnrolmentMapping objects containing required data
* @throws OperationManagementDAOException
*/
List<OperationEnrolmentMapping> getFirstPendingOperationMappingsForActiveEnrolments(long minDuration,
long maxDuration, int deviceTypeId)
throws OperationManagementDAOException;
/**
* This method returns the timestamp of last completed Operation for each active enrolment of given device-type
* where the operation was completed after the given timestamp.
*
* @param createdTimeStamp - Operation created time
* @param timeStamp - Timestamp of considered time-interval
* @param deviceTypeId - Device Type of required devices
* @return List<OperationEnrolmentMapping> - List of OperationEnrolmentMapping objects containing required data
* @throws OperationManagementDAOException
*/
List<OperationEnrolmentMapping> getFirstPendingOperationMappingsForActiveEnrolments(long createdTimeStamp)
Map<Integer, Long> getLastConnectedTimeForActiveEnrolments(long timeStamp, int deviceTypeId)
throws OperationManagementDAOException;
}

@ -18,8 +18,9 @@
*/
package org.wso2.carbon.device.mgt.core.operation.mgt.dao.impl;
import org.wso2.carbon.device.mgt.core.operation.mgt.OperationEnrolmentMapping;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.core.operation.mgt.OperationEnrolmentMapping;
import org.wso2.carbon.device.mgt.core.operation.mgt.OperationMapping;
import org.wso2.carbon.device.mgt.core.operation.mgt.dao.OperationManagementDAOException;
import org.wso2.carbon.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory;
@ -31,7 +32,9 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class OperationMappingDAOImpl implements OperationMappingDAO {
@ -134,8 +137,8 @@ public class OperationMappingDAOImpl implements OperationMappingDAO {
}
@Override
public List<OperationEnrolmentMapping> getFirstPendingOperationMappingsForActiveEnrolments(long createdTimeStamp)
throws OperationManagementDAOException {
public List<OperationEnrolmentMapping> getFirstPendingOperationMappingsForActiveEnrolments(long minDuration,
long maxDuration, int deviceTypeId) throws OperationManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
List<OperationEnrolmentMapping> enrolmentOperationMappingList = null;
@ -143,12 +146,17 @@ public class OperationMappingDAOImpl implements OperationMappingDAO {
Connection conn = OperationManagementDAOFactory.getConnection();
//We are specifically looking for operation mappings in 'Pending' & 'Repeated' states. Further we want
//devices to be active at that moment. Hence filtering by 'ACTIVE' & 'UNREACHABLE' device states.
String sql = "SELECT E.ID AS ENROLMENT_ID, E.DEVICE_ID, E.OWNER, E.STATUS, E.TENANT_ID, OP.CREATED_TIMESTAMP " +
"FROM DM_ENROLMENT E, (SELECT ENROLMENT_ID AS EID, MIN(CREATED_TIMESTAMP) AS CREATED_TIMESTAMP FROM " +
"DM_ENROLMENT_OP_MAPPING WHERE STATUS IN ('PENDING','REPEATED') AND CREATED_TIMESTAMP >= ? " +
"GROUP BY EID) OP WHERE OP.EID=E.ID AND E.STATUS IN ('ACTIVE','UNREACHABLE')";
String sql = "SELECT ENROLMENT_ID, D.DEVICE_IDENTIFICATION AS DEVICE_IDENTIFIER, MIN(CREATED_TIMESTAMP) " +
"AS CREATED_TIMESTAMP, E.STATUS AS ENROLMENT_STATUS, E.TENANT_ID FROM " +
"DM_ENROLMENT_OP_MAPPING AS OP INNER JOIN DM_ENROLMENT E ON OP.ENROLMENT_ID = E.ID INNER JOIN " +
"DM_DEVICE D ON E.DEVICE_ID = D.ID WHERE " +
"OP.STATUS IN ('"+ Operation.Status.PENDING.name() + "','" + Operation.Status.REPEATED.name() + "') " +
"AND OP.CREATED_TIMESTAMP BETWEEN ? AND ? AND E.STATUS IN ('" + EnrolmentInfo.Status.ACTIVE.name() +
"','" + EnrolmentInfo.Status.UNREACHABLE.name() + "') AND D.DEVICE_TYPE_ID = ? GROUP BY ENROLMENT_ID";
stmt = conn.prepareStatement(sql);
stmt.setLong(1, createdTimeStamp);
stmt.setLong(1, maxDuration);
stmt.setLong(2, minDuration);
stmt.setInt(3, deviceTypeId);
rs = stmt.executeQuery();
enrolmentOperationMappingList = new ArrayList<>();
while (rs.next()) {
@ -157,21 +165,52 @@ public class OperationMappingDAOImpl implements OperationMappingDAO {
}
} catch (SQLException e) {
throw new OperationManagementDAOException("Error occurred while fetching pending operation mappings for " +
"active devices ", e);
"active devices of type '" + deviceTypeId + "'", e);
} finally {
OperationManagementDAOUtil.cleanupResources(stmt, rs);
}
return enrolmentOperationMappingList;
}
@Override
public Map<Integer, Long> getLastConnectedTimeForActiveEnrolments(long timeStamp, int deviceTypeId) throws OperationManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
Map<Integer, Long> lastConnectedTimeMap = null;
try {
Connection conn = OperationManagementDAOFactory.getConnection();
//We are specifically looking for operation mappings in 'Pending' & 'Repeated' states. Further we want
//devices to be active at that moment. Hence filtering by 'ACTIVE' & 'UNREACHABLE' device states.
String sql = "SELECT OP.ENROLMENT_ID AS EID, MAX(OP.UPDATED_TIMESTAMP) AS LAST_CONNECTED_TIME FROM " +
"DM_ENROLMENT_OP_MAPPING AS OP INNER JOIN DM_ENROLMENT E ON OP.ENROLMENT_ID = E.ID INNER JOIN " +
"DM_DEVICE D ON E.DEVICE_ID = D.ID WHERE " +
"OP.STATUS = '" + Operation.Status.COMPLETED.name() + "'" +
"AND OP.UPDATED_TIMESTAMP >= ? AND E.STATUS IN ('" + EnrolmentInfo.Status.ACTIVE.name() +
"','" + EnrolmentInfo.Status.UNREACHABLE.name() + "') AND D.DEVICE_TYPE_ID = ? GROUP BY ENROLMENT_ID";
stmt = conn.prepareStatement(sql);
stmt.setLong(1, timeStamp);
stmt.setInt(2, deviceTypeId);
rs = stmt.executeQuery();
lastConnectedTimeMap = new HashMap<>();
while (rs.next()) {
lastConnectedTimeMap.put(rs.getInt("EID"), rs.getLong("LAST_CONNECTED_TIME"));
}
} catch (SQLException e) {
throw new OperationManagementDAOException("Error occurred while fetching last connected time for " +
"active devices of type '" + deviceTypeId + "'", e);
} finally {
OperationManagementDAOUtil.cleanupResources(stmt, rs);
}
return lastConnectedTimeMap;
}
private OperationEnrolmentMapping getEnrolmentOpMapping(ResultSet rs) throws SQLException {
OperationEnrolmentMapping enrolmentOperationMapping = new OperationEnrolmentMapping();
enrolmentOperationMapping.setEnrolmentId(rs.getInt("ENROLMENT_ID"));
enrolmentOperationMapping.setDeviceId(rs.getInt("DEVICE_ID"));
enrolmentOperationMapping.setDeviceId(rs.getString("DEVICE_IDENTIFIER"));
enrolmentOperationMapping.setTenantId(rs.getInt("TENANT_ID"));
enrolmentOperationMapping.setOwner(rs.getString("OWNER"));
enrolmentOperationMapping.setCreatedTime(rs.getLong("CREATED_TIMESTAMP"));
enrolmentOperationMapping.setDeviceStatus(rs.getString("STATUS"));
enrolmentOperationMapping.setDeviceStatus(rs.getString("ENROLMENT_STATUS"));
return enrolmentOperationMapping;
}
}

@ -19,7 +19,7 @@
package org.wso2.carbon.device.mgt.core.status.task;
import org.wso2.carbon.device.mgt.common.DeviceStatusTaskPluginConfig;
import org.wso2.carbon.device.mgt.core.config.status.task.DeviceStatusTaskConfig;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
/**
* This interface defines the methods that should be implemented by the management service of
@ -29,26 +29,32 @@ public interface DeviceStatusTaskManagerService {
/**
* This method will start the task.
*
* @param deviceType - DeviceType
* @param deviceStatusTaskConfig - DeviceStatusTaskConfig
* @throws DeviceStatusTaskException
*/
void startTask(String deviceType, DeviceStatusTaskPluginConfig deviceStatusTaskConfig)
void startTask(DeviceType deviceType, DeviceStatusTaskPluginConfig deviceStatusTaskConfig)
throws DeviceStatusTaskException;
/**
* This method will stop the task.
*
* @param deviceType - DeviceType
* @param deviceStatusTaskConfig - DeviceStatusTaskConfig
* @throws DeviceStatusTaskException
*/
void stopTask(String deviceType, DeviceStatusTaskPluginConfig deviceStatusTaskConfig)
void stopTask(DeviceType deviceType, DeviceStatusTaskPluginConfig deviceStatusTaskConfig)
throws DeviceStatusTaskException;
/**
* This will update the task frequency which it runs.
*
* @param deviceType
* @param deviceStatusTaskConfig - DeviceStatusTaskConfig
* @throws DeviceStatusTaskException
*/
void updateTask(String deviceType, DeviceStatusTaskPluginConfig deviceStatusTaskConfig)
void updateTask(DeviceType deviceType, DeviceStatusTaskPluginConfig deviceStatusTaskConfig)
throws DeviceStatusTaskException;
/**
@ -56,5 +62,5 @@ public interface DeviceStatusTaskManagerService {
* @param deviceType - Device Type
* @throws DeviceStatusTaskException
*/
boolean isTaskScheduled(String deviceType) throws DeviceStatusTaskException;
boolean isTaskScheduled(DeviceType deviceType) throws DeviceStatusTaskException;
}

@ -21,10 +21,7 @@ package org.wso2.carbon.device.mgt.core.status.task.impl;
import com.google.gson.Gson;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.core.encryption.SymmetricEncryption;
import org.wso2.carbon.device.mgt.common.DeviceStatusTaskPluginConfig;
import org.wso2.carbon.device.mgt.core.config.status.task.DeviceStatusTaskConfig;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.TransactionManagementException;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
@ -37,7 +34,6 @@ import org.wso2.carbon.ntask.core.Task;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@ -50,10 +46,12 @@ public class DeviceStatusMonitoringTask implements Task {
private static Log log = LogFactory.getLog(DeviceStatusMonitoringTask.class);
private String deviceType;
private DeviceStatusTaskPluginConfig deviceStatusTaskPluginConfig;
private int deviceTypeId = -1;
@Override
public void setProperties(Map<String, String> properties) {
deviceType = properties.get(DeviceStatusTaskManagerServiceImpl.DEVICE_TYPE);
deviceTypeId = Integer.parseInt(properties.get(DeviceStatusTaskManagerServiceImpl.DEVICE_TYPE_ID));
String deviceStatusTaskConfigStr = properties.get(DeviceStatusTaskManagerServiceImpl.DEVICE_STATUS_TASK_CONFIG);
Gson gson = new Gson();
deviceStatusTaskPluginConfig = gson.fromJson(deviceStatusTaskConfigStr, DeviceStatusTaskPluginConfig.class);
@ -68,14 +66,22 @@ public class DeviceStatusMonitoringTask implements Task {
public void execute() {
List<OperationEnrolmentMapping> operationEnrolmentMappings = null;
List<EnrolmentInfo> enrolmentInfoTobeUpdated = new ArrayList<>();
Map<Integer, Long> lastActivities = null;
EnrolmentInfo enrolmentInfo;
try {
operationEnrolmentMappings = this.getOperationEnrolmentMappings();
if (operationEnrolmentMappings.size() > 0) {
lastActivities = this.getLastDeviceActivities();
}
} catch (DeviceStatusTaskException e) {
log.error("Error occurred while fetching OperationEnrolment mappings of deviceType '" + deviceType + "'", e);
}
for (OperationEnrolmentMapping mapping:operationEnrolmentMappings) {
EnrolmentInfo.Status newStatus = this.determineDeviceStatus(mapping);
long lastActivity = -1;
if (lastActivities.containsKey(mapping.getEnrolmentId())) {
lastActivity = lastActivities.get(mapping.getEnrolmentId());
}
EnrolmentInfo.Status newStatus = this.determineDeviceStatus(mapping, lastActivity);
if (newStatus != mapping.getDeviceStatus()) {
enrolmentInfo = new EnrolmentInfo();
enrolmentInfo.setId(mapping.getEnrolmentId());
@ -93,19 +99,31 @@ public class DeviceStatusMonitoringTask implements Task {
}
}
private EnrolmentInfo.Status determineDeviceStatus(OperationEnrolmentMapping opMapping) {
long lastContactedBefore = (System.currentTimeMillis()/1000) - opMapping.getCreatedTime();
EnrolmentInfo.Status status = opMapping.getDeviceStatus();
if (lastContactedBefore >= this.deviceStatusTaskPluginConfig.getIdleTimeToMarkInactive()) {
status = EnrolmentInfo.Status.INACTIVE;
} else if (lastContactedBefore >= this.deviceStatusTaskPluginConfig.getIdleTimeToMarkUnreachable()) {
status = EnrolmentInfo.Status.UNREACHABLE;
private EnrolmentInfo.Status determineDeviceStatus(OperationEnrolmentMapping opMapping, long lastActivityTime) {
long lastPendingOpBefore = (System.currentTimeMillis()/1000) - opMapping.getCreatedTime();
EnrolmentInfo.Status newStatus = null;
if (lastPendingOpBefore >= this.deviceStatusTaskPluginConfig.getIdleTimeToMarkInactive()) {
newStatus = EnrolmentInfo.Status.INACTIVE;
} else if (lastPendingOpBefore >= this.deviceStatusTaskPluginConfig.getIdleTimeToMarkUnreachable()) {
newStatus = EnrolmentInfo.Status.UNREACHABLE;
}
return status;
if (lastActivityTime != -1) {
long lastActivityBefore = (System.currentTimeMillis()/1000) - lastActivityTime;
if (lastActivityBefore < lastPendingOpBefore) {
return opMapping.getDeviceStatus();
}
}
return newStatus;
}
private long getTimeWindow() {
return (System.currentTimeMillis()/1000) - this.deviceStatusTaskPluginConfig.getIdleTimeToMarkInactive();
private long getMinTimeWindow() {
return (System.currentTimeMillis()/1000) - this.deviceStatusTaskPluginConfig.getIdleTimeToMarkUnreachable();
}
private long getMaxTimeWindow() {
//Need to consider the frequency of the task as well
return (System.currentTimeMillis()/1000) - this.deviceStatusTaskPluginConfig.getIdleTimeToMarkInactive() -
this.deviceStatusTaskPluginConfig.getFrequency();
}
private boolean updateDeviceStatus(List<EnrolmentInfo> enrolmentInfos) throws
@ -133,7 +151,8 @@ public class DeviceStatusMonitoringTask implements Task {
try {
OperationManagementDAOFactory.openConnection();
operationEnrolmentMappings = OperationManagementDAOFactory.
getOperationMappingDAO().getFirstPendingOperationMappingsForActiveEnrolments(this.getTimeWindow());
getOperationMappingDAO().getFirstPendingOperationMappingsForActiveEnrolments(this.getMinTimeWindow(),
this.getMaxTimeWindow(), this.deviceTypeId);
} catch (SQLException e) {
throw new DeviceStatusTaskException("Error occurred while getting Enrolment operation mappings for " +
"determining device status of deviceType '" + deviceType + "'", e);
@ -145,4 +164,23 @@ public class DeviceStatusMonitoringTask implements Task {
}
return operationEnrolmentMappings;
}
private Map<Integer, Long> getLastDeviceActivities() throws DeviceStatusTaskException {
Map<Integer, Long> lastActivities = null;
try {
OperationManagementDAOFactory.openConnection();
lastActivities = OperationManagementDAOFactory.
getOperationMappingDAO().getLastConnectedTimeForActiveEnrolments(this.getMaxTimeWindow(),
this.deviceTypeId);
} catch (SQLException e) {
throw new DeviceStatusTaskException("Error occurred while getting last activities for " +
"determining device status of deviceType '" + deviceType + "'", e);
} catch (OperationManagementDAOException e) {
throw new DeviceStatusTaskException("Error occurred obtaining a DB connection for fetching " +
"last activities for status monitoring of deviceType '" + deviceType + "'", e);
} finally {
OperationManagementDAOFactory.closeConnection();
}
return lastActivities;
}
}

@ -21,8 +21,8 @@ package org.wso2.carbon.device.mgt.core.status.task.impl;
import com.google.gson.Gson;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.DeviceStatusTaskPluginConfig;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.status.task.DeviceStatusTaskException;
import org.wso2.carbon.device.mgt.core.status.task.DeviceStatusTaskManagerService;
@ -43,20 +43,21 @@ public class DeviceStatusTaskManagerServiceImpl implements DeviceStatusTaskManag
public static final String DEVICE_STATUS_MONITORING_TASK_TYPE = "DEVICE_STATUS_MONITORING";
static final String DEVICE_TYPE = "DEVICE_TYPE";
static final String DEVICE_TYPE_ID = "DEVICE_TYPE_ID";
static final String DEVICE_STATUS_TASK_CONFIG = "DEVICE_STATUS_TASK_CONFIG";
private static String TASK_CLASS = DeviceStatusMonitoringTask.class.getName();
@Override
public void startTask(String deviceType, DeviceStatusTaskPluginConfig deviceStatusTaskConfig)
public void startTask(DeviceType deviceType, DeviceStatusTaskPluginConfig deviceStatusTaskConfig)
throws DeviceStatusTaskException {
log.info("Device Status monitoring Task adding for " + deviceType);
log.info("Device Status monitoring Task adding for " + deviceType.getName());
try {
TaskService taskService = DeviceManagementDataHolder.getInstance().getTaskService();
taskService.registerTaskType(DEVICE_STATUS_MONITORING_TASK_TYPE);
if (log.isDebugEnabled()) {
log.debug("Device Status monitoring task is started for the device type " + deviceType);
log.debug("Device Status monitoring task is started for the device type " + deviceType.getName());
log.debug(
"Device Status monitoring task is at frequency of : " + deviceStatusTaskConfig.getFrequency());
}
@ -73,48 +74,49 @@ public class DeviceStatusTaskManagerServiceImpl implements DeviceStatusTaskManag
Map<String, String> properties = new HashMap<>();
properties.put(DEVICE_TYPE, deviceType);
properties.put(DEVICE_TYPE, deviceType.getName());
properties.put(DEVICE_TYPE_ID, deviceType.getId() + "");
properties.put(DEVICE_STATUS_TASK_CONFIG, deviceStatusTaskConfigs);
String taskName = DEVICE_STATUS_MONITORING_TASK_TYPE + "_" + deviceType;
String taskName = DEVICE_STATUS_MONITORING_TASK_TYPE + "_" + deviceType.getName() + "_" + deviceType.getId();
if (!taskManager.isTaskScheduled(deviceType)) {
if (!taskManager.isTaskScheduled(taskName)) {
TaskInfo taskInfo = new TaskInfo(taskName, TASK_CLASS, properties, triggerInfo);
taskManager.registerTask(taskInfo);
taskManager.rescheduleTask(taskInfo.getName());
} else {
throw new DeviceStatusTaskException(
"Device Status monitoring task is already started for this device-type : " + deviceType);
"Device Status monitoring task is already started for this device-type : " + deviceType.getName());
}
} catch (TaskException e) {
throw new DeviceStatusTaskException("Error occurred while creating the Device Status monitoring task " +
"for device-type : " + deviceType, e);
"for device-type : " + deviceType.getName(), e);
}
}
@Override
public void stopTask(String deviceType, DeviceStatusTaskPluginConfig deviceStatusTaskConfig)
public void stopTask(DeviceType deviceType, DeviceStatusTaskPluginConfig deviceStatusTaskConfig)
throws DeviceStatusTaskException {
try {
TaskService taskService = DeviceManagementDataHolder.getInstance().getTaskService();
String taskName = DEVICE_STATUS_MONITORING_TASK_TYPE + "_" + deviceType.getName() + "_" + deviceType.getId();
if (taskService.isServerInit()) {
TaskManager taskManager = taskService.getTaskManager(DEVICE_STATUS_MONITORING_TASK_TYPE);
taskManager.deleteTask(deviceType);
taskManager.deleteTask(taskName);
}
} catch (TaskException e) {
throw new DeviceStatusTaskException("Error occurred while deleting the Device Status monitoring task " +
"for tenant " + getTenantId(), e);
"for device-type : " + deviceType.getName(), e);
}
}
@Override
public void updateTask(String deviceType, DeviceStatusTaskPluginConfig deviceStatusTaskConfig)
public void updateTask(DeviceType deviceType, DeviceStatusTaskPluginConfig deviceStatusTaskConfig)
throws DeviceStatusTaskException {
int tenantId = getTenantId();
try {
TaskService taskService = DeviceManagementDataHolder.getInstance().getTaskService();
TaskManager taskManager = taskService.getTaskManager(DEVICE_STATUS_MONITORING_TASK_TYPE);
String taskName = DEVICE_STATUS_MONITORING_TASK_TYPE + "_" + deviceType + "_" + String.valueOf(tenantId);
String taskName = DEVICE_STATUS_MONITORING_TASK_TYPE + "_" + deviceType + "_" + deviceType.getId();
if (taskManager.isTaskScheduled(taskName)) {
taskManager.deleteTask(taskName);
TaskInfo.TriggerInfo triggerInfo = new TaskInfo.TriggerInfo();
@ -122,44 +124,40 @@ public class DeviceStatusTaskManagerServiceImpl implements DeviceStatusTaskManag
triggerInfo.setRepeatCount(-1);
Map<String, String> properties = new HashMap<>();
properties.put(DEVICE_TYPE, deviceType);
properties.put(DEVICE_TYPE, deviceType.getName());
properties.put(DEVICE_TYPE_ID, deviceType.getId() + "");
Gson gson = new Gson();
String deviceStatusTaskConfigs = gson.toJson(deviceStatusTaskConfig);
properties.put(DEVICE_STATUS_TASK_CONFIG, deviceStatusTaskConfigs);
TaskInfo taskInfo = new TaskInfo(deviceType, TASK_CLASS, properties, triggerInfo);
TaskInfo taskInfo = new TaskInfo(taskName, TASK_CLASS, properties, triggerInfo);
taskManager.registerTask(taskInfo);
taskManager.rescheduleTask(taskInfo.getName());
} else {
throw new DeviceStatusTaskException(
"Device details retrieving Device Status monitoring task has not been started for this tenant " +
tenantId + ". Please start the task first.");
"Device details retrieving Device Status monitoring task has not been started for this device-type " +
deviceType.getName() + ". Please start the task first.");
}
} catch (TaskException e) {
throw new DeviceStatusTaskException("Error occurred while updating the Device Status monitoring task for tenant " + tenantId,
e);
throw new DeviceStatusTaskException("Error occurred while updating the Device Status monitoring " +
"task for device-type : " + deviceType.getName(), e);
}
}
@Override
public boolean isTaskScheduled(String deviceType) throws DeviceStatusTaskException {
int tenantId = getTenantId();
String taskName = DEVICE_STATUS_MONITORING_TASK_TYPE + "_" + deviceType + "_" + String.valueOf(tenantId);
public boolean isTaskScheduled(DeviceType deviceType) throws DeviceStatusTaskException {
String taskName = DEVICE_STATUS_MONITORING_TASK_TYPE + "_" + deviceType.getName() + "_" + deviceType.getId();
TaskService taskService = DeviceManagementDataHolder.getInstance().getTaskService();
TaskManager taskManager;
try {
taskManager = taskService.getTaskManager(DEVICE_STATUS_MONITORING_TASK_TYPE);
return taskManager.isTaskScheduled(taskName);
} catch (TaskException e) {
throw new DeviceStatusTaskException("Error occurred while checking Device Status monitoring task for tenant " +
tenantId, e);
throw new DeviceStatusTaskException("Error occurred while checking Device Status monitoring task for device-type : " +
deviceType.getName(), e);
}
}
private int getTenantId() {
return PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
}
}

@ -48,6 +48,7 @@ import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.sql.SQLException;
import java.util.*;
@ -136,6 +137,31 @@ public final class DeviceManagerUtil {
return status;
}
/**
* Get the DeviceType information from Database.
*
* @param typeName device type
* @param tenantId provider tenant Id
* @return DeviceType which contains info about the device-type.
*/
public static DeviceType getDeviceType(String typeName, int tenantId) throws DeviceManagementException {
DeviceType deviceType = null;
try {
DeviceManagementDAOFactory.openConnection();
DeviceTypeDAO deviceTypeDAO = DeviceManagementDAOFactory.getDeviceTypeDAO();
deviceType = deviceTypeDAO.getDeviceType(typeName, tenantId);
} catch (DeviceManagementDAOException e) {
throw new DeviceManagementException("Error occurred while fetching the device type '"
+ typeName + "'", e);
} catch (SQLException e) {
throw new DeviceManagementException("Error occurred while fetching the device type '"
+ typeName + "'", e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}
return deviceType;
}
/**
* Un-registers an existing device type from the device management metadata repository.
*

Loading…
Cancel
Save