Request attribute update after deployment (#750)
Send attribute update request to ddi connected device after successful software update Signed-off-by: Stefan Klotz <stefan.klotz@bosch-si.com>
This commit is contained in:
committed by
Dominic Schabel
parent
93279c0803
commit
f8e1a547b0
@@ -12,7 +12,9 @@ import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.eclipse.hawkbit.dmf.json.model.DmfActionStatus;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetAttributesRequestedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent;
|
||||
@@ -30,6 +32,7 @@ import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.eclipse.hawkbit.repository.test.matcher.Expect;
|
||||
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
||||
import org.junit.Test;
|
||||
import org.springframework.amqp.core.Message;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
@@ -53,7 +56,7 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AmqpServiceInte
|
||||
final String controllerId = TARGET_PREFIX + "sendDownloadAndInstallStatus";
|
||||
registerTargetAndAssignDistributionSet(controllerId);
|
||||
|
||||
waitUntilTargetStatusIsPending(controllerId);
|
||||
waitUntilTargetHasStatus(controllerId, TargetUpdateStatus.PENDING);
|
||||
assertDownloadAndInstallMessage(getDistributionSet().getModules(), controllerId);
|
||||
}
|
||||
|
||||
@@ -75,7 +78,7 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AmqpServiceInte
|
||||
assignDistributionSetWithMaintenanceWindow(distributionSet.getId(), controllerId, getTestSchedule(2),
|
||||
getTestDuration(10), getTestTimeZone());
|
||||
|
||||
waitUntilTargetStatusIsPending(controllerId);
|
||||
waitUntilTargetHasStatus(controllerId, TargetUpdateStatus.PENDING);
|
||||
assertDownloadMessage(distributionSet.getModules(), controllerId);
|
||||
}
|
||||
|
||||
@@ -97,7 +100,7 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AmqpServiceInte
|
||||
assignDistributionSetWithMaintenanceWindow(distributionSet.getId(), controllerId, getTestSchedule(-5),
|
||||
getTestDuration(10), getTestTimeZone());
|
||||
|
||||
waitUntilTargetStatusIsPending(controllerId);
|
||||
waitUntilTargetHasStatus(controllerId, TargetUpdateStatus.PENDING);
|
||||
assertDownloadAndInstallMessage(distributionSet.getModules(), controllerId);
|
||||
}
|
||||
|
||||
@@ -122,7 +125,7 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AmqpServiceInte
|
||||
assertCancelActionMessage(assignmentResult.getActions().get(0), controllerId);
|
||||
|
||||
createAndSendTarget(controllerId, TENANT_EXIST);
|
||||
waitUntilTargetStatusIsPending(controllerId);
|
||||
waitUntilTargetHasStatus(controllerId, TargetUpdateStatus.PENDING);
|
||||
assertCancelActionMessage(assignmentResult.getActions().get(0), controllerId);
|
||||
|
||||
}
|
||||
@@ -143,7 +146,7 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AmqpServiceInte
|
||||
final Long actionId = registerTargetAndCancelActionId(controllerId);
|
||||
|
||||
createAndSendTarget(controllerId, TENANT_EXIST);
|
||||
waitUntilTargetStatusIsPending(controllerId);
|
||||
waitUntilTargetHasStatus(controllerId, TargetUpdateStatus.PENDING);
|
||||
assertCancelActionMessage(actionId, controllerId);
|
||||
}
|
||||
|
||||
@@ -159,11 +162,47 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AmqpServiceInte
|
||||
assertDeleteMessage(controllerId);
|
||||
}
|
||||
|
||||
private void waitUntilTargetStatusIsPending(final String controllerId) {
|
||||
|
||||
@Test
|
||||
@Description("Verify that attribute update is requested after device successfully closed software update.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2),
|
||||
@Expect(type = ActionUpdatedEvent.class, count = 2), @Expect(type = ActionCreatedEvent.class, count = 2),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 4),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void attributeRequestAfterSuccessfulUpdate() {
|
||||
final String controllerId = TARGET_PREFIX + "attributeUpdateRequest";
|
||||
registerAndAssertTargetWithExistingTenant(controllerId);
|
||||
final Target target = controllerManagement.getByControllerId(controllerId).get();
|
||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet(UUID.randomUUID().toString());
|
||||
|
||||
final long actionId1 = assignDistributionSet(distributionSet, target).getActions().get(0);
|
||||
waitUntilTargetHasStatus(controllerId, TargetUpdateStatus.PENDING);
|
||||
final Message messageError = createActionStatusUpdateMessage(controllerId, TENANT_EXIST, actionId1,
|
||||
DmfActionStatus.ERROR);
|
||||
getDmfClient().send(messageError);
|
||||
waitUntilTargetHasStatus(controllerId, TargetUpdateStatus.ERROR);
|
||||
|
||||
assertRequestAttributesUpdateMessageAbsent();
|
||||
|
||||
final long actionId2 = assignDistributionSet(distributionSet, target).getActions().get(0);
|
||||
waitUntilTargetHasStatus(controllerId, TargetUpdateStatus.PENDING);
|
||||
final Message messageFin = createActionStatusUpdateMessage(controllerId, TENANT_EXIST, actionId2,
|
||||
DmfActionStatus.FINISHED);
|
||||
getDmfClient().send(messageFin);
|
||||
waitUntilTargetHasStatus(controllerId, TargetUpdateStatus.IN_SYNC);
|
||||
|
||||
assertRequestAttributesUpdateMessage(controllerId);
|
||||
}
|
||||
|
||||
private void waitUntilTargetHasStatus(final String controllerId, final TargetUpdateStatus status) {
|
||||
waitUntil(() -> {
|
||||
final Optional<Target> findTargetByControllerID = targetManagement.getByControllerID(controllerId);
|
||||
return findTargetByControllerID.isPresent()
|
||||
&& TargetUpdateStatus.PENDING.equals(findTargetByControllerID.get().getUpdateStatus());
|
||||
&& status.equals(findTargetByControllerID.get().getUpdateStatus());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.eclipse.hawkbit.dmf.json.model.DmfAttributeUpdate;
|
||||
import org.eclipse.hawkbit.dmf.json.model.DmfUpdateMode;
|
||||
import org.eclipse.hawkbit.repository.RepositoryConstants;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetAttributesRequestedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent;
|
||||
@@ -363,13 +364,14 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Tests register target and cancel a assignment")
|
||||
@Description("Tests register target and send finished message")
|
||||
@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 = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void finishActionStatus() {
|
||||
final String controllerId = TARGET_PREFIX + "finishActionStatus";
|
||||
@@ -805,7 +807,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
verifyNumberOfDeadLetterMessages(3);
|
||||
}
|
||||
|
||||
private void sendUpdateAttributesMessageWithGivenAttributes(String target, String key, String value) {
|
||||
private void sendUpdateAttributesMessageWithGivenAttributes(final String target, final String key, final String value) {
|
||||
final DmfAttributeUpdate controllerAttribute = new DmfAttributeUpdate();
|
||||
controllerAttribute.getAttributes().put(key, value);
|
||||
final Message message = createUpdateAttributesMessage(target, TENANT_EXIST, controllerAttribute);
|
||||
@@ -889,7 +891,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
|
||||
verifyNumberOfDeadLetterMessages(1);
|
||||
}
|
||||
|
||||
private void verifyNumberOfDeadLetterMessages(int numberOfInvocations) {
|
||||
private void verifyNumberOfDeadLetterMessages(final int numberOfInvocations) {
|
||||
assertEmptyReceiverQueueCount();
|
||||
createConditionFactory()
|
||||
.until(() -> Mockito.verify(getDeadletterListener(), Mockito.times(numberOfInvocations)).handleMessage(Mockito.any()));
|
||||
|
||||
@@ -23,6 +23,8 @@ import org.eclipse.hawkbit.dmf.amqp.api.EventTopic;
|
||||
import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
|
||||
import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
|
||||
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.DmfDownloadAndUpdateRequest;
|
||||
import org.eclipse.hawkbit.dmf.json.model.DmfMetadata;
|
||||
@@ -147,6 +149,14 @@ public abstract class AmqpServiceIntegrationTest extends AbstractAmqpIntegration
|
||||
assertThat(headers.get(MessageHeaderKey.TYPE)).isEqualTo(MessageType.THING_DELETED.toString());
|
||||
}
|
||||
|
||||
protected void assertRequestAttributesUpdateMessage(final String target) {
|
||||
assertReplyMessageHeader(EventTopic.REQUEST_ATTRIBUTES_UPDATE, target);
|
||||
}
|
||||
|
||||
protected void assertRequestAttributesUpdateMessageAbsent() {
|
||||
assertThat(replyToListener.getEventTopicMessages()).doesNotContainKey(EventTopic.REQUEST_ATTRIBUTES_UPDATE);
|
||||
}
|
||||
|
||||
protected void assertPingReplyMessage(final String correlationId) {
|
||||
|
||||
verifyReplyToListener();
|
||||
@@ -302,6 +312,17 @@ public abstract class AmqpServiceIntegrationTest extends AbstractAmqpIntegration
|
||||
return createMessage(null, messageProperties);
|
||||
}
|
||||
|
||||
protected Message createActionStatusUpdateMessage(final String target, final String tenant, final long actionId,
|
||||
final DmfActionStatus status) {
|
||||
final MessageProperties messageProperties = createMessagePropertiesWithTenant(tenant);
|
||||
messageProperties.getHeaders().put(MessageHeaderKey.THING_ID, target);
|
||||
messageProperties.getHeaders().put(MessageHeaderKey.TYPE, MessageType.EVENT.toString());
|
||||
messageProperties.getHeaders().put(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.toString());
|
||||
|
||||
final DmfActionUpdateStatus dmfActionUpdateStatus = new DmfActionUpdateStatus(actionId, status);
|
||||
return createMessage(dmfActionUpdateStatus, messageProperties);
|
||||
}
|
||||
|
||||
protected MessageProperties createMessagePropertiesWithTenant(final String tenant) {
|
||||
final MessageProperties messageProperties = new MessageProperties();
|
||||
messageProperties.getHeaders().put(MessageHeaderKey.TENANT, tenant);
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa;
|
||||
|
||||
import static org.eclipse.hawkbit.repository.model.Target.CONTROLLER_ATTRIBUTE_KEY_SIZE;
|
||||
import static org.eclipse.hawkbit.repository.model.Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.time.ZonedDateTime;
|
||||
@@ -37,6 +40,7 @@ import org.eclipse.hawkbit.repository.MaintenanceScheduleHelper;
|
||||
import org.eclipse.hawkbit.repository.QuotaManagement;
|
||||
import org.eclipse.hawkbit.repository.RepositoryConstants;
|
||||
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||
import org.eclipse.hawkbit.repository.UpdateMode;
|
||||
import org.eclipse.hawkbit.repository.builder.ActionStatusCreate;
|
||||
@@ -97,9 +101,6 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import static org.eclipse.hawkbit.repository.model.Target.CONTROLLER_ATTRIBUTE_KEY_SIZE;
|
||||
import static org.eclipse.hawkbit.repository.model.Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE;
|
||||
|
||||
/**
|
||||
* JPA based {@link ControllerManagement} implementation.
|
||||
*
|
||||
@@ -120,6 +121,9 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
@Autowired
|
||||
private TargetRepository targetRepository;
|
||||
|
||||
@Autowired
|
||||
private TargetManagement targetManagement;
|
||||
|
||||
@Autowired
|
||||
private SoftwareModuleRepository softwareModuleRepository;
|
||||
|
||||
@@ -595,7 +599,9 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
* Sets {@link TargetUpdateStatus} based on given {@link ActionStatus}.
|
||||
*/
|
||||
private Action handleAddUpdateActionStatus(final JpaActionStatus actionStatus, final JpaAction action) {
|
||||
LOG.debug("addUpdateActionStatus for action {}", action.getId());
|
||||
|
||||
String controllerId = null;
|
||||
LOG.debug("handleAddUpdateActionStatus for action {}", action.getId());
|
||||
|
||||
switch (actionStatus.getStatus()) {
|
||||
case ERROR:
|
||||
@@ -604,7 +610,7 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
handleErrorOnAction(action, target);
|
||||
break;
|
||||
case FINISHED:
|
||||
handleFinishedAndStoreInTargetStatus(action);
|
||||
controllerId = handleFinishedAndStoreInTargetStatus(action);
|
||||
break;
|
||||
default:
|
||||
// information status entry - check for a potential DOS attack
|
||||
@@ -615,10 +621,13 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
|
||||
actionStatus.setAction(action);
|
||||
actionStatusRepository.save(actionStatus);
|
||||
final Action savedAction = actionRepository.save(action);
|
||||
|
||||
LOG.debug("addUpdateActionStatus for action {} isfinished.", action.getId());
|
||||
|
||||
return actionRepository.save(action);
|
||||
if (controllerId != null) {
|
||||
targetManagement.requestControllerAttributes(controllerId);
|
||||
}
|
||||
|
||||
return savedAction;
|
||||
}
|
||||
|
||||
private void handleErrorOnAction(final JpaAction mergedAction, final JpaTarget mergedTarget) {
|
||||
@@ -634,7 +643,7 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
ActionStatus.class, Action.class, actionStatusRepository::countByActionId);
|
||||
}
|
||||
|
||||
private void handleFinishedAndStoreInTargetStatus(final JpaAction action) {
|
||||
private String handleFinishedAndStoreInTargetStatus(final JpaAction action) {
|
||||
final JpaTarget target = (JpaTarget) action.getTarget();
|
||||
action.setActive(false);
|
||||
action.setStatus(Status.FINISHED);
|
||||
@@ -651,8 +660,9 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
}
|
||||
|
||||
targetRepository.save(target);
|
||||
|
||||
entityManager.detach(ds);
|
||||
|
||||
return target.getControllerId();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.apache.commons.lang3.RandomUtils;
|
||||
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
||||
import org.eclipse.hawkbit.repository.UpdateMode;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetAttributesRequestedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent;
|
||||
@@ -137,6 +138,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void controllerConfirmsUpdateWithFinished() {
|
||||
final Long actionId = createTargetAndAssignDs();
|
||||
@@ -188,6 +190,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
||||
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void controllerConfirmsUpdateWithFinishedAndIgnorsCancellationWithThat() {
|
||||
final Long actionId = createTargetAndAssignDs();
|
||||
@@ -557,6 +560,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void tryToFinishUpdateProcessMoreThanOnce() {
|
||||
final Long actionId = prepareFinishedUpdate().getId();
|
||||
@@ -593,6 +597,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void sendUpdatesForFinishUpdateProcessDropedIfDisabled() {
|
||||
repositoryProperties.setRejectActionStatusForClosedAction(true);
|
||||
@@ -619,6 +624,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void sendUpdatesForFinishUpdateProcessAcceptedIfEnabled() {
|
||||
repositoryProperties.setRejectActionStatusForClosedAction(false);
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||
import org.eclipse.hawkbit.repository.FilterParams;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetAttributesRequestedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent;
|
||||
@@ -427,6 +428,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
@Expect(type = ActionCreatedEvent.class, count = 2), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void findTargetByControllerIDWithDetails() {
|
||||
final DistributionSet set = testdataFactory.createDistributionSet("test");
|
||||
|
||||
@@ -27,8 +27,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetAttributesRequestedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent;
|
||||
@@ -54,9 +58,11 @@ import org.eclipse.hawkbit.util.IpUtil;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.ResultActions;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Step;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
/**
|
||||
@@ -192,6 +198,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 3), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 2),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6) })
|
||||
public void rootRsNotModified() throws Exception {
|
||||
final String etag = mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant()))
|
||||
@@ -227,11 +234,9 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
etagWithFirstUpdate)).andDo(MockMvcResultPrinter.print()).andExpect(status().isNotModified());
|
||||
|
||||
// now lets finish the update
|
||||
mvc.perform(post("/{tenant}/controller/v1/4711/deploymentBase/" + updateAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(updateAction.getId().toString(), "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
sendDeploymentActionFeedback(target, updateAction,
|
||||
JsonBuilder.deploymentActionFeedback(updateAction.getId().toString(), "closed"))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
|
||||
// we are again at the original state
|
||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant()).header("If-None-Match", etag))
|
||||
@@ -262,7 +267,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void rootRsPrecommissioned() throws Exception {
|
||||
final Target target = testdataFactory.createTarget("4711");
|
||||
testdataFactory.createTarget("4711");
|
||||
|
||||
assertThat(targetManagement.getByControllerID("4711").get().getUpdateStatus())
|
||||
.isEqualTo(TargetUpdateStatus.UNKNOWN);
|
||||
@@ -335,6 +340,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void tryToFinishAnUpdateProcessAfterItHasBeenFinished() throws Exception {
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
@@ -343,23 +349,89 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
.next();
|
||||
final Action savedAction = deploymentManagement.findActiveActionsByTarget(PAGE, savedTarget.getControllerId())
|
||||
.getContent().get(0);
|
||||
mvc.perform(post("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "proceeding"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
sendDeploymentActionFeedback(savedTarget, savedAction,
|
||||
JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "proceeding"))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant()).content(
|
||||
JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "closed", "failure"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
sendDeploymentActionFeedback(savedTarget, savedAction,
|
||||
JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "closed", "failure"))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant()).content(
|
||||
JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "closed", "success"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isGone());
|
||||
sendDeploymentActionFeedback(savedTarget, savedAction,
|
||||
JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "closed", "success"))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isGone());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Controller sends attribute update request after device successfully closed software update.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 2), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 6), @Expect(type = TargetPollEvent.class, count = 4),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1) })
|
||||
public void testAttributeUpdateRequestSendingAfterSuccessfulDeployment() throws Exception {
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("1");
|
||||
final Target savedTarget = testdataFactory.createTarget("922");
|
||||
final Map<String, String> attributes = Collections.singletonMap("AttributeKey", "AttributeValue");
|
||||
assertThatAttributesUpdateIsRequested(savedTarget.getControllerId());
|
||||
|
||||
mvc.perform(put("/{tenant}/controller/v1/{controllerId}/configData", tenantAware.getCurrentTenant(),
|
||||
savedTarget.getControllerId())
|
||||
.content(JsonBuilder.configData(savedTarget.getControllerId(), attributes, "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk());
|
||||
assertThatAttributesUpdateIsNotRequested(savedTarget.getControllerId());
|
||||
|
||||
assertAttributesUpdateNotRequestedAfterFailedDeployment(savedTarget, ds);
|
||||
|
||||
assertAttributesUpdateRequestedAfterSuccessfulDeployment(savedTarget, ds);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void assertAttributesUpdateNotRequestedAfterFailedDeployment(Target target, final DistributionSet ds)
|
||||
throws Exception {
|
||||
target = assignDistributionSet(ds.getId(), target.getControllerId()).getAssignedEntity().iterator().next();
|
||||
assignDistributionSet(ds.getId(), target.getControllerId());
|
||||
final Action action = deploymentManagement.findActiveActionsByTarget(PAGE, target.getControllerId())
|
||||
.getContent().get(0);
|
||||
sendDeploymentActionFeedback(target, action,
|
||||
JsonBuilder.deploymentActionFeedback(action.getId().toString(), "closed", "failure", ""))
|
||||
.andExpect(status().isOk());
|
||||
assertThatAttributesUpdateIsNotRequested(target.getControllerId());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void assertAttributesUpdateRequestedAfterSuccessfulDeployment(Target target, final DistributionSet ds)
|
||||
throws Exception {
|
||||
target = assignDistributionSet(ds.getId(), target.getControllerId()).getAssignedEntity().iterator().next();
|
||||
final Action action = deploymentManagement.findActiveActionsByTarget(PAGE, target.getControllerId())
|
||||
.getContent().get(0);
|
||||
sendDeploymentActionFeedback(target, action,
|
||||
JsonBuilder.deploymentActionFeedback(action.getId().toString(), "closed")).andExpect(status().isOk());
|
||||
assertThatAttributesUpdateIsRequested(target.getControllerId());
|
||||
}
|
||||
|
||||
private void assertThatAttributesUpdateIsRequested(final String targetControllerId)
|
||||
throws Exception {
|
||||
mvc.perform(
|
||||
get("/{tenant}/controller/v1/{controllerId}", tenantAware.getCurrentTenant(), targetControllerId)
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$._links.configData.href").isNotEmpty());
|
||||
}
|
||||
|
||||
private void assertThatAttributesUpdateIsNotRequested(final String targetControllerId) throws Exception {
|
||||
mvc.perform(get("/{tenant}/controller/v1/{controllerId}", tenantAware.getCurrentTenant(), targetControllerId)
|
||||
.accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._links.configData").doesNotExist());
|
||||
}
|
||||
|
||||
private ResultActions sendDeploymentActionFeedback(final Target target, final Action action,
|
||||
final String feedback) throws Exception {
|
||||
return mvc.perform(post("/{tenant}/controller/v1/{controllerId}/deploymentBase/{actionId}/feedback",
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(), action.getId()).content(feedback)
|
||||
.contentType(MediaType.APPLICATION_JSON));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -369,6 +441,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void testActionHistoryCount() throws Exception {
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
@@ -378,26 +451,20 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
final Action savedAction = deploymentManagement.findActiveActionsByTarget(PAGE, savedTarget.getControllerId())
|
||||
.getContent().get(0);
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "scheduled",
|
||||
TARGET_SCHEDULED_INSTALLATION_MSG))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
sendDeploymentActionFeedback(savedTarget, savedAction,
|
||||
JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "scheduled",
|
||||
TARGET_SCHEDULED_INSTALLATION_MSG)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "proceeding",
|
||||
TARGET_PROCEEDING_INSTALLATION_MSG))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
sendDeploymentActionFeedback(savedTarget, savedAction,
|
||||
JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "proceeding",
|
||||
TARGET_PROCEEDING_INSTALLATION_MSG)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "closed",
|
||||
"success", TARGET_COMPLETED_INSTALLATION_MSG))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
sendDeploymentActionFeedback(savedTarget, savedAction,
|
||||
JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "closed", "success",
|
||||
TARGET_COMPLETED_INSTALLATION_MSG)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "?actionHistory=3",
|
||||
tenantAware.getCurrentTenant()).contentType(MediaType.APPLICATION_JSON)
|
||||
@@ -416,6 +483,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void testActionHistoryZeroInput() throws Exception {
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
@@ -425,26 +493,20 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
final Action savedAction = deploymentManagement.findActiveActionsByTarget(PAGE, savedTarget.getControllerId())
|
||||
.getContent().get(0);
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "scheduled",
|
||||
TARGET_SCHEDULED_INSTALLATION_MSG))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
sendDeploymentActionFeedback(savedTarget, savedAction,
|
||||
JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "scheduled",
|
||||
TARGET_SCHEDULED_INSTALLATION_MSG)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "proceeding",
|
||||
TARGET_PROCEEDING_INSTALLATION_MSG))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
sendDeploymentActionFeedback(savedTarget, savedAction,
|
||||
JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "proceeding",
|
||||
TARGET_PROCEEDING_INSTALLATION_MSG)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "closed",
|
||||
"success", TARGET_COMPLETED_INSTALLATION_MSG))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
sendDeploymentActionFeedback(savedTarget, savedAction,
|
||||
JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "closed", "success",
|
||||
TARGET_COMPLETED_INSTALLATION_MSG)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "?actionHistory=-2",
|
||||
tenantAware.getCurrentTenant()).contentType(MediaType.APPLICATION_JSON)
|
||||
@@ -459,6 +521,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void testActionHistoryNegativeInput() throws Exception {
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
@@ -468,26 +531,20 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
final Action savedAction = deploymentManagement.findActiveActionsByTarget(PAGE, savedTarget.getControllerId())
|
||||
.getContent().get(0);
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "scheduled",
|
||||
TARGET_SCHEDULED_INSTALLATION_MSG))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
sendDeploymentActionFeedback(savedTarget, savedAction,
|
||||
JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "scheduled",
|
||||
TARGET_SCHEDULED_INSTALLATION_MSG)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "proceeding",
|
||||
TARGET_PROCEEDING_INSTALLATION_MSG))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
sendDeploymentActionFeedback(savedTarget, savedAction,
|
||||
JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "proceeding",
|
||||
TARGET_PROCEEDING_INSTALLATION_MSG)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "closed",
|
||||
"success", TARGET_COMPLETED_INSTALLATION_MSG))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
sendDeploymentActionFeedback(savedTarget, savedAction,
|
||||
JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "closed", "success",
|
||||
TARGET_COMPLETED_INSTALLATION_MSG)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "?actionHistory=-1",
|
||||
tenantAware.getCurrentTenant()).contentType(MediaType.APPLICATION_JSON)
|
||||
|
||||
Reference in New Issue
Block a user