Add MigrationState validation for migration.
Add set DEFAULT in rollback completed for REMOVED elements.
Issue-ID: POLICY-5515
Change-Id: Ib77b7bac5d78224d21e4ad15157118107ca88f14
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class AcmUtils {
public static final String ENTRY = "entry ";
+ private static final String NOT_VALID_INSTANCE =
+ "Instance cannot be deployed; There are elements in an invalid Migration state."
+ + "(ElementId: %s, MigrationState: %s)";
private static final StringToMapConverter MAP_CONVERTER = new StringToMapConverter();
private static final Logger LOGGER = LoggerFactory.getLogger(AcmUtils.class);
return message;
}
+ /**
+ * Check that the AutomationComposition has all elements in MigrationState as DEFAULT.
+ *
+ * @param automationComposition the AutomationComposition
+ */
+ public static void checkMigrationState(AutomationComposition automationComposition) {
+ var result = automationComposition.getElements().values()
+ .stream()
+ .filter(element -> !MigrationState.DEFAULT.equals(element.getMigrationState()))
+ .findAny();
+ // check if elements are in a valid state to be deployed
+ if (result.isPresent()) {
+ var msg = String.format(NOT_VALID_INSTANCE, result.get().getId(), result.get().getMigrationState());
+ throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, msg);
+ }
+ }
+
/**
* Recursive Merge.
*
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.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
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.AutomationCompositionElement;
+import org.onap.policy.clamp.models.acm.concepts.MigrationState;
import org.onap.policy.clamp.models.acm.document.concepts.DocToscaServiceTemplate;
import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
+import org.onap.policy.models.base.PfModelRuntimeException;
import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
import org.onap.policy.models.tosca.authorative.concepts.ToscaDataType;
import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
assertEquals(message.substring(0, 255), AcmUtils.validatedMessage(message));
}
+ @Test
+ void testCheckMigrationState() {
+ var automationComposition = getDummyAutomationComposition();
+ assertDoesNotThrow(() -> AcmUtils.checkMigrationState(automationComposition));
+ automationComposition.getElements().values().iterator().next().setMigrationState(MigrationState.REMOVED);
+ assertThatThrownBy(() -> AcmUtils.checkMigrationState(automationComposition))
+ .isInstanceOf(PfModelRuntimeException.class);
+ }
+
private AutomationComposition getDummyAutomationComposition() {
var automationComposition = new AutomationComposition();
automationComposition.setCompositionId(UUID.randomUUID());
AutomationCompositionProvider.validateInstanceEndpoint(compositionId, acFromDb);
var acDefinition = acDefinitionProvider.getAcDefinition(compositionId);
AcDefinitionProvider.checkPrimedComposition(acDefinition);
+ AcmUtils.checkMigrationState(acFromDb);
if (DeployState.UNDEPLOYED.equals(acFromDb.getDeployState())) {
LOGGER.info("Updating undeployed instance with id {}", instanceId);
acFromDb.setElements(automationComposition.getElements());
import io.micrometer.core.annotation.Timed;
import io.opentelemetry.context.Context;
-import jakarta.ws.rs.core.Response;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
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.MigrationState;
import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
import org.onap.policy.clamp.models.acm.concepts.SubState;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionDeployAck;
import org.onap.policy.clamp.models.acm.persistence.provider.MessageProvider;
import org.onap.policy.clamp.models.acm.utils.AcmStageUtils;
import org.onap.policy.clamp.models.acm.utils.AcmStateUtils;
+import org.onap.policy.clamp.models.acm.utils.AcmUtils;
import org.onap.policy.clamp.models.acm.utils.TimestampHelper;
-import org.onap.policy.models.base.PfModelRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
*/
public void deploy(AutomationComposition automationComposition, AutomationCompositionDefinition acDefinition) {
LOGGER.info("Deployment request received for instanceID: {}", automationComposition.getInstanceId());
-
- var elements = automationComposition.getElements().values();
- // check if elements are in a valid state to be deployed
- elements.stream().filter(element -> !MigrationState.DEFAULT.equals(element.getMigrationState()))
- .findAny().ifPresent(element -> {
- var msg = String.format("Instance cannot be deployed; There are elements in an invalid Migration state."
- + "(ElementId: %s, MigrationState: %s)", element.getId(), element.getMigrationState());
- LOGGER.warn(msg);
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, msg);
- });
+ AcmUtils.checkMigrationState(automationComposition);
if (StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())
&& DeployState.DEPLOYING.equals(automationComposition.getDeployState())
&& automationComposition.getElements().size() > 1) {
automationComposition.setLastMsg(TimestampHelper.now());
- for (var element : elements) {
+ for (var element : automationComposition.getElements().values()) {
if (!DeployState.DEPLOYED.equals(element.getDeployState())) {
element.setDeployState(DeployState.DEPLOYING);
element.setMessage(null);
|| DeployState.MIGRATION_REVERTING.equals(automationComposition.getDeployState())) {
automationComposition.setCompositionTargetId(null);
for (var acElement : automationComposition.getElements().values()) {
- if (MigrationState.NEW.equals(acElement.getMigrationState())) {
+ if (MigrationState.NEW.equals(acElement.getMigrationState())
+ || MigrationState.REMOVED.equals(acElement.getMigrationState())) {
acElement.setMigrationState(MigrationState.DEFAULT);
}
}
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.MigrationState;
import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
import org.onap.policy.clamp.models.acm.concepts.SubState;
import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AcInstanceStateUpdate;
automationCompositionTarget.setPrecheck(false);
AcmStateUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.LOCKED,
SubState.NONE);
+ automationComposition.getElements().values()
+ .forEach(el -> el.setMigrationState(MigrationState.DEFAULT));
var instantiationResponse = instantiationProvider.updateAutomationComposition(compositionId,
automationCompositionTarget);
import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
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.MigrationState;
import org.onap.policy.clamp.models.acm.concepts.SubState;
import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
import org.onap.policy.clamp.models.acm.utils.TimestampHelper;
// first element is migrated
clearInvocations(acProvider);
element.setDeployState(DeployState.DEPLOYED);
+ element.setMigrationState(MigrationState.REMOVED);
supervisionScanner.scanStage(automationComposition, acDefinition, new UpdateSync(), UUID.randomUUID());
verify(acProvider).updateAutomationComposition(any(AutomationComposition.class));
+ assertEquals(MigrationState.DEFAULT, element.getMigrationState());
assertEquals(DeployState.DEPLOYED, automationComposition.getDeployState());
}