Handle NotNow response from device

4.x.x
Milan Perera 6 years ago
parent 806ac13c39
commit b256d55847

@ -37,7 +37,7 @@ public class Operation implements Serializable {
} }
public enum Status { public enum Status {
IN_PROGRESS, PENDING, COMPLETED, ERROR, REPEATED IN_PROGRESS, PENDING, COMPLETED, ERROR, REPEATED, NOTNOW
} }
public enum Control { public enum Control {

@ -76,6 +76,9 @@ public interface OperationManager {
*/ */
List<? extends Operation> getPendingOperations(DeviceIdentifier deviceId) throws OperationManagementException; List<? extends Operation> getPendingOperations(DeviceIdentifier deviceId) throws OperationManagementException;
Operation getNextPendingOperation(DeviceIdentifier deviceId, long notNowOperationFrequency)
throws OperationManagementException;
Operation getNextPendingOperation(DeviceIdentifier deviceId) throws OperationManagementException; Operation getNextPendingOperation(DeviceIdentifier deviceId) throws OperationManagementException;
void updateOperation(DeviceIdentifier deviceId, Operation operation) throws OperationManagementException; void updateOperation(DeviceIdentifier deviceId, Operation operation) throws OperationManagementException;

@ -30,7 +30,7 @@ public class Operation implements Serializable {
} }
public enum Status { public enum Status {
IN_PROGRESS, PENDING, COMPLETED, ERROR, REPEATED IN_PROGRESS, PENDING, COMPLETED, ERROR, REPEATED, NOTNOW
} }
public enum Control { public enum Control {

@ -64,6 +64,7 @@ import org.wso2.carbon.device.mgt.core.task.impl.DeviceTaskManagerImpl;
import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil; import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
@ -537,6 +538,13 @@ public class OperationManagerImpl implements OperationManager {
@Override @Override
public Operation getNextPendingOperation(DeviceIdentifier deviceId) throws OperationManagementException { public Operation getNextPendingOperation(DeviceIdentifier deviceId) throws OperationManagementException {
// setting notNowOperationFrequency to -1 to avoid picking notnow operations
return this.getNextPendingOperation(deviceId, -1);
}
@Override
public Operation getNextPendingOperation(DeviceIdentifier deviceId, long notNowOperationFrequency)
throws OperationManagementException {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("device identifier id:[" + deviceId.getId() + "] type:[" + deviceId.getType() + "]"); log.debug("device identifier id:[" + deviceId.getId() + "] type:[" + deviceId.getType() + "]");
} }
@ -565,8 +573,32 @@ public class OperationManagerImpl implements OperationManager {
try { try {
OperationManagementDAOFactory.openConnection(); OperationManagementDAOFactory.openConnection();
org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation dtoOperation = operationDAO.getNextOperation( org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation dtoOperation = null;
enrolmentInfo.getId());
// check whether notnow is set
if (notNowOperationFrequency > 0) {
// retrieve Notnow operations
dtoOperation = operationDAO.getNextOperation(enrolmentInfo.getId(),
org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.Status.NOTNOW);
}
if (dtoOperation != null) {
long currentTime = Calendar.getInstance().getTime().getTime();
log.info("Current timestamp:" + currentTime);
long updatedTime = Timestamp.valueOf(dtoOperation.getReceivedTimeStamp()).getTime();
log.info("Updated timestamp: " + updatedTime);
// check if notnow frequency is met and set next pending operation if not, otherwise let notnow
// operation to proceed
if ((currentTime - updatedTime) < notNowOperationFrequency) {
dtoOperation = operationDAO.getNextOperation(enrolmentInfo.getId(),
org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.Status.PENDING);
}
} else {
dtoOperation = operationDAO.getNextOperation(enrolmentInfo.getId(),
org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.Status.PENDING);
}
if (dtoOperation != null) { if (dtoOperation != null) {
if (org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.Type.COMMAND.equals(dtoOperation.getType() if (org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation.Type.COMMAND.equals(dtoOperation.getType()
)) { )) {

@ -46,7 +46,7 @@ public interface OperationDAO {
List<? extends Operation> getOperationsForDevice(int enrolmentId, PaginationRequest request) throws OperationManagementDAOException; List<? extends Operation> getOperationsForDevice(int enrolmentId, PaginationRequest request) throws OperationManagementDAOException;
Operation getNextOperation(int enrolmentId) throws OperationManagementDAOException; Operation getNextOperation(int enrolmentId, Operation.Status status) throws OperationManagementDAOException;
boolean updateOperationStatus(int enrolmentId, int operationId,Operation.Status status) boolean updateOperationStatus(int enrolmentId, int operationId,Operation.Status status)
throws OperationManagementDAOException; throws OperationManagementDAOException;

@ -1372,7 +1372,7 @@ public class GenericOperationDAOImpl implements OperationDAO {
} }
@Override @Override
public Operation getNextOperation(int enrolmentId) throws OperationManagementDAOException { public Operation getNextOperation(int enrolmentId, Operation.Status status) throws OperationManagementDAOException {
PreparedStatement stmt = null; PreparedStatement stmt = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
@ -1383,7 +1383,7 @@ public class GenericOperationDAOImpl implements OperationDAO {
"WHERE dm.ENROLMENT_ID = ? AND dm.STATUS = ?) om ON o.ID = om.OPERATION_ID " + "WHERE dm.ENROLMENT_ID = ? AND dm.STATUS = ?) om ON o.ID = om.OPERATION_ID " +
"ORDER BY om.UPDATED_TIMESTAMP ASC, om.ID ASC LIMIT 1"); "ORDER BY om.UPDATED_TIMESTAMP ASC, om.ID ASC LIMIT 1");
stmt.setInt(1, enrolmentId); stmt.setInt(1, enrolmentId);
stmt.setString(2, Operation.Status.PENDING.toString()); stmt.setString(2, status.toString());
rs = stmt.executeQuery(); rs = stmt.executeQuery();
Operation operation = null; Operation operation = null;
@ -1392,11 +1392,7 @@ public class GenericOperationDAOImpl implements OperationDAO {
operation.setType(OperationDAOUtil.getType(rs.getString("TYPE"))); operation.setType(OperationDAOUtil.getType(rs.getString("TYPE")));
operation.setId(rs.getInt("ID")); operation.setId(rs.getInt("ID"));
operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString()); operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString());
// if (rs.getTimestamp("RECEIVED_TIMESTAMP") == null) {
// operation.setReceivedTimeStamp("");
// } else {
// operation.setReceivedTimeStamp(rs.getTimestamp("RECEIVED_TIMESTAMP").toString());
// }
if (rs.getLong("UPDATED_TIMESTAMP") == 0) { if (rs.getLong("UPDATED_TIMESTAMP") == 0) {
operation.setReceivedTimeStamp(""); operation.setReceivedTimeStamp("");
} else { } else {

@ -551,6 +551,9 @@ public interface DeviceManagementProviderService {
Operation getNextPendingOperation(DeviceIdentifier deviceId) throws OperationManagementException; Operation getNextPendingOperation(DeviceIdentifier deviceId) throws OperationManagementException;
Operation getNextPendingOperation(DeviceIdentifier deviceId, long notNowOperationFrequency)
throws OperationManagementException;
void updateOperation(DeviceIdentifier deviceId, Operation operation) throws OperationManagementException; void updateOperation(DeviceIdentifier deviceId, Operation operation) throws OperationManagementException;
boolean updateProperties(DeviceIdentifier deviceId, List<Device.Property> properties) throws DeviceManagementException; boolean updateProperties(DeviceIdentifier deviceId, List<Device.Property> properties) throws DeviceManagementException;

@ -1445,8 +1445,15 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
@Override @Override
public Operation getNextPendingOperation(DeviceIdentifier deviceId) throws OperationManagementException { public Operation getNextPendingOperation(DeviceIdentifier deviceId) throws OperationManagementException {
// // setting notNowOperationFrequency to -1 to avoid picking notnow operations
return pluginRepository.getOperationManager(deviceId.getType(), this.getTenantId()) return pluginRepository.getOperationManager(deviceId.getType(), this.getTenantId())
.getNextPendingOperation(deviceId); .getNextPendingOperation(deviceId, -1);
}
public Operation getNextPendingOperation(DeviceIdentifier deviceId, long notNowOperationFrequency)
throws OperationManagementException {
return pluginRepository.getOperationManager(deviceId.getType(), this.getTenantId())
.getNextPendingOperation(deviceId, notNowOperationFrequency);
} }
@Override @Override

@ -18,6 +18,8 @@
package org.wso2.carbon.device.mgt.core.operation; package org.wso2.carbon.device.mgt.core.operation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.powermock.api.mockito.PowerMockito; import org.powermock.api.mockito.PowerMockito;
import org.testng.Assert; import org.testng.Assert;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
@ -81,6 +83,8 @@ public class OperationManagementTests extends BaseDeviceManagementTest {
private Activity commandActivity; private Activity commandActivity;
private long commandActivityBeforeUpdatedTimestamp; private long commandActivityBeforeUpdatedTimestamp;
private static Log log = LogFactory.getLog(OperationManagementTests.class);
@BeforeClass @BeforeClass
public void init() throws Exception { public void init() throws Exception {
for (int i = 0; i < NO_OF_DEVICES; i++) { for (int i = 0; i < NO_OF_DEVICES; i++) {
@ -363,6 +367,35 @@ public class OperationManagementTests extends BaseDeviceManagementTest {
Assert.assertTrue(operation.getType().equals(Operation.Type.POLICY)); Assert.assertTrue(operation.getType().equals(Operation.Type.POLICY));
} }
@Test(dependsOnMethods = "getNextPendingOperation")
public void getNextNotNowOperation() throws OperationManagementException {
//This is required to introduce a delay for the update operation of the device.
try {
Thread.sleep(2000);
} catch (InterruptedException ignored) {
}
DeviceIdentifier deviceIdentifier = this.deviceIds.get(0);
Operation operation = this.operationMgtService.getNextPendingOperation(deviceIdentifier);
int operationId = operation.getId();
operation.setStatus(Operation.Status.NOTNOW);
operation.setOperationResponse("The operation is successfully completed");
this.operationMgtService.updateOperation(deviceIdentifier, operation);
//This is required to introduce a delay for the update operation of the device.
try {
Thread.sleep(2000);
} catch (InterruptedException ignored) {
}
operation = this.operationMgtService.getNextPendingOperation(deviceIdentifier);
Assert.assertTrue(operation.getId() != operationId, "Fetched the incorrect operation");
log.info("Waiting 10000ms for NotNow operation to be fetched");
try {
Thread.sleep(10000);
} catch (InterruptedException ignored) {
}
operation = this.operationMgtService.getNextPendingOperation(deviceIdentifier, 7000);
Assert.assertTrue(operation.getId() == operationId, "Fetched the incorrect NotNow operation");
}
@Test(dependsOnMethods = "updateOperation", expectedExceptions = OperationManagementException.class) @Test(dependsOnMethods = "updateOperation", expectedExceptions = OperationManagementException.class)
public void getNextPendingOperationAsNonAdmin() throws OperationManagementException { public void getNextPendingOperationAsNonAdmin() throws OperationManagementException {
startTenantFlowAsNonAdmin(); startTenantFlowAsNonAdmin();
@ -406,7 +439,7 @@ public class OperationManagementTests extends BaseDeviceManagementTest {
DeviceIdentifier deviceIdentifier = this.deviceIds.get(0); DeviceIdentifier deviceIdentifier = this.deviceIds.get(0);
List operation = this.operationMgtService.getOperationsByDeviceAndStatus(deviceIdentifier, List operation = this.operationMgtService.getOperationsByDeviceAndStatus(deviceIdentifier,
Operation.Status.PENDING); Operation.Status.PENDING);
Assert.assertEquals(operation.size(), 3); Assert.assertEquals(operation.size(), 2);
} }
@Test(dependsOnMethods = "getOperationByDeviceAndOperationId", expectedExceptions = OperationManagementException.class) @Test(dependsOnMethods = "getOperationByDeviceAndOperationId", expectedExceptions = OperationManagementException.class)
@ -479,8 +512,8 @@ public class OperationManagementTests extends BaseDeviceManagementTest {
public void getActivityCountUpdatedAfter() throws OperationManagementException, ParseException { public void getActivityCountUpdatedAfter() throws OperationManagementException, ParseException {
int activityCount = this.operationMgtService.getActivityCountUpdatedAfter int activityCount = this.operationMgtService.getActivityCountUpdatedAfter
(this.commandActivityBeforeUpdatedTimestamp / 1000); (this.commandActivityBeforeUpdatedTimestamp / 1000);
Assert.assertTrue(activityCount == 1, Assert.assertTrue(activityCount == 2,
"The activities updated after the created should be 1"); "The activities updated after the created should be 2");
} }
@Test @Test

Loading…
Cancel
Save