public AutomationCompositionRollback(final AutomationCompositionRollback otherAcmRollback) {\r
this.instanceId = otherAcmRollback.instanceId;\r
this.compositionId = otherAcmRollback.compositionId;\r
- this.elements = PfUtils.mapMap(otherAcmRollback.elements, UnaryOperator.identity());\r
+ this.elements = PfUtils.mapMap(otherAcmRollback.elements, AutomationCompositionElement::new);\r
}\r
\r
/**\r
public AutomationCompositionRollback(final AutomationComposition automationComposition) {\r
this.instanceId = automationComposition.getInstanceId();\r
this.compositionId = automationComposition.getCompositionId();\r
- this.elements = PfUtils.mapMap(automationComposition.getElements(), UnaryOperator.identity());\r
+ this.elements = PfUtils.mapMap(automationComposition.getElements(), AutomationCompositionElement::new);\r
}\r
}\r
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation.
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
DELETE,
UPDATE,
RESTARTING,
- MIGRATE
+ MIGRATE,
+ MIGRATION_REVERT
}
public class AcInstanceStateResolver {
private final StateDefinition<String> graph;
+ // DeployState
private static final String DEPLOYED = DeployState.DEPLOYED.name();
private static final String DEPLOYING = DeployState.DEPLOYING.name();
private static final String UNDEPLOYED = DeployState.UNDEPLOYED.name();
private static final String UPDATING = DeployState.UPDATING.name();
private static final String DELETING = DeployState.DELETING.name();
private static final String MIGRATING = DeployState.MIGRATING.name();
- private static final String MIGRATION_PRECHECKING = SubState.MIGRATION_PRECHECKING.name();
private static final String MIGRATION_REVERTING = DeployState.MIGRATION_REVERTING.name();
+
+ // SubState
+ private static final String MIGRATION_PRECHECKING = SubState.MIGRATION_PRECHECKING.name();
private static final String SUB_STATE_NONE = SubState.NONE.name();
private static final String PREPARING = SubState.PREPARING.name();
private static final String REVIEWING = SubState.REVIEWING.name();
+ // LockState
private static final String LOCKED = LockState.LOCKED.name();
private static final String LOCKING = LockState.LOCKING.name();
private static final String UNLOCKED = LockState.UNLOCKED.name();
private static final String UNLOCKING = LockState.UNLOCKING.name();
private static final String STATE_LOCKED_NONE = LockState.NONE.name();
+ // NONE Order
private static final String DEPLOY_NONE = DeployOrder.NONE.name();
private static final String LOCK_NONE = LockOrder.NONE.name();
private static final String SUB_NONE = SubOrder.NONE.name();
- private static final String NO_ERROR = StateChangeResult.NO_ERROR.name();
- private static final String FAILED = StateChangeResult.FAILED.name();
- private static final String TIMEOUT = StateChangeResult.TIMEOUT.name();
-
- // list of results
+ // DeployOrder
public static final String DEPLOY = DeployOrder.DEPLOY.name();
public static final String UNDEPLOY = DeployOrder.UNDEPLOY.name();
public static final String DELETE = DeployOrder.DELETE.name();
+ public static final String MIGRATE = DeployOrder.MIGRATE.name();
+ public static final String MIGRATION_REVERT = DeployOrder.MIGRATION_REVERT.name();
+ public static final String UPDATE = DeployOrder.UPDATE.name();
+
+ // LockOrder
public static final String LOCK = LockOrder.LOCK.name();
public static final String UNLOCK = LockOrder.UNLOCK.name();
- public static final String MIGRATE = DeployOrder.MIGRATE.name();
+
+ // SubOrder
public static final String MIGRATE_PRECHECK = SubOrder.MIGRATE_PRECHECK.name();
public static final String PREPARE = SubOrder.PREPARE.name();
public static final String REVIEW = SubOrder.REVIEW.name();
- public static final String UPDATE = DeployOrder.UPDATE.name();
+
+ // StateChangeResult
+ private static final String NO_ERROR = StateChangeResult.NO_ERROR.name();
+ private static final String FAILED = StateChangeResult.FAILED.name();
+ private static final String TIMEOUT = StateChangeResult.TIMEOUT.name();
+
public static final String NONE = "NONE";
/**
addSubOrderWithFail(REVIEW, DEPLOYED, LOCKED, REVIEWING);
// rollback
- addDeployOrderWithFail(MIGRATION_REVERTING, MIGRATING, LOCKED, SUB_STATE_NONE);
+ addDeployOrderWithFail(MIGRATION_REVERT, MIGRATING, LOCKED, SUB_STATE_NONE);
addDeployOrderWithFail(UNDEPLOY, MIGRATION_REVERTING, LOCKED, SUB_STATE_NONE);
}
@Transactional(readOnly = true)
public Set<UUID> getAcInstancesInTransition() {
var jpaList = automationCompositionRepository.findByDeployStateIn(List.of(DeployState.DEPLOYING,
- DeployState.UNDEPLOYING, DeployState.DELETING, DeployState.UPDATING, DeployState.MIGRATING));
+ DeployState.UNDEPLOYING, DeployState.DELETING, DeployState.UPDATING, DeployState.MIGRATING,
+ DeployState.MIGRATION_REVERTING));
jpaList.addAll(automationCompositionRepository.findByLockStateIn(
List.of(LockState.LOCKING, LockState.UNLOCKING)));
jpaList.addAll(automationCompositionRepository.findBySubStateIn(
return DeployState.DEPLOYING.equals(deployState) || DeployState.UNDEPLOYING.equals(deployState)
|| LockState.LOCKING.equals(lockState) || LockState.UNLOCKING.equals(lockState)
|| DeployState.DELETING.equals(deployState) || DeployState.UPDATING.equals(deployState)
- || DeployState.MIGRATING.equals(deployState) || !SubState.NONE.equals(subState);
+ || DeployState.MIGRATING.equals(deployState) || DeployState.MIGRATION_REVERTING.equals(deployState)
+ || !SubState.NONE.equals(subState);
}
/**
*/
public static DeployState deployCompleted(DeployState deployState) {
return switch (deployState) {
- case MIGRATING, UPDATING, DEPLOYING -> DeployState.DEPLOYED;
+ case MIGRATING, MIGRATION_REVERTING, UPDATING, DEPLOYING -> DeployState.DEPLOYED;
case UNDEPLOYING -> DeployState.UNDEPLOYED;
case DELETING -> DeployState.DELETED;
default -> deployState;
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2023-2024 Nordix Foundation.
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
assertThat(result).isEqualTo(AcInstanceStateResolver.REVIEW);
// rollback
- result = acTypeStateResolver.resolve(DeployOrder.MIGRATE, LockOrder.NONE, SubOrder.REVIEW,
- DeployState.MIGRATION_REVERTING, LockState.LOCKED, SubState.NONE, StateChangeResult.NO_ERROR);
- assertThat(result).isEqualTo(AcInstanceStateResolver.NONE);
+ result = acTypeStateResolver.resolve(DeployOrder.MIGRATION_REVERT, LockOrder.NONE, SubOrder.NONE,
+ DeployState.MIGRATING, LockState.LOCKED, SubState.NONE, StateChangeResult.FAILED);
+ assertThat(result).isEqualTo(AcInstanceStateResolver.MIGRATION_REVERT);
result = acTypeStateResolver.resolve(DeployOrder.UNDEPLOY, LockOrder.NONE, SubOrder.NONE,
DeployState.MIGRATION_REVERTING, LockState.LOCKED, SubState.NONE, StateChangeResult.FAILED);
var automationCompositionRepository = mock(AutomationCompositionRepository.class);
when(automationCompositionRepository.findByDeployStateIn(List.of(DeployState.DEPLOYING,
- DeployState.UNDEPLOYING, DeployState.DELETING, DeployState.UPDATING, DeployState.MIGRATING)))
+ DeployState.UNDEPLOYING, DeployState.DELETING, DeployState.UPDATING, DeployState.MIGRATING,
+ DeployState.MIGRATION_REVERTING)))
.thenReturn(res1);
when(automationCompositionRepository.findByLockStateIn(List.of(LockState.LOCKING, LockState.UNLOCKING)))
.thenReturn(List.of(inputAutomationCompositionsJpa.get(1)));
assertThat(AcmUtils.isInTransitionalState(DeployState.DELETING, LockState.NONE, SubState.NONE)).isTrue();
assertThat(AcmUtils.isInTransitionalState(DeployState.UPDATING, LockState.LOCKED, SubState.NONE)).isTrue();
assertThat(AcmUtils.isInTransitionalState(DeployState.MIGRATING, LockState.LOCKED, SubState.NONE)).isTrue();
+ assertThat(AcmUtils.isInTransitionalState(DeployState.MIGRATION_REVERTING, LockState.LOCKED,
+ SubState.NONE)).isTrue();
assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.LOCKED,
SubState.MIGRATION_PRECHECKING)).isTrue();
}
var elementsRemoved = updateElementsProperties(automationComposition, acToBeUpdated);
var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionTargetId());
- updateAcForMigration(acToBeUpdated, acDefinition);
+ updateAcForMigration(acToBeUpdated, acDefinition, DeployState.MIGRATING);
var acToPublish = new AutomationComposition(acToBeUpdated);
}
private void updateAcForMigration(AutomationComposition acToBeUpdated,
- AutomationCompositionDefinition acDefinition) {
- AcmUtils.setCascadedState(acToBeUpdated, DeployState.MIGRATING, LockState.LOCKED);
+ AutomationCompositionDefinition acDefinition, DeployState deployState) {
+ AcmUtils.setCascadedState(acToBeUpdated, deployState, LockState.LOCKED);
acToBeUpdated.setStateChangeResult(StateChangeResult.NO_ERROR);
var stage = ParticipantUtils.getFirstStage(acToBeUpdated, acDefinition.getServiceTemplate());
acToBeUpdated.setPhase(stage);
/**
* Rollback AC Instance.
*
- * @param instanceId the instanceId
+ * @param compositionId The UUID of the automation composition definition
+ * @param instanceId The UUID of the automation composition instance
*/
public void rollback(UUID compositionId, UUID instanceId) {
var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
validateCompositionRequested(compositionId, automationComposition);
- var automationCompositionToRollback =
- automationCompositionProvider.getAutomationCompositionRollback(instanceId);
-
- if (DeployState.DEPLOYED.equals(automationComposition.getDeployState())
- && SubState.NONE.equals(automationComposition.getSubState())
- && StateChangeResult.NO_ERROR.equals(automationComposition.getStateChangeResult())) {
- automationComposition.setCompositionId(automationCompositionToRollback.getCompositionId());
- automationComposition.setElements(automationCompositionToRollback.getElements().values().stream()
- .collect(Collectors.toMap(AutomationCompositionElement::getId, UnaryOperator.identity())));
- automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
- AcmUtils.setCascadedState(automationComposition, DeployState.MIGRATION_REVERTING, LockState.LOCKED);
- automationCompositionProvider.updateAutomationComposition(automationComposition);
- } else {
+
+ if (!DeployOrder.MIGRATION_REVERT.name().equals(acInstanceStateResolver.resolve(
+ DeployOrder.MIGRATION_REVERT, LockOrder.NONE,
+ SubOrder.NONE, automationComposition.getDeployState(), automationComposition.getLockState(),
+ automationComposition.getSubState(), automationComposition.getStateChangeResult()))) {
throw new PfModelRuntimeException(Status.BAD_REQUEST, "Invalid state for rollback");
}
+
+ var automationCompositionToRollback =
+ automationCompositionProvider.getAutomationCompositionRollback(instanceId);
+ var acToBeUpdated = new AutomationComposition(automationComposition);
+ acToBeUpdated.setCompositionTargetId(automationCompositionToRollback.getCompositionId());
+ acToBeUpdated.setElements(automationCompositionToRollback.getElements().values().stream()
+ .collect(Collectors.toMap(AutomationCompositionElement::getId, AutomationCompositionElement::new)));
+
+ var acDefinition = acDefinitionProvider.getAcDefinition(acToBeUpdated.getCompositionTargetId());
+ var validationResult =
+ validateAutomationComposition(acToBeUpdated, acToBeUpdated.getCompositionTargetId());
+ if (!validationResult.isValid()) {
+ throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
+ }
+
+ updateAcForMigration(acToBeUpdated, acDefinition, DeployState.MIGRATION_REVERTING);
+ var elementsRemoved = getElementRemoved(automationComposition, acToBeUpdated);
+ automationCompositionProvider.updateAutomationComposition(acToBeUpdated);
+ elementsRemoved.forEach(automationCompositionProvider::deleteAutomationCompositionElement);
+ supervisionAcHandler.migrate(acToBeUpdated);
}
private List<UUID> updateElementsProperties(AutomationComposition automationComposition,
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2023-2024 Nordix Foundation.
+ * Copyright (C) 2023-2025 OpenInfra Foundation Europe. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import io.micrometer.core.annotation.Timed;
import java.util.UUID;
import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
+import org.onap.policy.clamp.models.acm.concepts.DeployState;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionMigration;
import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
import org.onap.policy.clamp.models.acm.utils.AcmUtils;
description = "AUTOMATION_COMPOSITION_MIGRATION messages published")
public void send(AutomationComposition automationComposition, int stage) {
var acMigration = new AutomationCompositionMigration();
+ acMigration.setRollback(DeployState.MIGRATION_REVERTING.equals(automationComposition.getDeployState()));
acMigration.setPrecheck(Boolean.TRUE.equals(automationComposition.getPrecheck()));
acMigration.setCompositionId(automationComposition.getCompositionId());
acMigration.setAutomationCompositionId(automationComposition.getInstanceId());
acMigration.setStage(stage);
acMigration.setParticipantUpdatesList(
AcmUtils.createParticipantDeployList(automationComposition, DeployOrder.MIGRATE));
-
super.send(acMigration);
}
}
automationComposition.getSubState());
var deployState = automationComposition.getDeployState();
- if (DeployState.MIGRATING.equals(automationComposition.getDeployState())) {
+ if (DeployState.MIGRATING.equals(automationComposition.getDeployState())
+ || DeployState.MIGRATION_REVERTING.equals(automationComposition.getDeployState())) {
// migration scenario
automationComposition.setCompositionId(automationComposition.getCompositionTargetId());
automationComposition.setCompositionTargetId(null);
}
if (DeployState.MIGRATING.equals(automationComposition.getDeployState())
+ || DeployState.MIGRATION_REVERTING.equals(automationComposition.getDeployState())
|| SubState.PREPARING.equals(automationComposition.getSubState())) {
stageScanner.scanStage(automationComposition, serviceTemplate, updateSync);
} else if (DeployState.UPDATING.equals(automationComposition.getDeployState())
var toscaNodeTemplate = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates()
.get(element.getDefinition().getName());
var stageSet = DeployState.MIGRATING.equals(automationComposition.getDeployState())
+ || DeployState.MIGRATION_REVERTING.equals(automationComposition.getDeployState())
? ParticipantUtils.findStageSetMigrate(toscaNodeTemplate.getProperties())
: ParticipantUtils.findStageSetPrepare(toscaNodeTemplate.getProperties());
var minStage = stageSet.stream().min(Comparator.comparing(Integer::valueOf)).orElse(0);
}
private void sendNextStage(final AutomationComposition automationComposition, int minStageNotCompleted) {
- if (DeployState.MIGRATING.equals(automationComposition.getDeployState())) {
+ if (DeployState.MIGRATING.equals(automationComposition.getDeployState())
+ || DeployState.MIGRATION_REVERTING.equals(automationComposition.getDeployState())) {
LOGGER.debug("retry message AutomationCompositionMigration");
acMigrationPublisher.send(automationComposition, minStageNotCompleted);
}
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
-import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionRollback;
import org.onap.policy.clamp.models.acm.concepts.DeployState;
import org.onap.policy.clamp.models.acm.concepts.LockState;
import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
element.setId(UUID.randomUUID());
automationCompositionUpdate.getElements().put(element.getId(), element);
}
- acmFromDb.getElements().values().forEach(element -> element.setDeployState(DeployState.DEPLOYED));
+ acmFromDb.getElements().values().forEach(element ->
+ element.setDeployState(DeployState.DEPLOYED));
acmFromDb.setDeployState(DeployState.DEPLOYED);
assertThatThrownBy(
() -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
.thenReturn(automationCompositionUpdate);
var instantiationProvider =
- new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class),
- new AcInstanceStateResolver(), mock(SupervisionAcHandler.class), mock(ParticipantProvider.class),
- mock(AcRuntimeParameterGroup.class), encryptionUtils);
+ new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class),
+ new AcInstanceStateResolver(), mock(SupervisionAcHandler.class),
+ mock(ParticipantProvider.class),
+ mock(AcRuntimeParameterGroup.class), encryptionUtils);
var compositionId = automationCompositionUpdate.getCompositionId();
assertThatThrownBy(
() -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
- .hasMessageMatching(
- "Not allowed to UPDATE in the state " + automationCompositionUpdate.getDeployState());
+ .hasMessageMatching(
+ "Not allowed to UPDATE in the state " + automationCompositionUpdate.getDeployState());
automationCompositionUpdate.setDeployState(DeployState.UPDATING);
automationCompositionUpdate.setLockState(LockState.LOCKED);
automationCompositionUpdate.setCompositionTargetId(UUID.randomUUID());
assertThatThrownBy(
() -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
- .hasMessageMatching(
- "Not allowed to MIGRATE in the state " + automationCompositionUpdate.getDeployState());
+ .hasMessageMatching(
+ "Not allowed to MIGRATE in the state " + automationCompositionUpdate.getDeployState());
}
@Test
AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.LOCKED,
SubState.NONE);
var instantiationResponse = instantiationProvider.updateAutomationComposition(compositionId,
- automationCompositionTarget);
+ automationCompositionTarget);
verify(supervisionAcHandler).migrate(any());
InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationCompositionTarget);
var participantProvider = mock(ParticipantProvider.class);
var encryptionUtils = new EncryptionUtils(CommonTestData.getTestParamaterGroup());
var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
- new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, new AcRuntimeParameterGroup(),
+ new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, new AcRuntimeParameterGroup(),
encryptionUtils);
assertThatThrownBy(() -> instantiationProvider
.updateAutomationComposition(automationComposition.getCompositionId(), automationComposition))
- .hasMessageMatching(
- String.format(AC_DEFINITION_NOT_FOUND, automationComposition.getCompositionTargetId()));
+ .hasMessageMatching(
+ String.format(AC_DEFINITION_NOT_FOUND, automationComposition.getCompositionTargetId()));
var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
var compositionTargetId = acDefinitionTarget.getCompositionId();
when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
var automationComposition =
- InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
+ InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
automationComposition.setCompositionId(compositionId);
automationComposition.setDeployState(DeployState.DEPLOYED);
automationComposition.setLockState(LockState.LOCKED);
automationComposition.setPrecheck(true);
var acProvider = mock(AutomationCompositionProvider.class);
when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
- .thenReturn(automationComposition);
+ .thenReturn(automationComposition);
when(acProvider.updateAutomationComposition(automationComposition)).thenReturn(automationComposition);
var supervisionAcHandler = mock(SupervisionAcHandler.class);
var acmParticipantProvider = mock(ParticipantProvider.class);
var encryptionUtils = mock(EncryptionUtils.class);
var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
- new AcInstanceStateResolver(), supervisionAcHandler, acmParticipantProvider, new AcRuntimeParameterGroup(),
- encryptionUtils);
+ new AcInstanceStateResolver(), supervisionAcHandler, acmParticipantProvider,
+ new AcRuntimeParameterGroup(), encryptionUtils);
assertThatThrownBy(() -> instantiationProvider
- .updateAutomationComposition(automationComposition.getCompositionId(), automationComposition))
- .hasMessageMatching(
- String.format(AC_DEFINITION_NOT_FOUND, automationComposition.getCompositionTargetId()));
+ .updateAutomationComposition(automationComposition.getCompositionId(), automationComposition))
+ .hasMessageMatching(
+ String.format(AC_DEFINITION_NOT_FOUND, automationComposition.getCompositionTargetId()));
var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
var compositionTargetId = acDefinitionTarget.getCompositionId();
automationComposition.setCompositionTargetId(compositionTargetId);
var instantiationResponse = instantiationProvider
- .updateAutomationComposition(automationComposition.getCompositionId(), automationComposition);
+ .updateAutomationComposition(automationComposition.getCompositionId(), automationComposition);
verify(supervisionAcHandler).migratePrecheck(any());
verify(acProvider).updateAutomationComposition(automationComposition);
var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
var compositionId = acDefinition.getCompositionId();
var automationComposition =
- InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Rollback");
+ InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Rollback");
automationComposition.setCompositionId(compositionId);
automationComposition.setInstanceId(UUID.randomUUID());
automationComposition.setDeployState(DeployState.MIGRATION_REVERTING);
var acProvider = mock(AutomationCompositionProvider.class);
when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
- .thenReturn(automationComposition);
+ .thenReturn(automationComposition);
var rollbackRecord = new JpaAutomationCompositionRollback();
when(acProvider.getAutomationCompositionRollback(any(UUID.class))).thenReturn(rollbackRecord.toAuthorative());
final var participantProvider = mock(ParticipantProvider.class);
final var encryptionUtils = new EncryptionUtils(CommonTestData.getTestParamaterGroup());
var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
- new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, new AcRuntimeParameterGroup(),
- encryptionUtils);
+ new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, new AcRuntimeParameterGroup(),
+ encryptionUtils);
var instanceId = automationComposition.getInstanceId();
assertThrows(PfModelRuntimeException.class, () -> instantiationProvider.rollback(compositionId, instanceId));
// DeployState != MIGRATION_REVERTING
when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
- .thenReturn(automationComposition);
+ .thenReturn(automationComposition);
when(acProvider.getAutomationCompositionRollback(any(UUID.class))).thenReturn(rollbackRecord.toAuthorative());
automationComposition.setDeployState(DeployState.DELETING);
@Test
void testRollbackSuccess() {
- final var acDefinitionProvider = mock(AcDefinitionProvider.class);
- final var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
- final var compositionId = acDefinition.getCompositionId();
+ var acDefinitionProvider = mock(AcDefinitionProvider.class);
+ var acDefinition = CommonTestData.createAcDefinition(serviceTemplateMigration, AcTypeState.PRIMED);
+ var compositionId = acDefinition.getCompositionId();
+ when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
var automationComposition =
- InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Rollback");
- automationComposition.setInstanceId(UUID.randomUUID());
+ InstantiationUtils.getAutomationCompositionFromResource(AC_MIGRATE_JSON, "Crud");
+ var instanceId = UUID.randomUUID();
+ automationComposition.setInstanceId(instanceId);
automationComposition.setCompositionId(compositionId);
- automationComposition.setDeployState(DeployState.DEPLOYED);
- automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
+ automationComposition.setDeployState(DeployState.MIGRATING);
+ automationComposition.setLockState(LockState.LOCKED);
+ automationComposition.setStateChangeResult(StateChangeResult.FAILED);
automationComposition.setSubState(SubState.NONE);
- automationComposition.setCompositionTargetId(UUID.randomUUID());
-
var acProvider = mock(AutomationCompositionProvider.class);
- when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
- .thenReturn(automationComposition);
- final var supervisionAcHandler = mock(SupervisionAcHandler.class);
- final var participantProvider = mock(ParticipantProvider.class);
- final var encryptionUtils = new EncryptionUtils(CommonTestData.getTestParamaterGroup());
- final var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider,
- acDefinitionProvider, new AcInstanceStateResolver(), supervisionAcHandler,
- participantProvider, new AcRuntimeParameterGroup(), encryptionUtils);
+ when(acProvider.getAutomationComposition(instanceId)).thenReturn(automationComposition);
+ when(acProvider.updateAutomationComposition(automationComposition)).thenReturn(automationComposition);
- var rollbackRecord = new JpaAutomationCompositionRollback();
- rollbackRecord.setCompositionId(automationComposition.getCompositionId().toString());
+ var acRollback =
+ InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
- when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
- .thenReturn(automationComposition);
- when(acProvider.getAutomationCompositionRollback(any(UUID.class))).thenReturn(rollbackRecord.toAuthorative());
+ var rollbackRecord = new AutomationCompositionRollback();
+ var compositionTargetId = UUID.randomUUID();
+ rollbackRecord.setCompositionId(compositionTargetId);
+ rollbackRecord.setInstanceId(instanceId);
+ rollbackRecord.setElements(acRollback.getElements());
+ when(acProvider.getAutomationCompositionRollback(instanceId)).thenReturn(rollbackRecord);
- instantiationProvider.rollback(compositionId, automationComposition.getInstanceId());
+ var supervisionAcHandler = mock(SupervisionAcHandler.class);
+ var participantProvider = mock(ParticipantProvider.class);
+ var encryptionUtils = new EncryptionUtils(CommonTestData.getTestParamaterGroup());
+ var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
+ new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, new AcRuntimeParameterGroup(),
+ encryptionUtils);
+ assertThatThrownBy(() -> instantiationProvider.rollback(compositionId, instanceId))
+ .hasMessageMatching(String.format(AC_DEFINITION_NOT_FOUND, compositionTargetId));
- verify(acProvider).updateAutomationComposition(automationComposition);
- assertEquals(DeployState.MIGRATION_REVERTING, automationComposition.getDeployState());
+ var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
+ when(acDefinitionProvider.findAcDefinition(compositionTargetId)).thenReturn(Optional.of(acDefinitionTarget));
+ when(acDefinitionProvider.getAcDefinition(compositionTargetId)).thenReturn(acDefinitionTarget);
+
+ instantiationProvider.rollback(compositionId, automationComposition.getInstanceId());
+ verify(acProvider).updateAutomationComposition(any(AutomationComposition.class));
}
private void assertThatDeleteThrownBy(AutomationComposition automationComposition, DeployState deployState,
- LockState lockState) {
+ LockState lockState) {
automationComposition.setDeployState(deployState);
automationComposition.setLockState(lockState);
var acProvider = mock(AutomationCompositionProvider.class);
assertThatThrownBy(
() -> instantiationProvider.createAutomationComposition(compositionId, automationCompositionCreate))
- .hasMessageMatching(automationCompositionCreate.getKey().asIdentifier() + " already defined");
+ .hasMessageMatching(automationCompositionCreate.getKey().asIdentifier() + " already defined");
}
@Test
assertThatThrownBy(
() -> provider.getAutomationComposition(wrongCompositionId, automationComposition.getInstanceId()))
- .hasMessageMatching(compositionId + DO_NOT_MATCH + wrongCompositionId);
+ .hasMessageMatching(compositionId + DO_NOT_MATCH + wrongCompositionId);
assertThatThrownBy(() -> provider.compositionInstanceState(wrongCompositionId,
automationComposition.getInstanceId(), new AcInstanceStateUpdate()))
- .hasMessageMatching(compositionId + DO_NOT_MATCH + wrongCompositionId);
+ .hasMessageMatching(compositionId + DO_NOT_MATCH + wrongCompositionId);
var compositionTargetId = UUID.randomUUID();
automationComposition.setCompositionTargetId(compositionTargetId);
assertThatThrownBy(
() -> provider.getAutomationComposition(wrongCompositionId, automationComposition.getInstanceId()))
- .hasMessageMatching(compositionId + DO_NOT_MATCH + wrongCompositionId);
+ .hasMessageMatching(compositionId + DO_NOT_MATCH + wrongCompositionId);
var result = provider.getAutomationComposition(compositionTargetId, automationComposition.getInstanceId());
assertThat(result).isNotNull();
provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate);
verify(supervisionAcHandler).review(any(AutomationComposition.class));
}
-}
+}
\ No newline at end of file
verify(messageProvider).removeJob(JOB_ID);
}
+ @Test
+ void testSendAutomationCompositionMigrationReverting() {
+ var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
+ automationComposition.setDeployState(DeployState.MIGRATION_REVERTING);
+ automationComposition.setInstanceId(INSTANCE_ID);
+ automationComposition.setCompositionId(COMPOSITION_ID);
+ var compositionTargetId = UUID.randomUUID();
+ automationComposition.setCompositionTargetId(compositionTargetId);
+ automationComposition.setLockState(LockState.LOCKED);
+ automationComposition.setLastMsg(TimestampHelper.now());
+ automationComposition.setPhase(0);
+ for (var element : automationComposition.getElements().values()) {
+ element.setDeployState(DeployState.DEPLOYED);
+ element.setLockState(LockState.LOCKED);
+ }
+
+ var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+ Set<UUID> set = new HashSet<>();
+ set.add(automationComposition.getInstanceId());
+ when(automationCompositionProvider.getAcInstancesInTransition()).thenReturn(set);
+ when(automationCompositionProvider.findAutomationComposition(automationComposition.getInstanceId()))
+ .thenReturn(Optional.of(automationComposition));
+
+ var definitionTarget = createAutomationCompositionDefinition(AcTypeState.PRIMED);
+ definitionTarget.setCompositionId(compositionTargetId);
+ var acDefinitionProvider = createAcDefinitionProvider(AcTypeState.PRIMED);
+ when(acDefinitionProvider.getAcDefinition(compositionTargetId)).thenReturn(definitionTarget);
+ var stageScanner = mock(StageScanner.class);
+
+ var messageProvider = mock(MessageProvider.class);
+ when(messageProvider.createJob(automationComposition.getInstanceId())).thenReturn(Optional.of(JOB_ID));
+ var monitoringScanner = new MonitoringScanner(automationCompositionProvider, acDefinitionProvider,
+ mock(AcDefinitionScanner.class), stageScanner, mock(SimpleScanner.class), mock(PhaseScanner.class),
+ messageProvider);
+ var supervisionScanner = new SupervisionScanner(automationCompositionProvider, acDefinitionProvider,
+ messageProvider, monitoringScanner);
+
+ supervisionScanner.run();
+ verify(stageScanner).scanStage(automationComposition, definitionTarget.getServiceTemplate(),
+ new UpdateSync());
+ verify(messageProvider).removeJob(JOB_ID);
+ }
+
@Test
void testSendAutomationCompositionSimpleScan() {
var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
assertEquals(compositionTargetId, automationComposition.getCompositionId());
}
+ @Test
+ void testSendAutomationCompositionMigrationReverting() {
+ var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
+ automationComposition.setInstanceId(UUID.randomUUID());
+ automationComposition.setDeployState(DeployState.MIGRATION_REVERTING);
+ automationComposition.setCompositionId(COMPOSITION_ID);
+ var compositionTargetId = UUID.randomUUID();
+ automationComposition.setCompositionTargetId(compositionTargetId);
+ automationComposition.setLockState(LockState.LOCKED);
+ automationComposition.setLastMsg(TimestampHelper.now());
+ automationComposition.setPhase(0);
+ for (var element : automationComposition.getElements().values()) {
+ element.setDeployState(DeployState.DEPLOYED);
+ element.setLockState(LockState.LOCKED);
+ }
+ // first element is not migrated yet
+ var element = automationComposition.getElements().entrySet().iterator().next().getValue();
+ element.setDeployState(DeployState.MIGRATION_REVERTING);
+
+ var acProvider = mock(AutomationCompositionProvider.class);
+ when(acProvider.updateAutomationComposition(any())).thenReturn(automationComposition);
+ var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
+ var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
+ var supervisionScanner = new StageScanner(acProvider, mock(ParticipantSyncPublisher.class),
+ mock(AutomationCompositionMigrationPublisher.class), mock(AcPreparePublisher.class),
+ acRuntimeParameterGroup, encryptionUtils);
+ var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
+ supervisionScanner.scanStage(automationComposition, serviceTemplate, new UpdateSync());
+ verify(acProvider, times(0)).updateAutomationComposition(any(AutomationComposition.class));
+ assertEquals(DeployState.MIGRATION_REVERTING, automationComposition.getDeployState());
+
+ // send message for next stage
+ clearInvocations(acProvider);
+ var toscaNodeTemplate = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates()
+ .get(element.getDefinition().getName());
+ toscaNodeTemplate.setProperties(Map.of("stage", List.of(1)));
+
+ supervisionScanner.scanStage(automationComposition, serviceTemplate, new UpdateSync());
+ verify(acProvider).updateAutomationComposition(any(AutomationComposition.class));
+ assertEquals(DeployState.MIGRATION_REVERTING, automationComposition.getDeployState());
+
+ // first element is migrated
+ clearInvocations(acProvider);
+ element.setDeployState(DeployState.DEPLOYED);
+ supervisionScanner.scanStage(automationComposition, serviceTemplate, new UpdateSync());
+ verify(acProvider).updateAutomationComposition(any(AutomationComposition.class));
+
+ assertEquals(DeployState.DEPLOYED, automationComposition.getDeployState());
+ assertEquals(compositionTargetId, automationComposition.getCompositionId());
+ }
+
@Test
void testSendAutomationCompositionPrepare() {
var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");