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 + .../supervision/SupervisionAcHandlerTest.java | 166 +++++++++++++++++++-- 4 files changed, 245 insertions(+), 39 deletions(-) (limited to 'runtime-acm') 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()); diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java index e763127cc..6988cd3c4 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java @@ -42,6 +42,7 @@ 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.DeployState; import org.onap.policy.clamp.models.acm.concepts.LockState; +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.messages.dmaap.participant.ParticipantMessageType; import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; @@ -59,8 +60,7 @@ class SupervisionAcHandlerTest { .thenReturn(Optional.of(automationComposition)); var handler = new SupervisionAcHandler(automationCompositionProvider, - mock(AutomationCompositionDeployPublisher.class), - mock(AutomationCompositionStateChangePublisher.class), + mock(AutomationCompositionDeployPublisher.class), mock(AutomationCompositionStateChangePublisher.class), mock(AcElementPropertiesPublisher.class)); var automationCompositionAckMessage = @@ -98,8 +98,7 @@ class SupervisionAcHandlerTest { automationCompositionAckMessage.setAutomationCompositionId(IDENTIFIER); var handler = new SupervisionAcHandler(automationCompositionProvider, - mock(AutomationCompositionDeployPublisher.class), - mock(AutomationCompositionStateChangePublisher.class), + mock(AutomationCompositionDeployPublisher.class), mock(AutomationCompositionStateChangePublisher.class), mock(AcElementPropertiesPublisher.class)); handler.handleAutomationCompositionUpdateAckMessage(automationCompositionAckMessage); @@ -107,13 +106,66 @@ class SupervisionAcHandlerTest { verify(automationCompositionProvider).updateAutomationComposition(any(AutomationComposition.class)); } + @Test + void testHandleAcUpdateAckFailedMessage() { + var automationCompositionProvider = mock(AutomationCompositionProvider.class); + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud"); + automationComposition.setDeployState(DeployState.DEPLOYING); + automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); + when(automationCompositionProvider.findAutomationComposition(IDENTIFIER)) + .thenReturn(Optional.of(automationComposition)); + + var automationCompositionAckMessage = + new AutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_DEPLOY_ACK); + for (var element : automationComposition.getElements().values()) { + element.setDeployState(DeployState.DEPLOYED); + } + var elementEntry = automationComposition.getElements().entrySet().iterator().next(); + elementEntry.getValue().setDeployState(DeployState.DEPLOYING); + var acElementDeployAck = + new AcElementDeployAck(DeployState.UNDEPLOYED, LockState.NONE, "", "", Map.of(), true, "Error"); + automationCompositionAckMessage + .setAutomationCompositionResultMap(Map.of(elementEntry.getKey(), acElementDeployAck)); + + automationCompositionAckMessage.setParticipantId(CommonTestData.getParticipantId()); + automationCompositionAckMessage.setAutomationCompositionId(IDENTIFIER); + + var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); + + var handler = new SupervisionAcHandler(automationCompositionProvider, + mock(AutomationCompositionDeployPublisher.class), automationCompositionStateChangePublisher, null); + + handler.handleAutomationCompositionUpdateAckMessage(automationCompositionAckMessage); + + verify(automationCompositionProvider).updateAutomationComposition(any(AutomationComposition.class)); + } + + @Test + void testDeployFailed() { + var automationCompositionDeployPublisher = mock(AutomationCompositionDeployPublisher.class); + var automationCompositionProvider = mock(AutomationCompositionProvider.class); + var handler = new SupervisionAcHandler(automationCompositionProvider, automationCompositionDeployPublisher, + mock(AutomationCompositionStateChangePublisher.class), mock(AcElementPropertiesPublisher.class)); + + var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); + var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Deploy"); + automationComposition.setStateChangeResult(StateChangeResult.FAILED); + handler.deploy(automationComposition, acDefinition); + verify(automationCompositionProvider).updateAutomationComposition(automationComposition); + verify(automationCompositionDeployPublisher).send(automationComposition, acDefinition.getServiceTemplate(), 0, + true); + } + @Test void testUndeploy() { var automationCompositionProvider = mock(AutomationCompositionProvider.class); var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); var handler = new SupervisionAcHandler(automationCompositionProvider, - mock(AutomationCompositionDeployPublisher.class), - acStateChangePublisher, mock(AcElementPropertiesPublisher.class)); + mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher, + mock(AcElementPropertiesPublisher.class)); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); var automationComposition = @@ -124,17 +176,56 @@ class SupervisionAcHandlerTest { verify(acStateChangePublisher).send(any(AutomationComposition.class), anyInt(), anyBoolean()); } + @Test + void testUndeployFailed() { + var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); + var automationCompositionProvider = mock(AutomationCompositionProvider.class); + var handler = new SupervisionAcHandler(automationCompositionProvider, + mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher, + mock(AcElementPropertiesPublisher.class)); + + var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); + var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "UnDeploy"); + automationComposition.setStateChangeResult(StateChangeResult.FAILED); + automationComposition.getElements().values() + .forEach(element -> element.setDeployState(DeployState.UNDEPLOYING)); + handler.undeploy(automationComposition, acDefinition); + verify(automationCompositionProvider).updateAutomationComposition(automationComposition); + verify(acStateChangePublisher).send(any(AutomationComposition.class), anyInt(), anyBoolean()); + } + @Test void testUnlock() { var automationCompositionProvider = mock(AutomationCompositionProvider.class); var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); var handler = new SupervisionAcHandler(automationCompositionProvider, - mock(AutomationCompositionDeployPublisher.class), - acStateChangePublisher, mock(AcElementPropertiesPublisher.class)); + mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher, + mock(AcElementPropertiesPublisher.class)); + var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); + var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "UnLock"); + handler.unlock(automationComposition, acDefinition); + + verify(automationCompositionProvider).updateAutomationComposition(any(AutomationComposition.class)); + verify(acStateChangePublisher).send(any(AutomationComposition.class), anyInt(), anyBoolean()); + } + + @Test + void testUnlockFailed() { + var automationCompositionProvider = mock(AutomationCompositionProvider.class); + var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); + var handler = new SupervisionAcHandler(automationCompositionProvider, + mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher, + mock(AcElementPropertiesPublisher.class)); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "UnLock"); + automationComposition.setStateChangeResult(StateChangeResult.FAILED); + automationComposition.getElements().values().forEach(element -> element.setLockState(LockState.UNLOCKING)); handler.unlock(automationComposition, acDefinition); verify(automationCompositionProvider).updateAutomationComposition(any(AutomationComposition.class)); @@ -146,15 +237,70 @@ class SupervisionAcHandlerTest { var automationCompositionProvider = mock(AutomationCompositionProvider.class); var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); var handler = new SupervisionAcHandler(automationCompositionProvider, - mock(AutomationCompositionDeployPublisher.class), - acStateChangePublisher, mock(AcElementPropertiesPublisher.class)); + mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher, + mock(AcElementPropertiesPublisher.class)); + var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); + var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Lock"); + handler.lock(automationComposition, acDefinition); + + verify(automationCompositionProvider).updateAutomationComposition(any(AutomationComposition.class)); + verify(acStateChangePublisher).send(any(AutomationComposition.class), anyInt(), anyBoolean()); + } + + @Test + void testLockFailed() { + var automationCompositionProvider = mock(AutomationCompositionProvider.class); + var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class); + var handler = new SupervisionAcHandler(automationCompositionProvider, + mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher, + mock(AcElementPropertiesPublisher.class)); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Lock"); + automationComposition.setStateChangeResult(StateChangeResult.FAILED); + automationComposition.getElements().values().forEach(element -> element.setLockState(LockState.LOCKING)); handler.lock(automationComposition, acDefinition); verify(automationCompositionProvider).updateAutomationComposition(any(AutomationComposition.class)); verify(acStateChangePublisher).send(any(AutomationComposition.class), anyInt(), anyBoolean()); } + + @Test + void testDeleteAck() { + var automationCompositionProvider = mock(AutomationCompositionProvider.class); + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud"); + automationComposition.setDeployState(DeployState.DELETING); + when(automationCompositionProvider.findAutomationComposition(IDENTIFIER)) + .thenReturn(Optional.of(automationComposition)); + + var automationCompositionAckMessage = + new AutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_DEPLOY_ACK); + automationCompositionAckMessage + .setParticipantId(automationComposition.getElements().values().iterator().next().getParticipantId()); + automationCompositionAckMessage.setAutomationCompositionId(IDENTIFIER); + + var handler = new SupervisionAcHandler(automationCompositionProvider, + mock(AutomationCompositionDeployPublisher.class), mock(AutomationCompositionStateChangePublisher.class), + mock(AcElementPropertiesPublisher.class)); + + handler.handleAutomationCompositionUpdateAckMessage(automationCompositionAckMessage); + + verify(automationCompositionProvider).updateAutomationComposition(any(AutomationComposition.class)); + } + + @Test + void testUpdate() { + var acElementPropertiesPublisher = mock(AcElementPropertiesPublisher.class); + var handler = new SupervisionAcHandler(mock(AutomationCompositionProvider.class), + mock(AutomationCompositionDeployPublisher.class), mock(AutomationCompositionStateChangePublisher.class), + acElementPropertiesPublisher); + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Lock"); + handler.update(automationComposition); + verify(acElementPropertiesPublisher).send(any(AutomationComposition.class)); + } } -- cgit 1.2.3-korg