Support user consent flow (#1293)
* Introduce user consent flow * Add permissions to confirmation management * rename from consent to confirmation * Reformat code. Remove unused imports. Change and add permission checks when configuring auto-confirmation. * Do not include null values for DDI confirmation base endpoint * fix confirmation required checkbox id * Remove unused import. Fix consume/produce type of new API's. * Change term processing to proceeding when activating user consent flow * Align formatting and extend integration test cases for DMF and DDI. * Extend DMF test cases to consider auto-confirmation * Refactor action management to fix problem of handling action status updates on closed actions. * remove unsupported validation * use new confirmation api for DMF. Extend test cases., * Remove unnecessary fields. * Extend API documentation for DDI and MGMT API. * adapt ddi api docs adoc file * Fixed the duplicate migration version for db files * fix method to support confirmation * Fixed PR comments * Addressed PR comments * Fixed after merge compilation issue * Fixed after merge compilation issue * Fix failing tests in MgmtRolloutResourceTest * Fixed the permissions issue reflected by integration tests * Added back the missing line of code lost during merge * Fix the failing test on Jenkins Signed-off-by: Stanislav Trailov <stanislav.trailov@bosch.io> Signed-off-by: Dimitar Shterev <dimitar.shterev@bosch.io> Signed-off-by: Michael Herdt <Michael.Herdt@bosch.io> Signed-off-by: Shruthi Manavalli Ramanna <shruthimanavalli.ramanna@bosch-si.com> Co-authored-by: Shruthi Manavalli Ramanna <shruthimanavalli.ramanna@bosch-si.com>
This commit is contained in:
@@ -27,6 +27,7 @@ import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
|
||||
import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
|
||||
import org.eclipse.hawkbit.dmf.json.model.DmfDownloadResponse;
|
||||
import org.eclipse.hawkbit.repository.ArtifactManagement;
|
||||
import org.eclipse.hawkbit.repository.ConfirmationManagement;
|
||||
import org.eclipse.hawkbit.repository.ControllerManagement;
|
||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||
@@ -117,6 +118,9 @@ public class AmqpControllerAuthenticationTest {
|
||||
@Mock
|
||||
private ControllerManagement controllerManagement;
|
||||
|
||||
@Mock
|
||||
private ConfirmationManagement confirmationManagement;
|
||||
|
||||
@Mock
|
||||
private DdiSecurityProperties securityProperties;
|
||||
|
||||
@@ -156,7 +160,7 @@ public class AmqpControllerAuthenticationTest {
|
||||
|
||||
amqpMessageHandlerService = new AmqpMessageHandlerService(rabbitTemplate,
|
||||
mock(AmqpMessageDispatcherService.class), controllerManagement, new JpaEntityFactory(),
|
||||
systemSecurityContext, tenantConfigurationManagementMock);
|
||||
systemSecurityContext, tenantConfigurationManagementMock, confirmationManagement);
|
||||
|
||||
amqpAuthenticationMessageHandlerService = new AmqpAuthenticationMessageHandler(rabbitTemplate,
|
||||
authenticationManager, artifactManagementMock, cacheMock, hostnameResolverMock, controllerManagement,
|
||||
|
||||
@@ -36,16 +36,19 @@ import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
|
||||
import org.eclipse.hawkbit.dmf.json.model.DmfActionStatus;
|
||||
import org.eclipse.hawkbit.dmf.json.model.DmfActionUpdateStatus;
|
||||
import org.eclipse.hawkbit.dmf.json.model.DmfAttributeUpdate;
|
||||
import org.eclipse.hawkbit.dmf.json.model.DmfAutoConfirmation;
|
||||
import org.eclipse.hawkbit.dmf.json.model.DmfCreateThing;
|
||||
import org.eclipse.hawkbit.dmf.json.model.DmfDownloadResponse;
|
||||
import org.eclipse.hawkbit.dmf.json.model.DmfUpdateMode;
|
||||
import org.eclipse.hawkbit.repository.ArtifactManagement;
|
||||
import org.eclipse.hawkbit.repository.ConfirmationManagement;
|
||||
import org.eclipse.hawkbit.repository.ControllerManagement;
|
||||
import org.eclipse.hawkbit.repository.EntityFactory;
|
||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||
import org.eclipse.hawkbit.repository.UpdateMode;
|
||||
import org.eclipse.hawkbit.repository.builder.ActionStatusBuilder;
|
||||
import org.eclipse.hawkbit.repository.builder.ActionStatusCreate;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||
import org.eclipse.hawkbit.repository.jpa.builder.JpaActionStatusBuilder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHolder;
|
||||
@@ -110,6 +113,9 @@ public class AmqpMessageHandlerServiceTest {
|
||||
@Mock
|
||||
private ControllerManagement controllerManagementMock;
|
||||
|
||||
@Mock
|
||||
private ConfirmationManagement confirmationManagementMock;
|
||||
|
||||
@Mock
|
||||
private EntityFactory entityFactoryMock;
|
||||
|
||||
@@ -146,6 +152,12 @@ public class AmqpMessageHandlerServiceTest {
|
||||
@Captor
|
||||
private ArgumentCaptor<String> targetIdCaptor;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<String> initiatorCaptor;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<String> remarkCaptor;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<String> targetNameCaptor;
|
||||
|
||||
@@ -169,7 +181,8 @@ public class AmqpMessageHandlerServiceTest {
|
||||
final SystemSecurityContext systemSecurityContext = new SystemSecurityContext(tenantAware);
|
||||
|
||||
amqpMessageHandlerService = new AmqpMessageHandlerService(rabbitTemplate, amqpMessageDispatcherServiceMock,
|
||||
controllerManagementMock, entityFactoryMock, systemSecurityContext, tenantConfigurationManagement);
|
||||
controllerManagementMock, entityFactoryMock, systemSecurityContext, tenantConfigurationManagement,
|
||||
confirmationManagementMock);
|
||||
amqpAuthenticationMessageHandlerService = new AmqpAuthenticationMessageHandler(rabbitTemplate,
|
||||
authenticationManagerMock, artifactManagementMock, downloadIdCache, hostnameResolverMock,
|
||||
controllerManagementMock, tenantAwareMock);
|
||||
@@ -230,6 +243,16 @@ public class AmqpMessageHandlerServiceTest {
|
||||
assertThat(uriCaptor.getValue()).as("Uri is not right").hasToString("amqp://" + VIRTUAL_HOST + "/" + replyTo);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void assertInitiatorCapturedField(final String initiator) {
|
||||
assertThat(initiatorCaptor.getValue()).as("Initiator is wrong").isEqualTo(initiator);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void assertRemarkCapturedField(final String remark) {
|
||||
assertThat(remarkCaptor.getValue()).as("Remark is wrong").isEqualTo(remark);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Tests the creation of a target/thing with specified name by calling the same method that incoming RabbitMQ messages would access.")
|
||||
public void createThingWithName() {
|
||||
@@ -556,6 +579,7 @@ public class AmqpMessageHandlerServiceTest {
|
||||
final ActionStatusCreate create = mock(ActionStatusCreate.class);
|
||||
when(builder.create(22L)).thenReturn(create);
|
||||
when(create.status(any())).thenReturn(create);
|
||||
when(create.messages(any())).thenReturn(create);
|
||||
when(entityFactoryMock.actionStatus()).thenReturn(builder);
|
||||
// for the test the same action can be used
|
||||
when(controllerManagementMock.findActiveActionWithHighestWeight(any())).thenReturn(Optional.of(action));
|
||||
@@ -572,7 +596,7 @@ public class AmqpMessageHandlerServiceTest {
|
||||
final ArgumentCaptor<Target> targetCaptor = ArgumentCaptor.forClass(Target.class);
|
||||
|
||||
verify(amqpMessageDispatcherServiceMock, times(1)).sendUpdateMessageToTarget(actionPropertiesCaptor.capture(),
|
||||
targetCaptor.capture(), any(Map.class));
|
||||
targetCaptor.capture(), any(Map.class));
|
||||
final ActionProperties actionProperties = actionPropertiesCaptor.getValue();
|
||||
assertThat(actionProperties).isNotNull();
|
||||
assertThat(actionProperties.getTenant()).as("event has tenant").isEqualTo("DEFAULT");
|
||||
@@ -616,6 +640,56 @@ public class AmqpMessageHandlerServiceTest {
|
||||
.contains("Device reported status code: 12");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Tests activating auto-confirmation on a target.")
|
||||
void setAutoConfirmationStateActive() {
|
||||
final String knownThingId = "1";
|
||||
final String initiator = "iAmTheInitiator";
|
||||
final String remark = "remarkForTesting";
|
||||
|
||||
final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT);
|
||||
messageProperties.setHeader(MessageHeaderKey.THING_ID, knownThingId);
|
||||
messageProperties.setHeader(MessageHeaderKey.TOPIC, "UPDATE_AUTO_CONFIRM");
|
||||
final DmfAutoConfirmation autoConfirmation = new DmfAutoConfirmation();
|
||||
autoConfirmation.setEnabled(true);
|
||||
autoConfirmation.setInitiator(initiator);
|
||||
autoConfirmation.setRemark(remark);
|
||||
|
||||
final Message message = createMessage(autoConfirmation, messageProperties);
|
||||
|
||||
when(controllerManagementMock.activateAutoConfirmation(targetIdCaptor.capture(), initiatorCaptor.capture(),
|
||||
remarkCaptor.capture())).thenReturn(null);
|
||||
|
||||
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, VIRTUAL_HOST);
|
||||
|
||||
verify(controllerManagementMock, times(0)).deactivateAutoConfirmation(anyString());
|
||||
|
||||
assertThingIdCapturedField(knownThingId);
|
||||
assertInitiatorCapturedField(initiator);
|
||||
assertRemarkCapturedField(remark);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Description("Tests deactivating auto-confirmation on a target.")
|
||||
void setAutoConfirmationStateDeactivated() {
|
||||
final String knownThingId = "1";
|
||||
|
||||
final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT);
|
||||
messageProperties.setHeader(MessageHeaderKey.THING_ID, knownThingId);
|
||||
messageProperties.setHeader(MessageHeaderKey.TOPIC, "UPDATE_AUTO_CONFIRM");
|
||||
final DmfAutoConfirmation autoConfirmation = new DmfAutoConfirmation();
|
||||
|
||||
final Message message = createMessage(autoConfirmation, messageProperties);
|
||||
|
||||
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, VIRTUAL_HOST);
|
||||
|
||||
verify(controllerManagementMock).deactivateAutoConfirmation(targetIdCaptor.capture());
|
||||
verify(controllerManagementMock, times(0)).activateAutoConfirmation(anyString(), anyString(), anyString());
|
||||
|
||||
assertThingIdCapturedField(knownThingId);
|
||||
}
|
||||
|
||||
private DmfActionUpdateStatus createActionUpdateStatus(final DmfActionStatus status) {
|
||||
return createActionUpdateStatus(status, 2L);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -31,6 +30,7 @@ import org.eclipse.hawkbit.dmf.json.model.DmfActionRequest;
|
||||
import org.eclipse.hawkbit.dmf.json.model.DmfActionStatus;
|
||||
import org.eclipse.hawkbit.dmf.json.model.DmfActionUpdateStatus;
|
||||
import org.eclipse.hawkbit.dmf.json.model.DmfAttributeUpdate;
|
||||
import org.eclipse.hawkbit.dmf.json.model.DmfConfirmRequest;
|
||||
import org.eclipse.hawkbit.dmf.json.model.DmfCreateThing;
|
||||
import org.eclipse.hawkbit.dmf.json.model.DmfDownloadAndUpdateRequest;
|
||||
import org.eclipse.hawkbit.dmf.json.model.DmfMetadata;
|
||||
@@ -129,7 +129,13 @@ public abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpInt
|
||||
testdataFactory.addSoftwareModuleMetadata(distributionSet);
|
||||
|
||||
return registerTargetAndAssignDistributionSet(distributionSet.getId(), TargetUpdateStatus.REGISTERED,
|
||||
distributionSet.getModules(), controllerId);
|
||||
distributionSet.getModules(), controllerId);
|
||||
}
|
||||
|
||||
protected DistributionSetAssignmentResult prepareDistributionSetAndAssign(final String controllerId) {
|
||||
distributionSet = testdataFactory.createDistributionSet(UUID.randomUUID().toString());
|
||||
testdataFactory.addSoftwareModuleMetadata(distributionSet);
|
||||
return assignDistributionSet(distributionSet.getId(), controllerId);
|
||||
}
|
||||
|
||||
protected DistributionSetAssignmentResult registerTargetAndAssignDistributionSet(final Long assignDs,
|
||||
@@ -138,7 +144,11 @@ public abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpInt
|
||||
registerAndAssertTargetWithExistingTenant(controllerId, 1, expectedStatus, CREATED_BY);
|
||||
|
||||
final DistributionSetAssignmentResult assignmentResult = assignDistributionSet(assignDs, controllerId);
|
||||
assertDownloadAndInstallMessage(expectedSoftwareModulesInMessage, controllerId);
|
||||
if (isConfirmationFlowEnabled()) {
|
||||
assertConfirmMessage(expectedSoftwareModulesInMessage, controllerId);
|
||||
} else {
|
||||
assertDownloadAndInstallMessage(expectedSoftwareModulesInMessage, controllerId);
|
||||
}
|
||||
return assignmentResult;
|
||||
}
|
||||
|
||||
@@ -452,4 +462,24 @@ public abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpInt
|
||||
softwareModules.forEach(dmfModule -> assertThat(dmfModule.getMetadata()).containsExactly(
|
||||
new DmfMetadata(TestdataFactory.VISIBLE_SM_MD_KEY, TestdataFactory.VISIBLE_SM_MD_VALUE)));
|
||||
}
|
||||
|
||||
protected void assertConfirmMessage(final Set<SoftwareModule> dsModules, final String controllerId) {
|
||||
|
||||
final Message replyMessage = assertReplyMessageHeader(EventTopic.CONFIRM, controllerId);
|
||||
assertAllTargetsCount(1);
|
||||
|
||||
final DmfConfirmRequest confirmRequest = (DmfConfirmRequest) getDmfClient()
|
||||
.getMessageConverter().fromMessage(replyMessage);
|
||||
|
||||
assertConfirmRequest(confirmRequest, dsModules, controllerId);
|
||||
}
|
||||
|
||||
protected void assertConfirmRequest(final DmfConfirmRequest request, final Set<SoftwareModule> softwareModules,
|
||||
final String controllerId) {
|
||||
assertSoftwareModules(softwareModules, request.getSoftwareModules());
|
||||
final Target updatedTarget = waitUntilIsPresent(() -> targetManagement.getByControllerID(controllerId));
|
||||
assertThat(updatedTarget).isNotNull();
|
||||
assertThat(updatedTarget.getSecurityToken()).isEqualTo(request.getTargetSecurityToken());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -466,7 +466,7 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpSer
|
||||
|
||||
private Rollout createAndStartRollout(final DistributionSet ds, final String filterQuery, final Integer weight) {
|
||||
final Rollout rollout = testdataFactory.createRolloutByVariables(UUID.randomUUID().toString(), "", 1,
|
||||
filterQuery, ds, "50", "5", ActionType.FORCED, weight);
|
||||
filterQuery, ds, "50", "5", ActionType.FORCED, weight, false);
|
||||
rolloutManagement.start(rollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
return rollout;
|
||||
@@ -695,4 +695,28 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpSer
|
||||
assertThat(tokens.contains(requestTarget.getTargetSecurityToken()));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verify that a distribution assignment send a confirm message.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 1),
|
||||
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
|
||||
void sendConfirmStatus() {
|
||||
final String controllerId = TARGET_PREFIX + "sendConfirmStatus";
|
||||
enableConfirmationFlow();
|
||||
registerTargetAndAssignDistributionSet(controllerId);
|
||||
|
||||
waitUntilTargetHasStatus(controllerId, TargetUpdateStatus.PENDING);
|
||||
assertConfirmMessage(getDistributionSet().getModules(), controllerId);
|
||||
assertEventMessageNotPresent(EventTopic.DOWNLOAD_AND_INSTALL);
|
||||
}
|
||||
protected void assertEventMessageNotPresent(final EventTopic eventTopic) {
|
||||
assertThat(replyToListener.getLatestEventMessage(eventTopic)).isNull();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@ import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedE
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TenantConfigurationCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TenantConfigurationUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
||||
@@ -966,6 +968,26 @@ class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServiceIntegr
|
||||
getDmfClient().send(updateMessage);
|
||||
}
|
||||
|
||||
private void assertActionStatusList(final Long actionId, final int statusListCount,
|
||||
final Status... expectedActionStates) {
|
||||
createConditionFactory().await().untilAsserted(() -> {
|
||||
try {
|
||||
WithSpringAuthorityRule.runAsPrivileged(() -> {
|
||||
final List<ActionStatus> actionStatusList = deploymentManagement
|
||||
.findActionStatusByAction(PAGE, actionId).getContent();
|
||||
assertThat(actionStatusList).hasSize(statusListCount);
|
||||
|
||||
final List<Status> status = actionStatusList.stream().map(ActionStatus::getStatus)
|
||||
.collect(Collectors.toList());
|
||||
assertThat(status).containsOnly(expectedActionStates);
|
||||
|
||||
return null;
|
||||
});
|
||||
} catch (final Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
private int getAuthenticationMessageCount() {
|
||||
return Integer
|
||||
.parseInt(Objects.requireNonNull(getRabbitAdmin().getQueueProperties(amqpProperties.getReceiverQueue()))
|
||||
@@ -993,4 +1015,142 @@ class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServiceIntegr
|
||||
assertThat(node.has("actionId")).isTrue();
|
||||
return node.get("actionId").asText();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Register a target and send a update action status (confirmed). Verify if the updated action status is correct.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 1),
|
||||
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
|
||||
void confirmedActionStatus() {
|
||||
enableConfirmationFlow();
|
||||
final String controllerId = TARGET_PREFIX + "confirmedActionStatus";
|
||||
|
||||
final DistributionSetAssignmentResult assignmentResult = registerTargetAndAssignDistributionSet(controllerId);
|
||||
final Long actionId = getFirstAssignedActionId(assignmentResult);
|
||||
createAndSendActionStatusUpdateMessage(controllerId, actionId, DmfActionStatus.CONFIRMED);
|
||||
assertActionStatusList(actionId, 2, Status.WAIT_FOR_CONFIRMATION, Status.RUNNING);
|
||||
|
||||
// assert download and install message
|
||||
waitUntilEventMessagesAreDispatchedToTarget(EventTopic.CONFIRM, EventTopic.DOWNLOAD_AND_INSTALL);
|
||||
assertDownloadAndInstallMessage(assignmentResult.getDistributionSet().getModules(), controllerId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verify the DMF confirmed feedback can be provided if confirmation flow is disabled")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 1),
|
||||
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1),
|
||||
@Expect(type = TenantConfigurationUpdatedEvent.class, count = 1) })
|
||||
void verifyActionCanBeConfirmedOnDisabledConfirmationFlow() {
|
||||
enableConfirmationFlow();
|
||||
final String controllerId = TARGET_PREFIX + "confirmedActionStatus";
|
||||
|
||||
final DistributionSetAssignmentResult assignmentResult = registerTargetAndAssignDistributionSet(controllerId);
|
||||
final Long actionId = getFirstAssignedActionId(assignmentResult);
|
||||
// verify action status is in WAIT_FOR_CONFIRMATION
|
||||
assertActionStatusList(actionId, 1, Status.WAIT_FOR_CONFIRMATION);
|
||||
|
||||
disableConfirmationFlow();
|
||||
|
||||
createAndSendActionStatusUpdateMessage(controllerId, actionId, DmfActionStatus.CONFIRMED);
|
||||
assertActionStatusList(actionId, 2, Status.WAIT_FOR_CONFIRMATION, Status.RUNNING);
|
||||
|
||||
// assert download and install message
|
||||
waitUntilEventMessagesAreDispatchedToTarget(EventTopic.CONFIRM, EventTopic.DOWNLOAD_AND_INSTALL);
|
||||
assertDownloadAndInstallMessage(assignmentResult.getDistributionSet().getModules(), controllerId);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Description("Verify the DMF confirmed feedback can be provided if confirmation flow is disabled")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = ActionUpdatedEvent.class, count = 0),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 1),
|
||||
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1),
|
||||
@Expect(type = TenantConfigurationUpdatedEvent.class, count = 1)})
|
||||
void verifyActionCanBeDeniedOnDisabledConfirmationFlow() {
|
||||
enableConfirmationFlow();
|
||||
final String controllerId = TARGET_PREFIX + "confirmedActionStatus";
|
||||
|
||||
final DistributionSetAssignmentResult assignmentResult = registerTargetAndAssignDistributionSet(controllerId);
|
||||
final Long actionId = getFirstAssignedActionId(assignmentResult);
|
||||
// verify action status is in WAIT_FOR_CONFIRMATION
|
||||
assertActionStatusList(actionId, 1, Status.WAIT_FOR_CONFIRMATION);
|
||||
|
||||
disableConfirmationFlow();
|
||||
|
||||
createAndSendActionStatusUpdateMessage(controllerId, actionId, DmfActionStatus.DENIED);
|
||||
assertActionStatusList(actionId, 2, Status.WAIT_FOR_CONFIRMATION);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verify the DMF download and install message is send directly if auto-confirmation is active")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = ActionUpdatedEvent.class, count = 0),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetPollEvent.class, count = 1),
|
||||
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
|
||||
void verifyDownloadAndInstallDirectlySendOnAutoConfirmationEnabled() {
|
||||
enableConfirmationFlow();
|
||||
final String controllerId = TARGET_PREFIX + "confirmedActionStatus";
|
||||
|
||||
registerAndAssertTargetWithExistingTenant(controllerId);
|
||||
|
||||
confirmationManagement.activateAutoConfirmation(controllerId, null, null);
|
||||
|
||||
final DistributionSetAssignmentResult assignmentResult = prepareDistributionSetAndAssign(controllerId);
|
||||
final Long actionId = getFirstAssignedActionId(assignmentResult);
|
||||
// verify action status is in WAIT_FOR_CONFIRMATION
|
||||
assertActionStatusList(actionId, 1, Status.WAIT_FOR_CONFIRMATION);
|
||||
|
||||
// assert download and install message
|
||||
waitUntilEventMessagesAreDispatchedToTarget(EventTopic.DOWNLOAD_AND_INSTALL);
|
||||
assertDownloadAndInstallMessage(assignmentResult.getDistributionSet().getModules(), controllerId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Register a target and send a update action status (denied). Verify if the updated action status is correct.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = ActionUpdatedEvent.class), @Expect(type = ActionCreatedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 1),
|
||||
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
|
||||
void deniedActionStatus() {
|
||||
enableConfirmationFlow();
|
||||
final String controllerId = TARGET_PREFIX + "deniedActionStatus";
|
||||
final DistributionSetAssignmentResult assignmentResult = registerTargetAndAssignDistributionSet(controllerId);
|
||||
final Long actionId = getFirstAssignedActionId(assignmentResult);
|
||||
assertActionStatusList(actionId, 1, Status.WAIT_FOR_CONFIRMATION);
|
||||
createAndSendActionStatusUpdateMessage(controllerId, actionId, DmfActionStatus.DENIED);
|
||||
assertActionStatusList(actionId, 2, Status.WAIT_FOR_CONFIRMATION);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user