Fix for sycning status update in Android

4.x.x
inoshperera 4 years ago
parent b98d787367
commit 8effa09a8f

@ -0,0 +1,57 @@
/*
* Copyright (c) 2021, 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 org.wso2.carbon.device.mgt.common.device.details;
import org.wso2.carbon.device.mgt.common.Device;
import java.io.Serializable;
public class DeviceMonitoringData implements Serializable {
private static final long serialVersionUID = 2448141793L;
long lastUpdatedTime;
Device device;
int tenantId;
public int getTenantId() {
return tenantId;
}
public void setTenantId(int tenantId) {
this.tenantId = tenantId;
}
public Device getDevice() {
return device;
}
public void setDevice(Device device) {
this.device = device;
}
public long getLastUpdatedTime() {
return lastUpdatedTime;
}
public void setLastUpdatedTime(long lastUpdatedTime) {
this.lastUpdatedTime = lastUpdatedTime;
}
}

@ -45,6 +45,7 @@ import org.wso2.carbon.device.mgt.common.Count;
import org.wso2.carbon.device.mgt.common.configuration.mgt.DevicePropertyInfo; import org.wso2.carbon.device.mgt.common.configuration.mgt.DevicePropertyInfo;
import org.wso2.carbon.device.mgt.common.device.details.DeviceData; import org.wso2.carbon.device.mgt.common.device.details.DeviceData;
import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistorySnapshot; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistorySnapshot;
import org.wso2.carbon.device.mgt.common.device.details.DeviceMonitoringData;
import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.geo.GeoCluster; import org.wso2.carbon.device.mgt.core.geo.GeoCluster;
import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate;
@ -682,6 +683,19 @@ public interface DeviceDAO {
int getCountOfDeviceExpiredByOSVersion(String deviceType, Long osValue, int tenantId) int getCountOfDeviceExpiredByOSVersion(String deviceType, Long osValue, int tenantId)
throws DeviceManagementDAOException; throws DeviceManagementDAOException;
/**
* Get All devices for monitoring
* @param deviceTypeId device type identifier
* @param deviceTypeName name of the type. (android, ios ...)
* @param activeServerCount Number of available servers
* @param serverHashIndex server index number
* @return device object
* @throws DeviceManagementDAOException
*/
List<DeviceMonitoringData> getAllDevicesForMonitoring(int deviceTypeId, String deviceTypeName,
int activeServerCount, int serverHashIndex)
throws DeviceManagementDAOException;
/** /**
* Get a paginated list of devices filtered by given encryption status * Get a paginated list of devices filtered by given encryption status
* *

@ -47,6 +47,7 @@ import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.configuration.mgt.DevicePropertyInfo; import org.wso2.carbon.device.mgt.common.configuration.mgt.DevicePropertyInfo;
import org.wso2.carbon.device.mgt.common.device.details.DeviceData; import org.wso2.carbon.device.mgt.common.device.details.DeviceData;
import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistorySnapshot; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistorySnapshot;
import org.wso2.carbon.device.mgt.common.device.details.DeviceMonitoringData;
import org.wso2.carbon.device.mgt.core.dao.DeviceDAO; import org.wso2.carbon.device.mgt.core.dao.DeviceDAO;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
@ -2784,4 +2785,56 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
} }
return deviceCount; return deviceCount;
} }
@Override
public List<DeviceMonitoringData> getAllDevicesForMonitoring(
int deviceTypeId, String deviceTypeName, int activeServerCount, int serverHashIndex)
throws DeviceManagementDAOException {
List<DeviceMonitoringData> devices = new ArrayList<>();
String sql = "SELECT D.ID AS DEVICE_ID," +
" D.NAME AS DEVICE_NAME, " +
" D.DESCRIPTION AS DESCRIPTION," +
" D.DEVICE_IDENTIFICATION, " +
" D.LAST_UPDATED_TIMESTAMP, " +
" D.TENANT_ID, " +
" E.ENROLMENT_ID, " +
" EN.OWNER, " +
" EN.OWNERSHIP, " +
" EN.IS_TRANSFERRED, " +
" EN.DATE_OF_ENROLMENT, " +
" EN.DATE_OF_LAST_UPDATE, " +
" EN.STATUS " +
"FROM DM_DEVICE D, DM_ENROLMENT EN," +
" (SELECT DEVICE_ID, MAX(ID) AS ENROLMENT_ID" +
" FROM DM_ENROLMENT" +
" WHERE STATUS IN ('ACTIVE', 'UNREACHABLE') " +
" GROUP BY DEVICE_ID) E" +
" WHERE D.ID = E.DEVICE_ID AND E.ENROLMENT_ID = EN.ID AND D.DEVICE_TYPE_ID = ?";
if (activeServerCount > 0) {
sql += " AND MOD(D.ID, ?) = ?";
}
try {
Connection conn = this.getConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, deviceTypeId);
if (activeServerCount > 0) {
stmt.setInt(2, activeServerCount);
stmt.setInt(3, serverHashIndex);
}
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
devices.add(DeviceManagementDAOUtil.loadDevice(rs, deviceTypeName));
}
return devices;
}
}
} catch (SQLException e) {
String msg = "Error occurred while retrieving devices";
log.error(msg, e);
throw new DeviceManagementDAOException(msg, e);
}
}
} }

@ -26,6 +26,7 @@ import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo; import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo;
import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistorySnapshot; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistorySnapshot;
import org.wso2.carbon.device.mgt.common.device.details.DeviceMonitoringData;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
import org.wso2.carbon.device.mgt.core.dto.DeviceType; 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.DeviceManagementDataHolder;
@ -196,6 +197,23 @@ public final class DeviceManagementDAOUtil {
return device; return device;
} }
public static DeviceMonitoringData loadDevice(ResultSet rs, String deviceTypeName) throws SQLException {
Device device = new Device();
device.setId(rs.getInt("DEVICE_ID"));
device.setName(rs.getString("DEVICE_NAME"));
device.setDescription(rs.getString("DESCRIPTION"));
device.setType(deviceTypeName);
device.setDeviceIdentifier(rs.getString("DEVICE_IDENTIFICATION"));
device.setEnrolmentInfo(loadEnrolment(rs));
DeviceMonitoringData deviceMonitoringData = new DeviceMonitoringData();
deviceMonitoringData.setLastUpdatedTime(rs
.getTimestamp("LAST_UPDATED_TIMESTAMP").getTime());
deviceMonitoringData.setTenantId(rs.getInt("TENANT_ID"));
deviceMonitoringData.setDevice(device);
return deviceMonitoringData;
}
//This method will retrieve most appropriate device information when there are multiple device enrollments for //This method will retrieve most appropriate device information when there are multiple device enrollments for
//a single device. Here we'll consider only active status. //a single device. Here we'll consider only active status.
public static Device loadActiveDevice(ResultSet rs, boolean deviceInfoIncluded) throws SQLException { public static Device loadActiveDevice(ResultSet rs, boolean deviceInfoIncluded) throws SQLException {

@ -19,13 +19,10 @@
package org.wso2.carbon.device.mgt.core.operation.mgt.dao; package org.wso2.carbon.device.mgt.core.operation.mgt.dao;
import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation; 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.OperationMapping;
import java.util.List; import java.util.List;
import java.util.Map;
public interface OperationMappingDAO { public interface OperationMappingDAO {
@ -41,63 +38,5 @@ public interface OperationMappingDAO {
void updateOperationMapping(List<OperationMapping> operationMappingList) throws void updateOperationMapping(List<OperationMapping> operationMappingList) throws
OperationManagementDAOException; OperationManagementDAOException;
/**
* 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 first pending/repeated operation available for each active enrolment of given device-type
* in a task partitioned execution scenario
* where the operation was created after the given timestamp.
*
* @param minDuration
* @param maxDuration
* @param deviceTypeId
* @param activeServerCount
* @param serverHashIndex
* @return
*/
List<OperationEnrolmentMapping> getFirstPendingOperationMappingsForActiveEnrolments(long minDuration,
long maxDuration, int deviceTypeId,
int activeServerCount, int serverHashIndex)
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 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
*/
Map<Integer, Long> getLastConnectedTimeForActiveEnrolments(long timeStamp, int deviceTypeId)
throws OperationManagementDAOException;
/**
* This method returns the timestamp of last completed Operation for each active enrolment of given device-type
* in a task partitioned execution scenario
* where the operation was completed after the given timestamp.
*
* @param timeStamp
* @param deviceTypeId
* @param activeServerCount
* @param serverHashIndex
* @return
*/
Map<Integer, Long> getLastConnectedTimeForActiveEnrolments(long timeStamp, int deviceTypeId, int activeServerCount, int serverHashIndex)
throws OperationManagementDAOException;
} }

