From ebb4d0cf867d752ae148880dd0109fc3cf6d6025 Mon Sep 17 00:00:00 2001 From: FrancescoFioraEst Date: Wed, 31 May 2023 16:38:22 +0100 Subject: Add Failure handling support in the ACM-R Issue-ID: POLICY-4705 Change-Id: I919b7981cdbe69ac7ce703fceb2e980a6d9a056e Signed-off-by: FrancescoFioraEst --- ...AutomationCompositionInstantiationProvider.java | 30 ++++---- .../runtime/supervision/SupervisionAcHandler.java | 83 ++++++++++++++++++---- .../runtime/supervision/SupervisionScanner.java | 5 ++ 3 files changed, 89 insertions(+), 29 deletions(-) (limited to 'runtime-acm/src/main') diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java index 787547860..eb0c9b7d2 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java @@ -21,8 +21,6 @@ package org.onap.policy.clamp.acm.runtime.instantiation; - -import java.util.Map; import java.util.UUID; import javax.validation.Valid; import javax.ws.rs.core.Response; @@ -31,7 +29,6 @@ import lombok.AllArgsConstructor; import org.onap.policy.clamp.acm.runtime.supervision.SupervisionAcHandler; 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.AutomationCompositionElement; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions; import org.onap.policy.clamp.models.acm.concepts.DeployState; import org.onap.policy.clamp.models.acm.concepts.LockState; @@ -126,12 +123,13 @@ public class AutomationCompositionInstantiationProvider { response.setAffectedAutomationComposition(automationComposition.getKey().asIdentifier()); return response; - } else if (DeployState.DEPLOYED.equals(acToUpdate.getDeployState()) + } else if ((DeployState.DEPLOYED.equals(acToUpdate.getDeployState()) + || DeployState.UPDATING.equals(acToUpdate.getDeployState())) && LockState.LOCKED.equals(acToUpdate.getLockState())) { return updateDeployedAutomationComposition(compositionId, automationComposition, acToUpdate); } throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, - "Not allowed to update in the state " + acToUpdate.getDeployState()); + "Not allowed to update in the state " + acToUpdate.getDeployState()); } /** @@ -143,24 +141,24 @@ public class AutomationCompositionInstantiationProvider { * @return the result of the update */ public InstantiationResponse updateDeployedAutomationComposition(UUID compositionId, - AutomationComposition automationComposition, - AutomationComposition acToBeUpdated) { + AutomationComposition automationComposition, AutomationComposition acToBeUpdated) { // Iterate and update the element property values - for (Map.Entry dbAcElement : acToBeUpdated.getElements().entrySet()) { + for (var dbAcElement : acToBeUpdated.getElements().entrySet()) { var elementId = dbAcElement.getKey(); if (automationComposition.getElements().containsKey(elementId)) { - dbAcElement.getValue().getProperties().putAll(automationComposition.getElements().get(elementId) - .getProperties()); + dbAcElement.getValue().getProperties() + .putAll(automationComposition.getElements().get(elementId).getProperties()); } } - // Publish property update event to the participants - supervisionAcHandler.update(acToBeUpdated); - var validationResult = validateAutomationComposition(acToBeUpdated); if (!validationResult.isValid()) { throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult()); } + + // Publish property update event to the participants + supervisionAcHandler.update(acToBeUpdated); + automationComposition = automationCompositionProvider.updateAutomationComposition(acToBeUpdated); var response = new InstantiationResponse(); var instanceId = automationComposition.getInstanceId(); @@ -169,7 +167,6 @@ public class AutomationCompositionInstantiationProvider { return response; } - /** * Validate AutomationComposition. * @@ -234,7 +231,8 @@ public class AutomationCompositionInstantiationProvider { throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId); } - if (!DeployState.UNDEPLOYED.equals(automationComposition.getDeployState())) { + if (!DeployState.UNDEPLOYED.equals(automationComposition.getDeployState()) + && !DeployState.DELETING.equals(automationComposition.getDeployState())) { throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, "Automation composition state is still " + automationComposition.getDeployState()); } @@ -279,7 +277,7 @@ public class AutomationCompositionInstantiationProvider { var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId()); var result = acInstanceStateResolver.resolve(acInstanceStateUpdate.getDeployOrder(), acInstanceStateUpdate.getLockOrder(), automationComposition.getDeployState(), - automationComposition.getLockState()); + automationComposition.getLockState(), automationComposition.getStateChangeResult()); switch (result) { case "DEPLOY": supervisionAcHandler.deploy(automationComposition, acDefinition); diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java index da3cbc399..e9f8d6ce5 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java @@ -34,6 +34,7 @@ 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.ParticipantUtils; +import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionDeployAck; import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; import org.onap.policy.clamp.models.acm.utils.AcmUtils; @@ -55,7 +56,6 @@ public class SupervisionAcHandler { // Publishers for participant communication private final AutomationCompositionDeployPublisher automationCompositionDeployPublisher; private final AutomationCompositionStateChangePublisher automationCompositionStateChangePublisher; - private final AcElementPropertiesPublisher acElementPropertiesPublisher; /** @@ -65,7 +65,17 @@ public class SupervisionAcHandler { * @param acDefinition the AutomationCompositionDefinition */ public void deploy(AutomationComposition automationComposition, AutomationCompositionDefinition acDefinition) { - AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYING, LockState.NONE); + if (StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())) { + automationComposition.setDeployState(DeployState.DEPLOYING); + for (var element : automationComposition.getElements().values()) { + if (!DeployState.DEPLOYED.equals(element.getDeployState())) { + element.setDeployState(DeployState.DEPLOYING); + } + } + } else { + AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYING, LockState.NONE); + } + automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); automationCompositionProvider.updateAutomationComposition(automationComposition); var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate()); automationCompositionDeployPublisher.send(automationComposition, acDefinition.getServiceTemplate(), startPhase, @@ -79,7 +89,17 @@ public class SupervisionAcHandler { * @param acDefinition the AutomationCompositionDefinition */ public void undeploy(AutomationComposition automationComposition, AutomationCompositionDefinition acDefinition) { - AcmUtils.setCascadedState(automationComposition, DeployState.UNDEPLOYING, LockState.NONE); + if (StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())) { + automationComposition.setDeployState(DeployState.UNDEPLOYING); + for (var element : automationComposition.getElements().values()) { + if (!DeployState.UNDEPLOYED.equals(element.getDeployState())) { + element.setDeployState(DeployState.UNDEPLOYING); + } + } + } else { + AcmUtils.setCascadedState(automationComposition, DeployState.UNDEPLOYING, LockState.NONE); + } + automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); automationCompositionProvider.updateAutomationComposition(automationComposition); var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate()); automationCompositionStateChangePublisher.send(automationComposition, startPhase, true); @@ -92,7 +112,17 @@ public class SupervisionAcHandler { * @param acDefinition the AutomationCompositionDefinition */ public void unlock(AutomationComposition automationComposition, AutomationCompositionDefinition acDefinition) { - AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.UNLOCKING); + if (StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())) { + automationComposition.setLockState(LockState.UNLOCKING); + for (var element : automationComposition.getElements().values()) { + if (!LockState.UNLOCKED.equals(element.getLockState())) { + element.setLockState(LockState.UNLOCKING); + } + } + } else { + AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.UNLOCKING); + } + automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); automationCompositionProvider.updateAutomationComposition(automationComposition); var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate()); automationCompositionStateChangePublisher.send(automationComposition, startPhase, true); @@ -105,7 +135,17 @@ public class SupervisionAcHandler { * @param acDefinition the AutomationCompositionDefinition */ public void lock(AutomationComposition automationComposition, AutomationCompositionDefinition acDefinition) { - AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.LOCKING); + if (StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())) { + automationComposition.setLockState(LockState.LOCKING); + for (var element : automationComposition.getElements().values()) { + if (!LockState.LOCKED.equals(element.getLockState())) { + element.setLockState(LockState.LOCKING); + } + } + } else { + AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.LOCKING); + } + automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); automationCompositionProvider.updateAutomationComposition(automationComposition); var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate()); automationCompositionStateChangePublisher.send(automationComposition, startPhase, true); @@ -113,10 +153,12 @@ public class SupervisionAcHandler { /** * Handle Element property update on a deployed instance. + * * @param automationComposition the AutomationComposition */ public void update(AutomationComposition automationComposition) { - AcmUtils.setCascadedState(automationComposition, DeployState.UPDATING, LockState.NONE); + AcmUtils.setCascadedState(automationComposition, DeployState.UPDATING, automationComposition.getLockState()); + automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); acElementPropertiesPublisher.send(automationComposition); } @@ -128,6 +170,7 @@ public class SupervisionAcHandler { */ public void delete(AutomationComposition automationComposition, AutomationCompositionDefinition acDefinition) { AcmUtils.setCascadedState(automationComposition, DeployState.DELETING, LockState.NONE); + automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); automationCompositionProvider.updateAutomationComposition(automationComposition); var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate()); automationCompositionStateChangePublisher.send(automationComposition, startPhase, true); @@ -176,8 +219,11 @@ public class SupervisionAcHandler { || automationCompositionAckMessage.getAutomationCompositionResultMap().isEmpty()) { if (DeployState.DELETING.equals(automationComposition.get().getDeployState())) { // scenario when Automation Composition instance has never been deployed - automationComposition.get().getElements().values() - .forEach(element -> element.setDeployState(DeployState.DELETED)); + for (var element : automationComposition.get().getElements().values()) { + if (element.getParticipantId().equals(automationCompositionAckMessage.getParticipantId())) { + element.setDeployState(DeployState.DELETED); + } + } automationCompositionProvider.updateAutomationComposition(automationComposition.get()); } else { LOGGER.warn("Empty AutomationCompositionResultMap {} {}", @@ -188,26 +234,37 @@ public class SupervisionAcHandler { } var updated = updateState(automationComposition.get(), - automationCompositionAckMessage.getAutomationCompositionResultMap().entrySet()); + automationCompositionAckMessage.getAutomationCompositionResultMap().entrySet(), + automationCompositionAckMessage.getStateChangeResult()); if (updated) { automationCompositionProvider.updateAutomationComposition(automationComposition.get()); } } private boolean updateState(AutomationComposition automationComposition, - Set> automationCompositionResultSet) { + Set> automationCompositionResultSet, + StateChangeResult stateChangeResult) { var updated = false; + var elementInErrors = StateChangeResult.FAILED.equals(stateChangeResult); + boolean inProgress = StateChangeResult.NO_ERROR.equals(automationComposition.getStateChangeResult()); + for (var acElementAck : automationCompositionResultSet) { var element = automationComposition.getElements().get(acElementAck.getKey()); if (element != null) { - element.setDeployState(acElementAck.getValue().getDeployState()); - element.setLockState(acElementAck.getValue().getLockState()); + element.setMessage(acElementAck.getValue().getMessage()); + element.setOutProperties(acElementAck.getValue().getOutProperties()); element.setOperationalState(acElementAck.getValue().getOperationalState()); element.setUseState(acElementAck.getValue().getUseState()); - element.setOutProperties(acElementAck.getValue().getOutProperties()); updated = true; + if (!elementInErrors || inProgress) { + element.setDeployState(acElementAck.getValue().getDeployState()); + element.setLockState(acElementAck.getValue().getLockState()); + } } } + if (elementInErrors && inProgress) { + automationComposition.setStateChangeResult(stateChangeResult.FAILED); + } return updated; } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java index e23d79d57..803bc86ca 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java @@ -138,6 +138,11 @@ public class SupervisionScanner { LOGGER.debug("automation composition scan: transition from state {} to {} not completed", automationComposition.getDeployState(), automationComposition.getLockState()); + if (DeployState.UPDATING.equals(automationComposition.getDeployState())) { + // UPDATING do not need phases + return; + } + var isForward = AcmUtils.isForward(automationComposition.getDeployState(), automationComposition.getLockState()); -- cgit 1.2.3-korg