Fix cancel action status (#429)
* Fixed handling of action cancellation status updates. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Fix broken DDI test. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Code readibility. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Reduce access to default. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Added test for finished on action that is in cancelling. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Update MariaDb driver Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Wrong branch Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Remove duplicate status definition. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Use updated picture in docs. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Leverage existing statics. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Fix picture upload. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Revert change Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -2,6 +2,7 @@
|
||||
# Denote all files that are truly binary and should not be modified.
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.jpeg binary
|
||||
*.pdf binary
|
||||
*.PNG binary
|
||||
*.pptx binary
|
||||
|
||||
@@ -4,7 +4,7 @@ title : "Interfaces"
|
||||
series : "homepagetop"
|
||||
sequence: "2"
|
||||
order : 2
|
||||
imagename : "hawkBit_overview.png"
|
||||
imagename : "hawkBit_overview.jpeg"
|
||||
style: "thumb1"
|
||||
animatestyle: "fadeIn"
|
||||
fadestyle: "fadeIn"
|
||||
|
||||
BIN
docs/src/main/resources/img/hawkBit_overview.jpeg
Normal file
BIN
docs/src/main/resources/img/hawkBit_overview.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 206 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 40 KiB |
@@ -439,7 +439,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
case REJECTED:
|
||||
LOG.info("Target rejected the cancelation request (actionid: {}, controllerId: {}).", actionid,
|
||||
target.getControllerId());
|
||||
status = Status.WARNING;
|
||||
status = Status.CANCEL_REJECTED;
|
||||
messages.add(RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target rejected the cancelation request.");
|
||||
break;
|
||||
case CLOSED:
|
||||
|
||||
@@ -276,7 +276,7 @@ public class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
||||
assertThat(deploymentManagement.countActionStatusAll()).isEqualTo(5);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId())).hasSize(1);
|
||||
|
||||
// cancelation canceled -> should remove the action from active
|
||||
// cancellation canceled -> should remove the action from active
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId())).hasSize(1);
|
||||
current = System.currentTimeMillis();
|
||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||
@@ -289,7 +289,8 @@ public class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
||||
assertThat(deploymentManagement.countActionStatusAll()).isEqualTo(6);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId())).hasSize(1);
|
||||
|
||||
// cancelation rejected -> action still active until controller close it
|
||||
// cancellation rejected -> action still active until controller close
|
||||
// it
|
||||
// with finished or
|
||||
// error
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId())).hasSize(1);
|
||||
@@ -304,9 +305,9 @@ public class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
||||
assertThat(deploymentManagement.countActionStatusAll()).isEqualTo(7);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId())).hasSize(1);
|
||||
|
||||
// cancelaction closed -> should remove the action from active
|
||||
// update closed -> should remove the action from active
|
||||
current = System.currentTimeMillis();
|
||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/deploymentBase/"
|
||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.cancelActionFeedback(cancelAction.getId().toString(), "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
|
||||
@@ -294,7 +294,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
||||
|
||||
private Status hanldeCancelRejectedState(final Message message, final Action action) {
|
||||
if (action.isCancelingOrCanceled()) {
|
||||
return Status.WARNING;
|
||||
return Status.CANCEL_REJECTED;
|
||||
} else {
|
||||
logAndThrowMessageError(message,
|
||||
"Cancel recjected message is not allowed, if action is on state: " + action.getStatus());
|
||||
|
||||
@@ -23,40 +23,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class MgmtActionStatus {
|
||||
|
||||
/**
|
||||
* Action is finished successfully for this target.
|
||||
*/
|
||||
public static final String AS_FINISHED = "finished";
|
||||
|
||||
/**
|
||||
* Action has failed for this target.
|
||||
*/
|
||||
public static final String AS_ERROR = "error";
|
||||
|
||||
/**
|
||||
* Action is still running but with warnings.
|
||||
*/
|
||||
public static final String AS_WARNING = "warning";
|
||||
|
||||
/**
|
||||
* Action is still running for this target.
|
||||
*/
|
||||
public static final String AS_RUNNING = "running";
|
||||
/**
|
||||
* Action has been canceled for this target.
|
||||
*/
|
||||
public static final String AS_CANCELED = "canceled";
|
||||
|
||||
/**
|
||||
* Action has been presented to the target.
|
||||
*/
|
||||
public static final String AS_RETRIEVED = "retrieved";
|
||||
|
||||
/**
|
||||
* Action has been canceled for this target.
|
||||
*/
|
||||
public static final String AS_CANCELING = "canceling";
|
||||
|
||||
@JsonProperty("id")
|
||||
private Long statusId;
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.repository.model.PollStatus;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.eclipse.hawkbit.rest.data.ResponseList;
|
||||
import org.eclipse.hawkbit.rest.data.SortDirection;
|
||||
import org.eclipse.hawkbit.util.IpUtil;
|
||||
@@ -112,7 +111,7 @@ public final class MgmtTargetMapper {
|
||||
targetRest.setControllerId(target.getControllerId());
|
||||
targetRest.setDescription(target.getDescription());
|
||||
targetRest.setName(target.getName());
|
||||
targetRest.setUpdateStatus(getUpdateStatusName(target.getTargetInfo().getUpdateStatus()));
|
||||
targetRest.setUpdateStatus(target.getTargetInfo().getUpdateStatus().name().toLowerCase());
|
||||
|
||||
final URI address = target.getTargetInfo().getAddress();
|
||||
if (address != null) {
|
||||
@@ -198,37 +197,6 @@ public final class MgmtTargetMapper {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static String getNameOfActionStatusType(final Action.Status type) {
|
||||
String result;
|
||||
|
||||
switch (type) {
|
||||
case CANCELED:
|
||||
result = MgmtActionStatus.AS_CANCELED;
|
||||
break;
|
||||
case ERROR:
|
||||
result = MgmtActionStatus.AS_ERROR;
|
||||
break;
|
||||
case FINISHED:
|
||||
result = MgmtActionStatus.AS_FINISHED;
|
||||
break;
|
||||
case RETRIEVED:
|
||||
result = MgmtActionStatus.AS_RETRIEVED;
|
||||
break;
|
||||
case RUNNING:
|
||||
result = MgmtActionStatus.AS_RUNNING;
|
||||
break;
|
||||
case WARNING:
|
||||
result = MgmtActionStatus.AS_WARNING;
|
||||
break;
|
||||
default:
|
||||
return type.name().toLowerCase();
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
private static String getType(final Action action) {
|
||||
if (!action.isCancelingOrCanceled()) {
|
||||
return MgmtAction.ACTION_UPDATE;
|
||||
@@ -239,39 +207,13 @@ public final class MgmtTargetMapper {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getUpdateStatusName(final TargetUpdateStatus updatestatus) {
|
||||
String result;
|
||||
|
||||
switch (updatestatus) {
|
||||
case ERROR:
|
||||
result = "error";
|
||||
break;
|
||||
case IN_SYNC:
|
||||
result = "in_sync";
|
||||
break;
|
||||
case PENDING:
|
||||
result = "pending";
|
||||
break;
|
||||
case REGISTERED:
|
||||
result = "registered";
|
||||
break;
|
||||
case UNKNOWN:
|
||||
result = "unknown";
|
||||
break;
|
||||
default:
|
||||
return updatestatus.name().toLowerCase();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static MgmtActionStatus toResponse(final ActionStatus actionStatus) {
|
||||
final MgmtActionStatus result = new MgmtActionStatus();
|
||||
|
||||
result.setMessages(actionStatus.getMessages());
|
||||
result.setReportedAt(actionStatus.getCreatedAt());
|
||||
result.setStatusId(actionStatus.getId());
|
||||
result.setType(getNameOfActionStatusType(actionStatus.getStatus()));
|
||||
result.setType(actionStatus.getStatus().name().toLowerCase());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -12,11 +12,10 @@ import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||
import org.eclipse.hawkbit.exception.SpServerError;
|
||||
|
||||
/**
|
||||
* Thrown if cancelation of actions is performened where the action is not
|
||||
* cancelable, e.g. the action is not active or is already a cancel action.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Thrown if cancellation of action is requested where the action cannot be
|
||||
* cancelled (e.g. the action is not active or is already a canceled action) or
|
||||
* controller provides cancellation feedback on an action that is actually not
|
||||
* in caneling state.
|
||||
*
|
||||
*/
|
||||
public final class CancelActionNotAllowedException extends AbstractServerRtException {
|
||||
|
||||
@@ -172,7 +172,12 @@ public interface Action extends TenantAwareBaseEntity {
|
||||
* Action is in waiting state, e.g. the action is scheduled in a rollout
|
||||
* but not yet activated.
|
||||
*/
|
||||
SCHEDULED;
|
||||
SCHEDULED,
|
||||
|
||||
/**
|
||||
* Cancellation has been rejected by the controller.
|
||||
*/
|
||||
CANCEL_REJECTED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.eclipse.hawkbit.repository.builder.ActionStatusCreate;
|
||||
import org.eclipse.hawkbit.repository.event.remote.DownloadProgressEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.exception.ToManyAttributeEntriesException;
|
||||
import org.eclipse.hawkbit.repository.exception.TooManyStatusEntriesException;
|
||||
@@ -101,9 +102,6 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
@Autowired
|
||||
private RepositoryProperties repositoryProperties;
|
||||
|
||||
@Autowired
|
||||
private TenantConfigurationRepository tenantConfigurationRepository;
|
||||
|
||||
@Autowired
|
||||
private TenantConfigurationManagement tenantConfigurationManagement;
|
||||
|
||||
@@ -242,26 +240,29 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
final JpaActionStatusCreate create = (JpaActionStatusCreate) c;
|
||||
|
||||
final JpaAction action = getActionAndThrowExceptionIfNotFound(create.getActionId());
|
||||
|
||||
if (!action.isCancelingOrCanceled()) {
|
||||
throw new CancelActionNotAllowedException("The action is not in canceling state.");
|
||||
}
|
||||
|
||||
final JpaActionStatus actionStatus = create.build();
|
||||
|
||||
checkForToManyStatusEntries(action);
|
||||
action.setStatus(actionStatus.getStatus());
|
||||
|
||||
switch (actionStatus.getStatus()) {
|
||||
case WARNING:
|
||||
case ERROR:
|
||||
case RUNNING:
|
||||
break;
|
||||
case CANCELED:
|
||||
case FINISHED:
|
||||
handleFinishedCancelation(actionStatus, action);
|
||||
break;
|
||||
case RETRIEVED:
|
||||
actionStatus.addMessage(RepositoryConstants.SERVER_MESSAGE_PREFIX + "Cancellation request retrieved.");
|
||||
case ERROR:
|
||||
case CANCEL_REJECTED:
|
||||
// Cancellation rejected. Back to running.
|
||||
action.setStatus(Status.RUNNING);
|
||||
break;
|
||||
default:
|
||||
// do nothing
|
||||
// information status entry - check for a potential DOS attack
|
||||
checkForToManyStatusEntries(action);
|
||||
break;
|
||||
}
|
||||
|
||||
actionStatus.setAction(actionRepository.save(action));
|
||||
actionStatusRepository.save(actionStatus);
|
||||
|
||||
@@ -306,17 +307,11 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
|
||||
/**
|
||||
* Sets {@link TargetUpdateStatus} based on given {@link ActionStatus}.
|
||||
*
|
||||
* @param actionStatus
|
||||
* @param action
|
||||
* @return
|
||||
*/
|
||||
private Action handleAddUpdateActionStatus(final JpaActionStatus actionStatus, final JpaAction action) {
|
||||
LOG.debug("addUpdateActionStatus for action {}", action.getId());
|
||||
|
||||
JpaTarget target = (JpaTarget) action.getTarget();
|
||||
// check for a potential DOS attack
|
||||
checkForToManyStatusEntries(action);
|
||||
|
||||
switch (actionStatus.getStatus()) {
|
||||
case ERROR:
|
||||
@@ -327,10 +322,9 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
case FINISHED:
|
||||
handleFinishedAndStoreInTargetStatus(target, action);
|
||||
break;
|
||||
case CANCELED:
|
||||
case WARNING:
|
||||
case RUNNING:
|
||||
default:
|
||||
// information status entry - check for a potential DOS attack
|
||||
checkForToManyStatusEntries(action);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -339,8 +333,6 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
|
||||
LOG.debug("addUpdateActionStatus {} for target {} is finished.", action, target.getId());
|
||||
|
||||
action.setStatus(actionStatus.getStatus());
|
||||
|
||||
return actionRepository.save(action);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ import static org.fest.assertions.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.validation.ConstraintViolationException;
|
||||
|
||||
@@ -20,13 +22,15 @@ import org.eclipse.hawkbit.repository.RepositoryProperties;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.CancelTargetAssignmentEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
|
||||
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.jpa.model.JpaAction;
|
||||
import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.repository.model.Artifact;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
@@ -37,8 +41,11 @@ import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
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;
|
||||
|
||||
@Features("Component Tests - Repository")
|
||||
@@ -49,40 +56,256 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
||||
private RepositoryProperties repositoryProperties;
|
||||
|
||||
@Test
|
||||
@Description("Controller adds a new action status.")
|
||||
@Description("Controller confirms successfull update with FINISHED status.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@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 = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void controllerAddsActionStatus() {
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
Target savedTarget = testdataFactory.createTarget();
|
||||
public void controllerConfirmsUpdateWithFinished() {
|
||||
final Long actionId = createTargetAndAssignDs();
|
||||
|
||||
assertThat(savedTarget.getTargetInfo().getUpdateStatus()).isEqualTo(TargetUpdateStatus.UNKNOWN);
|
||||
simulateIntermediateStatusOnUpdate(actionId);
|
||||
|
||||
savedTarget = assignDistributionSet(ds.getId(), savedTarget.getControllerId()).getAssignedEntity().iterator()
|
||||
.next();
|
||||
final JpaAction savedAction = (JpaAction) deploymentManagement
|
||||
.findActiveActionsByTarget(savedTarget.getControllerId()).get(0);
|
||||
controllerManagament
|
||||
.addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.FINISHED));
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.IN_SYNC,
|
||||
Action.Status.FINISHED, Action.Status.FINISHED, false);
|
||||
|
||||
assertThat(targetManagement.findTargetByControllerID(savedTarget.getControllerId()).getTargetInfo()
|
||||
.getUpdateStatus()).isEqualTo(TargetUpdateStatus.PENDING);
|
||||
assertThat(actionStatusRepository.count()).isEqualTo(6);
|
||||
assertThat(deploymentManagement.findActionStatusByAction(pageReq, actionId).getNumberOfElements()).isEqualTo(6);
|
||||
}
|
||||
|
||||
controllerManagament.addUpdateActionStatus(
|
||||
entityFactory.actionStatus().create(savedAction.getId()).status(Action.Status.RUNNING));
|
||||
@Test
|
||||
@Description("Controller confirms successfull update with FINISHED status on a action that is on canceling. "
|
||||
+ "Reason: The decission to ignore the cancellation is in fact up to the controller.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void controllerConfirmsUpdateWithFinishedAndIgnorsCancellationWithThat() {
|
||||
final Long actionId = createTargetAndAssignDs();
|
||||
deploymentManagement.cancelAction(actionId);
|
||||
|
||||
controllerManagament
|
||||
.addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.FINISHED));
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.IN_SYNC,
|
||||
Action.Status.FINISHED, Action.Status.FINISHED, false);
|
||||
|
||||
assertThat(actionStatusRepository.count()).isEqualTo(3);
|
||||
assertThat(deploymentManagement.findActionStatusByAction(pageReq, actionId).getNumberOfElements()).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Update server rejects cancelation feedback if action is not in CANCELING state.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void cancellationFeedbackRejectedIfActionIsNotInCanceling() {
|
||||
final Long actionId = createTargetAndAssignDs();
|
||||
|
||||
try {
|
||||
controllerManagament.addCancelActionStatus(
|
||||
entityFactory.actionStatus().create(actionId).status(Action.Status.FINISHED));
|
||||
fail("Expected " + CancelActionNotAllowedException.class.getName());
|
||||
} catch (final CancelActionNotAllowedException e) {
|
||||
// expected
|
||||
}
|
||||
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING,
|
||||
Action.Status.RUNNING, Action.Status.RUNNING, true);
|
||||
|
||||
assertThat(actionStatusRepository.count()).isEqualTo(1);
|
||||
assertThat(deploymentManagement.findActionStatusByAction(pageReq, actionId).getNumberOfElements()).isEqualTo(1);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Controller confirms action cancelation with FINISHED status.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void controllerConfirmsActionCancelationWithFinished() {
|
||||
final Long actionId = createTargetAndAssignDs();
|
||||
|
||||
deploymentManagement.cancelAction(actionId);
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING,
|
||||
Action.Status.CANCELING, Action.Status.CANCELING, true);
|
||||
|
||||
simulateIntermediateStatusOnCancellation(actionId);
|
||||
|
||||
controllerManagament
|
||||
.addCancelActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.FINISHED));
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.IN_SYNC,
|
||||
Action.Status.CANCELED, Action.Status.FINISHED, false);
|
||||
|
||||
assertThat(actionStatusRepository.count()).isEqualTo(7);
|
||||
assertThat(deploymentManagement.findActionStatusByAction(pageReq, actionId).getNumberOfElements()).isEqualTo(7);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Controller confirms action cancelation with FINISHED status.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void controllerConfirmsActionCancelationWithCanceled() {
|
||||
final Long actionId = createTargetAndAssignDs();
|
||||
|
||||
deploymentManagement.cancelAction(actionId);
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING,
|
||||
Action.Status.CANCELING, Action.Status.CANCELING, true);
|
||||
|
||||
simulateIntermediateStatusOnCancellation(actionId);
|
||||
|
||||
controllerManagament
|
||||
.addCancelActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.CANCELED));
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.IN_SYNC,
|
||||
Action.Status.CANCELED, Action.Status.CANCELED, false);
|
||||
|
||||
assertThat(actionStatusRepository.count()).isEqualTo(7);
|
||||
assertThat(deploymentManagement.findActionStatusByAction(pageReq, actionId).getNumberOfElements()).isEqualTo(7);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Controller rejects action cancelation with CANCEL_REJECTED status. Action goes back to RUNNING status as it expects "
|
||||
+ "that the controller will continue the original update.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void controllerRejectsActionCancelationWithReject() {
|
||||
final Long actionId = createTargetAndAssignDs();
|
||||
|
||||
deploymentManagement.cancelAction(actionId);
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING,
|
||||
Action.Status.CANCELING, Action.Status.CANCELING, true);
|
||||
|
||||
simulateIntermediateStatusOnCancellation(actionId);
|
||||
|
||||
controllerManagament.addCancelActionStatus(
|
||||
entityFactory.actionStatus().create(actionId).status(Action.Status.CANCEL_REJECTED));
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING,
|
||||
Action.Status.RUNNING, Action.Status.CANCEL_REJECTED, true);
|
||||
|
||||
assertThat(actionStatusRepository.count()).isEqualTo(7);
|
||||
assertThat(deploymentManagement.findActionStatusByAction(pageReq, actionId).getNumberOfElements()).isEqualTo(7);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Controller rejects action cancelation with ERROR status. Action goes back to RUNNING status as it expects "
|
||||
+ "that the controller will continue the original update.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void controllerRejectsActionCancelationWithError() {
|
||||
final Long actionId = createTargetAndAssignDs();
|
||||
|
||||
deploymentManagement.cancelAction(actionId);
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING,
|
||||
Action.Status.CANCELING, Action.Status.CANCELING, true);
|
||||
|
||||
simulateIntermediateStatusOnCancellation(actionId);
|
||||
|
||||
controllerManagament
|
||||
.addCancelActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.ERROR));
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING,
|
||||
Action.Status.RUNNING, Action.Status.ERROR, true);
|
||||
|
||||
assertThat(actionStatusRepository.count()).isEqualTo(7);
|
||||
assertThat(deploymentManagement.findActionStatusByAction(pageReq, actionId).getNumberOfElements()).isEqualTo(7);
|
||||
}
|
||||
|
||||
@Step
|
||||
private Long createTargetAndAssignDs() {
|
||||
final Long dsId = testdataFactory.createDistributionSet().getId();
|
||||
testdataFactory.createTarget();
|
||||
assignDistributionSet(dsId, TestdataFactory.DEFAULT_CONTROLLER_ID);
|
||||
assertThat(targetManagement.findTargetByControllerID(TestdataFactory.DEFAULT_CONTROLLER_ID).getTargetInfo()
|
||||
.getUpdateStatus()).isEqualTo(TargetUpdateStatus.PENDING);
|
||||
|
||||
controllerManagament.addUpdateActionStatus(
|
||||
entityFactory.actionStatus().create(savedAction.getId()).status(Action.Status.FINISHED));
|
||||
assertThat(targetManagement.findTargetByControllerID(TestdataFactory.DEFAULT_CONTROLLER_ID).getTargetInfo()
|
||||
.getUpdateStatus()).isEqualTo(TargetUpdateStatus.IN_SYNC);
|
||||
return deploymentManagement.findActiveActionsByTarget(TestdataFactory.DEFAULT_CONTROLLER_ID).get(0).getId();
|
||||
}
|
||||
|
||||
@Step
|
||||
private void simulateIntermediateStatusOnCancellation(final Long actionId) {
|
||||
controllerManagament
|
||||
.addCancelActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.RUNNING));
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING,
|
||||
Action.Status.CANCELING, Action.Status.RUNNING, true);
|
||||
|
||||
controllerManagament
|
||||
.addCancelActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.DOWNLOAD));
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING,
|
||||
Action.Status.CANCELING, Action.Status.DOWNLOAD, true);
|
||||
|
||||
controllerManagament
|
||||
.addCancelActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.RETRIEVED));
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING,
|
||||
Action.Status.CANCELING, Action.Status.RETRIEVED, true);
|
||||
|
||||
controllerManagament
|
||||
.addCancelActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.WARNING));
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING,
|
||||
Action.Status.CANCELING, Action.Status.WARNING, true);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void simulateIntermediateStatusOnUpdate(final Long actionId) {
|
||||
controllerManagament
|
||||
.addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.RUNNING));
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING,
|
||||
Action.Status.RUNNING, Action.Status.RUNNING, true);
|
||||
|
||||
controllerManagament
|
||||
.addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.DOWNLOAD));
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING,
|
||||
Action.Status.RUNNING, Action.Status.DOWNLOAD, true);
|
||||
|
||||
controllerManagament
|
||||
.addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.RETRIEVED));
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING,
|
||||
Action.Status.RUNNING, Action.Status.RETRIEVED, true);
|
||||
|
||||
controllerManagament
|
||||
.addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.WARNING));
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING,
|
||||
Action.Status.RUNNING, Action.Status.WARNING, true);
|
||||
}
|
||||
|
||||
private void assertActionStatus(final Long actionId, final String controllerId,
|
||||
final TargetUpdateStatus expectedTargetUpdateStatus, final Action.Status expectedActionActionStatus,
|
||||
final Action.Status expectedActionStatus, final boolean actionActive) {
|
||||
final TargetUpdateStatus targetStatus = targetManagement.findTargetByControllerID(controllerId).getTargetInfo()
|
||||
.getUpdateStatus();
|
||||
assertThat(targetStatus).isEqualTo(expectedTargetUpdateStatus);
|
||||
final Action action = deploymentManagement.findAction(actionId);
|
||||
assertThat(action.getStatus()).isEqualTo(expectedActionActionStatus);
|
||||
assertThat(action.isActive()).isEqualTo(actionActive);
|
||||
final List<ActionStatus> actionStatusList = deploymentManagement.findActionStatusByAction(pageReq, actionId)
|
||||
.getContent();
|
||||
assertThat(actionStatusList.get(actionStatusList.size() - 1).getStatus()).isEqualTo(expectedActionStatus);
|
||||
|
||||
assertThat(actionStatusRepository.findAll(pageReq).getNumberOfElements()).isEqualTo(3);
|
||||
assertThat(deploymentManagement.findActionStatusByAction(pageReq, savedAction.getId()).getNumberOfElements())
|
||||
.isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -123,7 +346,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("Register a controller which does not exist")
|
||||
public void testfindOrRegisterTargetIfItDoesNotexist() {
|
||||
public void findOrRegisterTargetIfItDoesNotexist() {
|
||||
final Target target = controllerManagament.findOrRegisterTargetIfItDoesNotexist("AA", null);
|
||||
assertThat(target).as("target should not be null").isNotNull();
|
||||
|
||||
@@ -142,47 +365,94 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("Controller trys to finish an update process after it has been finished by an error action status.")
|
||||
public void tryToFinishUpdateProcessMoreThanOnce() {
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
Target savedTarget = testdataFactory.createTarget();
|
||||
savedTarget = assignDistributionSet(ds.getId(), savedTarget.getControllerId()).getAssignedEntity().iterator()
|
||||
.next();
|
||||
Action savedAction = deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId()).get(0);
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@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 = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void tryToFinishWithErrorUpdateProcessMoreThanOnce() {
|
||||
final Long actionId = createTargetAndAssignDs();
|
||||
|
||||
// test and verify
|
||||
savedAction = controllerManagament.addUpdateActionStatus(
|
||||
entityFactory.actionStatus().create(savedAction.getId()).status(Action.Status.RUNNING));
|
||||
assertThat(targetManagement.findTargetByControllerID(TestdataFactory.DEFAULT_CONTROLLER_ID).getTargetInfo()
|
||||
.getUpdateStatus()).isEqualTo(TargetUpdateStatus.PENDING);
|
||||
controllerManagament
|
||||
.addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.RUNNING));
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING,
|
||||
Action.Status.RUNNING, Action.Status.RUNNING, true);
|
||||
|
||||
savedAction = controllerManagament.addUpdateActionStatus(
|
||||
entityFactory.actionStatus().create(savedAction.getId()).status(Action.Status.ERROR));
|
||||
assertThat(targetManagement.findTargetByControllerID(TestdataFactory.DEFAULT_CONTROLLER_ID).getTargetInfo()
|
||||
.getUpdateStatus()).isEqualTo(TargetUpdateStatus.ERROR);
|
||||
controllerManagament
|
||||
.addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.ERROR));
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.ERROR,
|
||||
Action.Status.ERROR, Action.Status.ERROR, false);
|
||||
|
||||
// try with disabled late feedback
|
||||
repositoryProperties.setRejectActionStatusForClosedAction(true);
|
||||
savedAction = controllerManagament.addUpdateActionStatus(
|
||||
entityFactory.actionStatus().create(savedAction.getId()).status(Action.Status.FINISHED));
|
||||
controllerManagament
|
||||
.addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.FINISHED));
|
||||
|
||||
// test
|
||||
assertThat(targetManagement.findTargetByControllerID(TestdataFactory.DEFAULT_CONTROLLER_ID).getTargetInfo()
|
||||
.getUpdateStatus()).isEqualTo(TargetUpdateStatus.ERROR);
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.ERROR,
|
||||
Action.Status.ERROR, Action.Status.ERROR, false);
|
||||
|
||||
// try with enabled late feedback
|
||||
// try with enabled late feedback - should not make a difference as it
|
||||
// only allows intermediate feedbacks and not multiple close
|
||||
repositoryProperties.setRejectActionStatusForClosedAction(false);
|
||||
controllerManagament.addUpdateActionStatus(
|
||||
entityFactory.actionStatus().create(savedAction.getId()).status(Action.Status.FINISHED));
|
||||
controllerManagament
|
||||
.addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.FINISHED));
|
||||
|
||||
// test
|
||||
assertThat(targetManagement.findTargetByControllerID(TestdataFactory.DEFAULT_CONTROLLER_ID).getTargetInfo()
|
||||
.getUpdateStatus()).isEqualTo(TargetUpdateStatus.ERROR);
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.ERROR,
|
||||
Action.Status.ERROR, Action.Status.ERROR, false);
|
||||
|
||||
assertThat(actionStatusRepository.count()).isEqualTo(3);
|
||||
assertThat(deploymentManagement.findActionStatusByAction(pageReq, actionId).getNumberOfElements()).isEqualTo(3);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Controller trys to finish an update process after it has been finished by an FINISHED action status.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@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 = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void tryToFinishUpdateProcessMoreThanOnce() {
|
||||
final Long actionId = prepareFinishedUpdate().getId();
|
||||
|
||||
// try with disabled late feedback
|
||||
repositoryProperties.setRejectActionStatusForClosedAction(true);
|
||||
controllerManagament
|
||||
.addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.FINISHED));
|
||||
|
||||
// test
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.IN_SYNC,
|
||||
Action.Status.FINISHED, Action.Status.FINISHED, false);
|
||||
|
||||
// try with enabled late feedback - should not make a difference as it
|
||||
// only allows intermediate feedbacks and not multiple close
|
||||
repositoryProperties.setRejectActionStatusForClosedAction(false);
|
||||
controllerManagament
|
||||
.addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.FINISHED));
|
||||
|
||||
// test
|
||||
assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.IN_SYNC,
|
||||
Action.Status.FINISHED, Action.Status.FINISHED, false);
|
||||
|
||||
assertThat(actionStatusRepository.count()).isEqualTo(3);
|
||||
assertThat(deploymentManagement.findActionStatusByAction(pageReq, actionId).getNumberOfElements()).isEqualTo(3);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Controller trys to send an update feedback after it has been finished which is reject as the repository is "
|
||||
+ "configured to reject that.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@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 = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void sendUpdatesForFinishUpdateProcessDropedIfDisabled() {
|
||||
repositoryProperties.setRejectActionStatusForClosedAction(true);
|
||||
|
||||
@@ -194,14 +464,21 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
||||
// nothing changed as "feedback after close" is disabled
|
||||
assertThat(targetManagement.findTargetByControllerID(TestdataFactory.DEFAULT_CONTROLLER_ID).getTargetInfo()
|
||||
.getUpdateStatus()).isEqualTo(TargetUpdateStatus.IN_SYNC);
|
||||
assertThat(actionStatusRepository.findAll(pageReq).getNumberOfElements()).isEqualTo(3);
|
||||
|
||||
assertThat(actionStatusRepository.count()).isEqualTo(3);
|
||||
assertThat(deploymentManagement.findActionStatusByAction(pageReq, action.getId()).getNumberOfElements())
|
||||
.isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Controller trys to send an update feedback after it has been finished which is actepted as the repository is "
|
||||
@Description("Controller trys to send an update feedback after it has been finished which is accepted as the repository is "
|
||||
+ "configured to accept them.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@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 = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void sendUpdatesForFinishUpdateProcessAcceptedIfEnabled() {
|
||||
repositoryProperties.setRejectActionStatusForClosedAction(false);
|
||||
|
||||
@@ -212,9 +489,58 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
||||
// nothing changed as "feedback after close" is disabled
|
||||
assertThat(targetManagement.findTargetByControllerID(TestdataFactory.DEFAULT_CONTROLLER_ID).getTargetInfo()
|
||||
.getUpdateStatus()).isEqualTo(TargetUpdateStatus.IN_SYNC);
|
||||
|
||||
// however, additional action status has been stored
|
||||
assertThat(actionStatusRepository.findAll(pageReq).getNumberOfElements()).isEqualTo(4);
|
||||
assertThat(deploymentManagement.findActionStatusByAction(pageReq, action.getId()).getNumberOfElements())
|
||||
.isEqualTo(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that target attribute update is reflected by the repository.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 3) })
|
||||
public void updateTargetAttributes() {
|
||||
final String controllerId = "test123";
|
||||
testdataFactory.createTarget(controllerId);
|
||||
addAttributeAndVerify(controllerId);
|
||||
addSecondAttributeAndVerify(controllerId);
|
||||
updateAttributeAndVerify(controllerId);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void addAttributeAndVerify(final String controllerId) {
|
||||
final Map<String, String> testData = Maps.newHashMapWithExpectedSize(1);
|
||||
testData.put("test1", "testdata1");
|
||||
controllerManagament.updateControllerAttributes(controllerId, testData);
|
||||
|
||||
final Target target = targetManagement.findTargetByControllerIDWithDetails(controllerId);
|
||||
assertThat(target.getTargetInfo().getControllerAttributes()).as("Controller Attributes are wrong")
|
||||
.isEqualTo(testData);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void addSecondAttributeAndVerify(final String controllerId) {
|
||||
final Map<String, String> testData = Maps.newHashMapWithExpectedSize(2);
|
||||
testData.put("test2", "testdata20");
|
||||
controllerManagament.updateControllerAttributes(controllerId, testData);
|
||||
|
||||
final Target target = targetManagement.findTargetByControllerIDWithDetails(controllerId);
|
||||
testData.put("test1", "testdata1");
|
||||
assertThat(target.getTargetInfo().getControllerAttributes()).as("Controller Attributes are wrong")
|
||||
.isEqualTo(testData);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void updateAttributeAndVerify(final String controllerId) {
|
||||
final Map<String, String> testData = Maps.newHashMapWithExpectedSize(2);
|
||||
testData.put("test1", "testdata12");
|
||||
|
||||
controllerManagament.updateControllerAttributes(controllerId, testData);
|
||||
|
||||
final Target target = targetManagement.findTargetByControllerIDWithDetails(controllerId);
|
||||
testData.put("test2", "testdata20");
|
||||
assertThat(target.getTargetInfo().getControllerAttributes()).as("Controller Attributes are wrong")
|
||||
.isEqualTo(testData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,11 +54,9 @@ import org.springframework.data.domain.PageRequest;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
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;
|
||||
|
||||
@Features("Component Tests - Repository")
|
||||
@@ -245,54 +243,6 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that target attribute update is reflected by the repository.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 3) })
|
||||
public void updateTargetAttributes() {
|
||||
final String controllerId = "test123";
|
||||
testdataFactory.createTarget(controllerId);
|
||||
addAttributeAndVerify(controllerId);
|
||||
addSecondAttributeAndVerify(controllerId);
|
||||
updateAttributeAndVerify(controllerId);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void addAttributeAndVerify(final String controllerId) {
|
||||
final Map<String, String> testData = Maps.newHashMapWithExpectedSize(1);
|
||||
testData.put("test1", "testdata1");
|
||||
controllerManagament.updateControllerAttributes(controllerId, testData);
|
||||
|
||||
final Target target = targetManagement.findTargetByControllerIDWithDetails(controllerId);
|
||||
assertThat(target.getTargetInfo().getControllerAttributes()).as("Controller Attributes are wrong")
|
||||
.isEqualTo(testData);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void addSecondAttributeAndVerify(final String controllerId) {
|
||||
final Map<String, String> testData = Maps.newHashMapWithExpectedSize(2);
|
||||
testData.put("test2", "testdata20");
|
||||
controllerManagament.updateControllerAttributes(controllerId, testData);
|
||||
|
||||
final Target target = targetManagement.findTargetByControllerIDWithDetails(controllerId);
|
||||
testData.put("test1", "testdata1");
|
||||
assertThat(target.getTargetInfo().getControllerAttributes()).as("Controller Attributes are wrong")
|
||||
.isEqualTo(testData);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void updateAttributeAndVerify(final String controllerId) {
|
||||
final Map<String, String> testData = Maps.newHashMapWithExpectedSize(2);
|
||||
testData.put("test1", "testdata12");
|
||||
|
||||
controllerManagament.updateControllerAttributes(controllerId, testData);
|
||||
|
||||
final Target target = targetManagement.findTargetByControllerIDWithDetails(controllerId);
|
||||
testData.put("test2", "testdata20");
|
||||
assertThat(target.getTargetInfo().getControllerAttributes()).as("Controller Attributes are wrong")
|
||||
.isEqualTo(testData);
|
||||
}
|
||||
|
||||
private Target createTargetWithAttributes(final String controllerId) {
|
||||
final Map<String, String> testData = new HashMap<>();
|
||||
testData.put("test1", "testdata1");
|
||||
|
||||
@@ -78,6 +78,8 @@ import org.springframework.core.env.Environment;
|
||||
import org.springframework.data.auditing.AuditingHandler;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.annotation.DirtiesContext.ClassMode;
|
||||
@@ -104,7 +106,7 @@ import com.google.common.collect.Lists;
|
||||
public abstract class AbstractIntegrationTest implements EnvironmentAware {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AbstractIntegrationTest.class);
|
||||
|
||||
protected static final Pageable pageReq = new PageRequest(0, 400);
|
||||
protected static final Pageable pageReq = new PageRequest(0, 400, new Sort(Direction.ASC, "id"));
|
||||
|
||||
/**
|
||||
* Constant for MediaType HAL with encoding UTF-8. Necessary since Spring
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.test.util;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.SecureRandom;
|
||||
@@ -44,6 +46,7 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
|
||||
@@ -498,7 +501,9 @@ public class TestdataFactory {
|
||||
* @return persisted {@link Target}
|
||||
*/
|
||||
public Target createTarget(final String controllerId) {
|
||||
return targetManagement.createTarget(entityFactory.target().create().controllerId(controllerId));
|
||||
final Target target = targetManagement.createTarget(entityFactory.target().create().controllerId(controllerId));
|
||||
assertThat(target.getTargetInfo().getUpdateStatus()).isEqualTo(TargetUpdateStatus.UNKNOWN);
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
|
||||
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
||||
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
||||
import org.eclipse.hawkbit.ui.utils.UINotification;
|
||||
import org.slf4j.Logger;
|
||||
@@ -72,7 +73,6 @@ public class ActionHistoryTable extends TreeTable {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ActionHistoryTable.class);
|
||||
private static final String BUTTON_CANCEL = "button.cancel";
|
||||
private static final String BUTTON_OK = "button.ok";
|
||||
private static final String STATUS_ICON_GREEN = "statusIconGreen";
|
||||
|
||||
private final I18N i18n;
|
||||
private final transient DeploymentManagement deploymentManagement;
|
||||
@@ -504,50 +504,21 @@ public class ActionHistoryTable extends TreeTable {
|
||||
*/
|
||||
private Label getStatusIcon(final Action.Status status) {
|
||||
final Label label = new LabelBuilder().name("").buildLabel();
|
||||
final String statusIconPending = "statusIconPending";
|
||||
label.setContentMode(ContentMode.HTML);
|
||||
if (Action.Status.FINISHED == status) {
|
||||
label.setDescription(i18n.get("label.finished"));
|
||||
label.setStyleName(STATUS_ICON_GREEN);
|
||||
label.setValue(FontAwesome.CHECK_CIRCLE.getHtml());
|
||||
} else if (Action.Status.ERROR == status) {
|
||||
label.setDescription(i18n.get("label.error"));
|
||||
label.setStyleName("statusIconRed");
|
||||
label.setValue(FontAwesome.EXCLAMATION_CIRCLE.getHtml());
|
||||
} else if (Action.Status.WARNING == status) {
|
||||
label.setStyleName("statusIconOrange");
|
||||
label.setDescription(i18n.get("label.warning"));
|
||||
label.setValue(FontAwesome.EXCLAMATION_CIRCLE.getHtml());
|
||||
} else if (Action.Status.RUNNING == status) {
|
||||
// dynamic spinner
|
||||
label.setStyleName(statusIconPending);
|
||||
label.setDescription(i18n.get("label.running"));
|
||||
label.setValue(FontAwesome.ADJUST.getHtml());
|
||||
} else if (Action.Status.CANCELING == status) {
|
||||
label.setStyleName(statusIconPending);
|
||||
label.setDescription(i18n.get("label.cancelling"));
|
||||
label.setValue(FontAwesome.TIMES_CIRCLE.getHtml());
|
||||
} else if (Action.Status.CANCELED == status) {
|
||||
label.setStyleName(statusIconPending);
|
||||
label.setDescription(i18n.get("label.cancelled"));
|
||||
label.setStyleName(STATUS_ICON_GREEN);
|
||||
label.setValue(FontAwesome.TIMES_CIRCLE.getHtml());
|
||||
} else if (Action.Status.RETRIEVED == status) {
|
||||
label.setStyleName(statusIconPending);
|
||||
label.setDescription(i18n.get("label.retrieved"));
|
||||
label.setValue(FontAwesome.CIRCLE_O.getHtml());
|
||||
} else if (Action.Status.DOWNLOAD == status) {
|
||||
label.setStyleName(statusIconPending);
|
||||
label.setDescription(i18n.get("label.download"));
|
||||
label.setValue(FontAwesome.CLOUD_DOWNLOAD.getHtml());
|
||||
} else if (Action.Status.SCHEDULED == status) {
|
||||
label.setStyleName(statusIconPending);
|
||||
label.setDescription(i18n.get("label.scheduled"));
|
||||
label.setValue(FontAwesome.HOURGLASS_1.getHtml());
|
||||
} else {
|
||||
|
||||
final ActionStatusIconMapper mapping = ActionStatusIconMapper.MAPPINGS.get(status);
|
||||
|
||||
if (mapping == null) {
|
||||
LOG.error("Unknown status icon mapping");
|
||||
label.setDescription("");
|
||||
label.setValue("");
|
||||
return label;
|
||||
}
|
||||
|
||||
label.setDescription(i18n.get(mapping.getDescriptionI18N()));
|
||||
label.setStyleName(mapping.getStyleName());
|
||||
label.setValue(mapping.getIcon().getHtml());
|
||||
|
||||
return label;
|
||||
|
||||
}
|
||||
@@ -568,7 +539,7 @@ public class ActionHistoryTable extends TreeTable {
|
||||
|
||||
if (actionWithActiveStatus.isHitAutoForceTime(currentTimeMillis)) {
|
||||
autoForceLabel.setDescription("autoforced");
|
||||
autoForceLabel.setStyleName(STATUS_ICON_GREEN);
|
||||
autoForceLabel.setStyleName(SPUIStyleDefinitions.STATUS_ICON_GREEN);
|
||||
autoForceLabel.setDescription("auto forced since " + SPDateTimeUtil
|
||||
.getDurationFormattedString(actionWithActiveStatus.getForcedTime(), currentTimeMillis, i18n));
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.ui.management.actionhistory;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.vaadin.server.FontAwesome;
|
||||
|
||||
/**
|
||||
* Mapping utility for {@link ActionStatus} to icon in action history table.
|
||||
*
|
||||
*/
|
||||
public final class ActionStatusIconMapper {
|
||||
static final Map<Action.Status, ActionStatusIconMapper> MAPPINGS = Maps.newHashMapWithExpectedSize(10);
|
||||
|
||||
static {
|
||||
MAPPINGS.put(Action.Status.FINISHED, new ActionStatusIconMapper("label.finished",
|
||||
SPUIStyleDefinitions.STATUS_ICON_GREEN, FontAwesome.CHECK_CIRCLE));
|
||||
MAPPINGS.put(Action.Status.CANCELED, new ActionStatusIconMapper("label.cancelled",
|
||||
SPUIStyleDefinitions.STATUS_ICON_GREEN, FontAwesome.TIMES_CIRCLE));
|
||||
|
||||
MAPPINGS.put(Action.Status.ERROR, new ActionStatusIconMapper("label.error",
|
||||
SPUIStyleDefinitions.STATUS_ICON_RED, FontAwesome.EXCLAMATION_CIRCLE));
|
||||
|
||||
MAPPINGS.put(Action.Status.WARNING, new ActionStatusIconMapper("label.warning",
|
||||
SPUIStyleDefinitions.STATUS_ICON_ORANGE, FontAwesome.EXCLAMATION_CIRCLE));
|
||||
MAPPINGS.put(Action.Status.CANCEL_REJECTED, new ActionStatusIconMapper("label.warning",
|
||||
SPUIStyleDefinitions.STATUS_ICON_ORANGE, FontAwesome.EXCLAMATION_CIRCLE));
|
||||
|
||||
MAPPINGS.put(Action.Status.RUNNING, new ActionStatusIconMapper("label.running",
|
||||
SPUIStyleDefinitions.STATUS_ICON_PENDING, FontAwesome.ADJUST));
|
||||
MAPPINGS.put(Action.Status.CANCELING, new ActionStatusIconMapper("label.cancelling",
|
||||
SPUIStyleDefinitions.STATUS_ICON_PENDING, FontAwesome.TIMES_CIRCLE));
|
||||
MAPPINGS.put(Action.Status.RETRIEVED, new ActionStatusIconMapper("label.retrieved",
|
||||
SPUIStyleDefinitions.STATUS_ICON_PENDING, FontAwesome.CIRCLE_O));
|
||||
MAPPINGS.put(Action.Status.DOWNLOAD, new ActionStatusIconMapper("label.download",
|
||||
SPUIStyleDefinitions.STATUS_ICON_PENDING, FontAwesome.CLOUD_DOWNLOAD));
|
||||
MAPPINGS.put(Action.Status.SCHEDULED, new ActionStatusIconMapper("label.scheduled",
|
||||
SPUIStyleDefinitions.STATUS_ICON_PENDING, FontAwesome.HOURGLASS_1));
|
||||
}
|
||||
|
||||
private final String descriptionI18N;
|
||||
private final String styleName;
|
||||
private final FontAwesome icon;
|
||||
|
||||
private ActionStatusIconMapper(final String descriptionI18N, final String styleName, final FontAwesome icon) {
|
||||
this.descriptionI18N = descriptionI18N;
|
||||
this.styleName = styleName;
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
String getDescriptionI18N() {
|
||||
return descriptionI18N;
|
||||
}
|
||||
|
||||
String getStyleName() {
|
||||
return styleName;
|
||||
}
|
||||
|
||||
FontAwesome getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -183,6 +183,11 @@ public final class SPUIStyleDefinitions {
|
||||
*/
|
||||
public static final String STATUS_ICON_RED = "statusIconRed";
|
||||
|
||||
/**
|
||||
* Status icon style - orange color.
|
||||
*/
|
||||
public static final String STATUS_ICON_ORANGE = "statusIconOrange";
|
||||
|
||||
/**
|
||||
* Status icon style - green color.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user