@ -194,154 +194,6 @@ public class OperationMappingDAOImpl implements OperationMappingDAO {
} }
} }
@Override
public List<OperationEnrolmentMapping> getFirstPendingOperationMappingsForActiveEnrolments(long minDuration,
long maxDuration, int deviceTypeId) throws OperationManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
List<OperationEnrolmentMapping> enrolmentOperationMappingList;
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 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 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," +
" D.DEVICE_IDENTIFICATION, E.STATUS, E.TENANT_ID";
stmt = conn.prepareStatement(sql);
stmt.setLong(1, maxDuration);
stmt.setLong(2, minDuration);
stmt.setInt(3, deviceTypeId);
rs = stmt.executeQuery();
enrolmentOperationMappingList = new ArrayList<>();
while (rs.next()) {
OperationEnrolmentMapping enrolmentOperationMapping = this.getEnrolmentOpMapping(rs);
enrolmentOperationMappingList.add(enrolmentOperationMapping);
}
} catch (SQLException e) {
throw new OperationManagementDAOException("Error occurred while fetching pending operation mappings for " +
"active devices of type '" + deviceTypeId + "'", e);
} finally {
OperationManagementDAOUtil.cleanupResources(stmt, rs);
}
return enrolmentOperationMappingList;
}
@Override
public List<OperationEnrolmentMapping> getFirstPendingOperationMappingsForActiveEnrolments(
long minDuration,
long maxDuration, int deviceTypeId,
int activeServerCount, int serverHashIndex) throws OperationManagementDAOException {
List<OperationEnrolmentMapping> enrolmentOperationMappingList;
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 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 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 = ? AND MOD(D.ID, ?) = ? GROUP BY ENROLMENT_ID," +
" D.DEVICE_IDENTIFICATION, E.STATUS, E.TENANT_ID";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setLong(1, maxDuration);
stmt.setLong(2, minDuration);
stmt.setInt(3, deviceTypeId);
stmt.setInt(4, activeServerCount);
stmt.setInt(5, serverHashIndex);
try (ResultSet rs = stmt.executeQuery()) {
enrolmentOperationMappingList = new ArrayList<>();
while (rs.next()) {
OperationEnrolmentMapping enrolmentOperationMapping = this.getEnrolmentOpMapping(rs);
enrolmentOperationMappingList.add(enrolmentOperationMapping);
}
}
}
} catch (SQLException e) {
String msg = "Error occurred while fetching pending operation mappings for " +
"active devices of type '" + deviceTypeId + "'";
log.error(msg, e);
throw new OperationManagementDAOException(msg, e);
}
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 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;
}
@Override
public Map<Integer, Long> getLastConnectedTimeForActiveEnrolments(long timeStamp,
int deviceTypeId,
int activeServerCount,
int serverHashIndex)
throws OperationManagementDAOException {
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 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 = ? AND MOD(D.ID, ?) = ? GROUP BY ENROLMENT_ID";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setLong(1, timeStamp);
stmt.setInt(2, deviceTypeId);
stmt.setInt(3, activeServerCount);
stmt.setInt(4, serverHashIndex);
try (ResultSet rs = stmt.executeQuery()) {
lastConnectedTimeMap = new HashMap<>();
while (rs.next()) {
lastConnectedTimeMap.put(rs.getInt("EID"), rs.getLong("LAST_CONNECTED_TIME"));
}
}
}
} catch (SQLException e) {
String msg = "Error occurred while fetching last connected time for " +
"active devices of type '" + deviceTypeId + "'";
log.error(msg, e);
throw new OperationManagementDAOException(msg, e);
}
return lastConnectedTimeMap;
}
private OperationEnrolmentMapping getEnrolmentOpMapping(ResultSet rs) throws SQLException { private OperationEnrolmentMapping getEnrolmentOpMapping(ResultSet rs) throws SQLException {
OperationEnrolmentMapping enrolmentOperationMapping = new OperationEnrolmentMapping(); OperationEnrolmentMapping enrolmentOperationMapping = new OperationEnrolmentMapping();
enrolmentOperationMapping.setEnrolmentId(rs.getInt("ENROLMENT_ID")); enrolmentOperationMapping.setEnrolmentId(rs.getInt("ENROLMENT_ID"));

@ -1405,6 +1405,12 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
log.debug(msg); log.debug(msg);
} }
return null; return null;
} else {
Device deviceFromCache = getDeviceFromCache(deviceData.getDeviceIdentifier());
if (deviceFromCache != null && device.getEnrolmentInfo() != null &&
deviceFromCache.getEnrolmentInfo().getStatus() != device.getEnrolmentInfo().getStatus()) {
this.addDeviceToCache(deviceData.getDeviceIdentifier(), device);
}
} }
} catch (DeviceManagementDAOException e) { } catch (DeviceManagementDAOException e) {
String msg = String msg =

@ -21,24 +21,18 @@ package org.wso2.carbon.device.mgt.core.status.task.impl;
import com.google.gson.Gson; import com.google.gson.Gson;
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 org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceStatusTaskPluginConfig; import org.wso2.carbon.device.mgt.common.DeviceStatusTaskPluginConfig;
import org.wso2.carbon.device.mgt.common.DynamicTaskContext; import org.wso2.carbon.device.mgt.common.DynamicTaskContext;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.device.details.DeviceMonitoringData;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException; import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException;
import org.wso2.carbon.device.mgt.core.cache.impl.DeviceCacheManagerImpl; import org.wso2.carbon.device.mgt.core.cache.impl.DeviceCacheManagerImpl;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.operation.mgt.OperationEnrolmentMapping;
import org.wso2.carbon.device.mgt.core.operation.mgt.dao.OperationManagementDAOException;
import org.wso2.carbon.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.status.task.DeviceStatusTaskException; import org.wso2.carbon.device.mgt.core.status.task.DeviceStatusTaskException;
import org.wso2.carbon.device.mgt.core.task.impl.DynamicPartitionedScheduleTask; import org.wso2.carbon.device.mgt.core.task.impl.DynamicPartitionedScheduleTask;
import org.wso2.carbon.ntask.core.Task;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
@ -67,102 +61,84 @@ public class DeviceStatusMonitoringTask extends DynamicPartitionedScheduleTask {
@Override @Override
protected void setup() { protected void setup() {
}
public List<DeviceMonitoringData> getAllDevicesForMonitoring() throws DeviceManagementException {
try {
DeviceManagementDAOFactory.openConnection();
DynamicTaskContext ctx = getTaskContext();
if (ctx != null && ctx.isPartitioningEnabled()) {
return DeviceManagementDAOFactory.getDeviceDAO()
.getAllDevicesForMonitoring(this.deviceTypeId, this.deviceType,
ctx.getActiveServerCount(), ctx.getServerHashIndex());
} else {
return DeviceManagementDAOFactory.getDeviceDAO()
.getAllDevicesForMonitoring(this.deviceTypeId, this.deviceType, -1, -1);
}
} catch (DeviceManagementDAOException e) {
String msg = "Error occurred while retrieving devices list for monitoring.";
log.error(msg, e);
throw new DeviceManagementException(msg, e);
} catch (SQLException e) {
String msg = "Error occurred while opening a connection to the data source";
log.error(msg, e);
throw new DeviceManagementException(msg, e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}
} }
@Override @Override
public void executeDynamicTask() { public void executeDynamicTask() {
List<OperationEnrolmentMapping> operationEnrolmentMappings;
List<EnrolmentInfo> enrolmentInfoTobeUpdated = new ArrayList<>();
Map<Integer, Long> lastActivities = null;
EnrolmentInfo enrolmentInfo;
DeviceIdentifier deviceIdentifier;
Device device;
try { try {
operationEnrolmentMappings = this.getOperationEnrolmentMappings(super.getTaskContext()); List<EnrolmentInfo> enrolmentInfoTobeUpdated = new ArrayList<>();
if (!operationEnrolmentMappings.isEmpty()) { List<DeviceMonitoringData> allDevicesForMonitoring = getAllDevicesForMonitoring();
lastActivities = this.getLastDeviceActivities(super.getTaskContext()); long timeMillis = System.currentTimeMillis();
} for (DeviceMonitoringData monitoringData : allDevicesForMonitoring) {
} catch (DeviceStatusTaskException e) { long lastUpdatedTime = (timeMillis - monitoringData
log.error("Error occurred while fetching OperationEnrolment mappings of deviceType '" + deviceType + "'", e); .getLastUpdatedTime()) / 1000;
return;
} EnrolmentInfo enrolmentInfo = new EnrolmentInfo();
for (OperationEnrolmentMapping mapping : operationEnrolmentMappings) { enrolmentInfo.setId(monitoringData.getDevice().getEnrolmentInfo().getId());
long lastActivity = -1; EnrolmentInfo.Status status = null;
if (lastActivities != null && lastActivities.containsKey(mapping.getEnrolmentId())) { if (lastUpdatedTime >= this.deviceStatusTaskPluginConfig
lastActivity = lastActivities.get(mapping.getEnrolmentId()); .getIdleTimeToMarkInactive()) {
} status = EnrolmentInfo.Status.INACTIVE;
EnrolmentInfo.Status newStatus = this.determineDeviceStatus(mapping, lastActivity); } else if (lastUpdatedTime >= this.deviceStatusTaskPluginConfig
if (newStatus != mapping.getDeviceStatus()) { .getIdleTimeToMarkUnreachable()) {
deviceIdentifier = new DeviceIdentifier(); status = EnrolmentInfo.Status.UNREACHABLE;
deviceIdentifier.setId(mapping.getDeviceId());
deviceIdentifier.setId(mapping.getDeviceType());
device = DeviceCacheManagerImpl.getInstance().getDeviceFromCache(deviceIdentifier, mapping.getTenantId());
if (device == null) {
enrolmentInfo = new EnrolmentInfo();
enrolmentInfo.setId(mapping.getEnrolmentId());
enrolmentInfo.setStatus(newStatus);
} else {
DeviceManagementProviderService dmps = DeviceManagementDataHolder.getInstance()
.getDeviceManagementProvider();
try {
Device updatedDevice = dmps
.getDevice(device.getDeviceIdentifier(), device.getDeviceInfo().getUpdatedTime(), true);
if (updatedDevice != null) {
device = updatedDevice;
}
} catch (DeviceManagementException e) {
log.error(
"Error occurred while getting the updated device information which has device identifier: "
+ device.getDeviceIdentifier());
}
enrolmentInfo = device.getEnrolmentInfo();
enrolmentInfo.setStatus(newStatus);
device.setEnrolmentInfo(enrolmentInfo);
DeviceCacheManagerImpl.getInstance().addDeviceToCache(deviceIdentifier, device, mapping.getTenantId());
} }
enrolmentInfoTobeUpdated.add(enrolmentInfo);
if(log.isDebugEnabled()){ if (status != null) {
log.debug("Enrollment Information updated for device ID : " + device.getDeviceIdentifier()); enrolmentInfo.setStatus(status);
enrolmentInfoTobeUpdated.add(enrolmentInfo);
DeviceIdentifier deviceIdentifier =
new DeviceIdentifier(monitoringData.getDevice()
.getDeviceIdentifier(), deviceType);
DeviceCacheManagerImpl.getInstance().removeDeviceFromCache(deviceIdentifier,
monitoringData.getTenantId());
DeviceCacheManagerImpl.getInstance().addDeviceToCache(deviceIdentifier,
monitoringData.getDevice(), monitoringData.getTenantId());
} }
} }
}
if (!enrolmentInfoTobeUpdated.isEmpty()) { if (!enrolmentInfoTobeUpdated.isEmpty()) {
try { try {
this.updateDeviceStatus(enrolmentInfoTobeUpdated); this.updateDeviceStatus(enrolmentInfoTobeUpdated);
} catch (DeviceStatusTaskException e) { } catch (DeviceStatusTaskException e) {
log.error("Error occurred while updating non-responsive device-status of devices of type '" + deviceType + "'", e); log.error("Error occurred while updating non-responsive " +
"device-status of devices of type '" + deviceType + "'", e);
}
} }
}
}
private EnrolmentInfo.Status determineDeviceStatus(OperationEnrolmentMapping opMapping, long lastActivityTime) {
long lastPendingOpBefore = (System.currentTimeMillis() / 1000) - opMapping.getCreatedTime(); } catch (DeviceManagementException e) {
EnrolmentInfo.Status newStatus = null; String msg = "Error occurred while retrieving devices list for monitoring.";
if (lastPendingOpBefore >= this.deviceStatusTaskPluginConfig.getIdleTimeToMarkInactive()) { log.error(msg, e);
newStatus = EnrolmentInfo.Status.INACTIVE;
} else if (lastPendingOpBefore >= this.deviceStatusTaskPluginConfig.getIdleTimeToMarkUnreachable()) {
newStatus = EnrolmentInfo.Status.UNREACHABLE;
}
if (lastActivityTime != -1) {
long lastActivityBefore = (System.currentTimeMillis() / 1000) - lastActivityTime;
if (lastActivityBefore < lastPendingOpBefore) {
return opMapping.getDeviceStatus();
}
} }
return newStatus;
} }
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 private boolean updateDeviceStatus(List<EnrolmentInfo> enrolmentInfos) throws
DeviceStatusTaskException { DeviceStatusTaskException {
@ -184,56 +160,4 @@ public class DeviceStatusMonitoringTask extends DynamicPartitionedScheduleTask {
return updateStatus; return updateStatus;
} }
private List<OperationEnrolmentMapping> getOperationEnrolmentMappings(DynamicTaskContext ctx) throws DeviceStatusTaskException {
List<OperationEnrolmentMapping> operationEnrolmentMappings;
try {
OperationManagementDAOFactory.openConnection();
if(ctx != null && ctx.isPartitioningEnabled()){
operationEnrolmentMappings = OperationManagementDAOFactory.
getOperationMappingDAO().getFirstPendingOperationMappingsForActiveEnrolments(this.getMinTimeWindow(),
this.getMaxTimeWindow(), this.deviceTypeId,
ctx.getActiveServerCount(), ctx.getServerHashIndex());
} else {
operationEnrolmentMappings = OperationManagementDAOFactory.
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);
} catch (OperationManagementDAOException e) {
throw new DeviceStatusTaskException("Error occurred obtaining a DB connection for fetching " +
"operation-enrolment mappings for status monitoring of deviceType '" + deviceType + "'", e);
} finally {
OperationManagementDAOFactory.closeConnection();
}
return operationEnrolmentMappings;
}
private Map<Integer, Long> getLastDeviceActivities(DynamicTaskContext ctx) throws DeviceStatusTaskException {
Map<Integer, Long> lastActivities;
try {
OperationManagementDAOFactory.openConnection();
if(ctx != null && ctx.isPartitioningEnabled()) {
lastActivities = OperationManagementDAOFactory.
getOperationMappingDAO().getLastConnectedTimeForActiveEnrolments(this.getMaxTimeWindow(),
this.deviceTypeId,
ctx.getActiveServerCount(), ctx.getServerHashIndex());
} else {
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;
}
} }

Loading…
Cancel
Save