diff options
author | FrancescoFioraEst <francesco.fiora@est.tech> | 2023-06-16 10:42:14 +0100 |
---|---|---|
committer | Francesco Fiora <francesco.fiora@est.tech> | 2023-06-16 09:51:29 +0000 |
commit | 0f24f33b124bf326e4b7dbaa2a55cab72696b9ee (patch) | |
tree | 6fcf5bc915bd52d1e0071401293ebe0fdc4d9495 | |
parent | a2320d29b9373041db88395d9fdda7ea84d38807 (diff) |
Add support for Prime Deprime Failure Handling in ACM-Runtime
Issue-ID: POLICY-4714
Change-Id: I1f3cf8f0fcebc7c48b3632ad10aa8907c41cdb5a
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
11 files changed, 149 insertions, 64 deletions
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionDefinition.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionDefinition.java index a8c069723..eb8a919d6 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionDefinition.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AutomationCompositionDefinition.java @@ -44,6 +44,8 @@ public class AutomationCompositionDefinition { @NonNull private AcTypeState state; + private StateChangeResult stateChangeResult; + @NonNull // Map used to store prime state with key as NodeTemplate Name and value as NodeTemplateState private Map<String, NodeTemplateState> elementStateMap = new HashMap<>(); @@ -58,5 +60,6 @@ public class AutomationCompositionDefinition { this.serviceTemplate = new ToscaServiceTemplate(otherAcmDefinition.serviceTemplate); this.state = otherAcmDefinition.state; this.elementStateMap = PfUtils.mapMap(otherAcmDefinition.elementStateMap, NodeTemplateState::new); + this.stateChangeResult = otherAcmDefinition.stateChangeResult; } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/NodeTemplateState.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/NodeTemplateState.java index 5d28cd736..62e92087e 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/NodeTemplateState.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/NodeTemplateState.java @@ -40,6 +40,8 @@ public class NodeTemplateState { private AcTypeState state; + private String message; + /** * Copy constructor, does a deep copy but as all fields here are immutable, it's just a regular copy. * @@ -50,5 +52,6 @@ public class NodeTemplateState { this.participantId = copyConstructor.participantId; this.nodeTemplateId = new ToscaConceptIdentifier(copyConstructor.nodeTemplateId); this.state = copyConstructor.state; + this.message = copyConstructor.message; } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionDefinition.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionDefinition.java index 11e3f583e..50949d751 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionDefinition.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionDefinition.java @@ -41,6 +41,7 @@ import lombok.EqualsAndHashCode; import lombok.NonNull; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; +import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.clamp.models.acm.document.base.ToscaServiceTemplateValidation; import org.onap.policy.clamp.models.acm.document.concepts.DocToscaServiceTemplate; import org.onap.policy.common.parameters.BeanValidationResult; @@ -76,6 +77,9 @@ public class JpaAutomationCompositionDefinition extends Validated @NotNull private AcTypeState state; + @Column + private StateChangeResult stateChangeResult; + @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "compositionId", foreignKey = @ForeignKey(name = "dt_element_fk")) private Set<JpaNodeTemplateState> elements = new HashSet<>(); @@ -91,6 +95,7 @@ public class JpaAutomationCompositionDefinition extends Validated var acmDefinition = new AutomationCompositionDefinition(); acmDefinition.setCompositionId(UUID.fromString(this.compositionId)); acmDefinition.setState(this.state); + acmDefinition.setStateChangeResult(this.stateChangeResult); acmDefinition.setServiceTemplate(this.serviceTemplate.toAuthorative()); for (var element : this.elements) { var key = element.getNodeTemplateId().getName(); @@ -103,6 +108,7 @@ public class JpaAutomationCompositionDefinition extends Validated public void fromAuthorative(final AutomationCompositionDefinition copyConcept) { this.compositionId = copyConcept.getCompositionId().toString(); this.state = copyConcept.getState(); + this.stateChangeResult = copyConcept.getStateChangeResult(); this.serviceTemplate = new DocToscaServiceTemplate(copyConcept.getServiceTemplate()); setName(this.serviceTemplate.getName()); setVersion(this.serviceTemplate.getVersion()); diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaNodeTemplateState.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaNodeTemplateState.java index 19d25e1b5..8ee1075f6 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaNodeTemplateState.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaNodeTemplateState.java @@ -70,6 +70,9 @@ public class JpaNodeTemplateState extends Validated implements PfAuthorative<Nod @NotNull private AcTypeState state; + @Column + private String message; + /** * The Default Constructor. */ @@ -96,6 +99,7 @@ public class JpaNodeTemplateState extends Validated implements PfAuthorative<Nod } this.nodeTemplateId = copyConcept.getNodeTemplateId().asConceptKey(); this.state = copyConcept.getState(); + this.message = copyConcept.getMessage(); } @Override @@ -107,6 +111,7 @@ public class JpaNodeTemplateState extends Validated implements PfAuthorative<Nod } nodeTemplateState.setNodeTemplateId(new ToscaConceptIdentifier(this.nodeTemplateId)); nodeTemplateState.setState(this.state); + nodeTemplateState.setMessage(this.message); return nodeTemplateState; } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcTypeStateResolver.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcTypeStateResolver.java index 7070a312c..f1c930955 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcTypeStateResolver.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcTypeStateResolver.java @@ -21,6 +21,7 @@ package org.onap.policy.clamp.models.acm.persistence.provider; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; +import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.clamp.models.acm.messages.rest.commissioning.PrimeOrder; import org.onap.policy.clamp.models.acm.utils.StateDefinition; import org.springframework.stereotype.Component; @@ -33,17 +34,29 @@ public class AcTypeStateResolver { private static final String PRIME = PrimeOrder.PRIME.toString(); private static final String DEPRIME = PrimeOrder.DEPRIME.toString(); private static final String PRIMED = AcTypeState.PRIMED.toString(); + private static final String PRIMING = AcTypeState.PRIMING.toString(); private static final String COMMISSIONED = AcTypeState.COMMISSIONED.toString(); + private static final String DEPRIMING = AcTypeState.DEPRIMING.toString(); + private static final String NO_ERROR = StateChangeResult.NO_ERROR.name(); + private static final String FAILED = StateChangeResult.FAILED.name(); /** * Construct. */ public AcTypeStateResolver() { - this.graph = new StateDefinition<>(2, PrimeOrder.NONE); - this.graph.put(new String[] {PRIME, PRIMED}, PrimeOrder.PRIME); - this.graph.put(new String[] {PRIME, COMMISSIONED}, PrimeOrder.PRIME); - this.graph.put(new String[] {DEPRIME, PRIMED}, PrimeOrder.DEPRIME); - this.graph.put(new String[] {DEPRIME, COMMISSIONED}, PrimeOrder.DEPRIME); + this.graph = new StateDefinition<>(3, PrimeOrder.NONE); + + // no error + this.graph.put(new String[] {PRIME, PRIMED, NO_ERROR}, PrimeOrder.PRIME); + this.graph.put(new String[] {PRIME, COMMISSIONED, NO_ERROR}, PrimeOrder.PRIME); + this.graph.put(new String[] {DEPRIME, PRIMED, NO_ERROR}, PrimeOrder.DEPRIME); + this.graph.put(new String[] {DEPRIME, COMMISSIONED, NO_ERROR}, PrimeOrder.DEPRIME); + + // failed + this.graph.put(new String[] {PRIME, PRIMING, FAILED}, PrimeOrder.PRIME); + this.graph.put(new String[] {DEPRIME, PRIMING, FAILED}, PrimeOrder.DEPRIME); + this.graph.put(new String[] {DEPRIME, DEPRIMING, FAILED}, PrimeOrder.DEPRIME); + this.graph.put(new String[] {PRIME, DEPRIMING, FAILED}, PrimeOrder.PRIME); } /** @@ -51,11 +64,13 @@ public class AcTypeStateResolver { * * @param primeOrder the PrimeOrder * @param acTypeState then current AcTypeState + * @param acStateChangeResult the current Result of the State Change * @return primeOrder or NONE if the primeOrder is not consistent */ - public PrimeOrder resolve(PrimeOrder primeOrder, AcTypeState acTypeState) { + public PrimeOrder resolve(PrimeOrder primeOrder, AcTypeState acTypeState, StateChangeResult acStateChangeResult) { var po = primeOrder != null ? primeOrder : PrimeOrder.NONE; var state = acTypeState != null ? acTypeState : AcTypeState.COMMISSIONED; - return this.graph.get(new String[] {po.toString(), state.toString()}); + var stateChangeResult = acStateChangeResult != null ? acStateChangeResult : StateChangeResult.NO_ERROR; + return this.graph.get(new String[] {po.name(), state.name(), stateChangeResult.name()}); } } diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcTypeStateResolverTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcTypeStateResolverTest.java index bf27c3e4f..5ea13c94a 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcTypeStateResolverTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcTypeStateResolverTest.java @@ -24,6 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; +import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.clamp.models.acm.messages.rest.commissioning.PrimeOrder; class AcTypeStateResolverTest { @@ -31,25 +32,26 @@ class AcTypeStateResolverTest { @Test void testAcTypeState() { var acTypeStateResolver = new AcTypeStateResolver(); - var result = acTypeStateResolver.resolve(PrimeOrder.PRIME, AcTypeState.COMMISSIONED); + var result = + acTypeStateResolver.resolve(PrimeOrder.PRIME, AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR); assertThat(result).isEqualTo(PrimeOrder.PRIME); - result = acTypeStateResolver.resolve(PrimeOrder.PRIME, AcTypeState.PRIMED); + result = acTypeStateResolver.resolve(PrimeOrder.PRIME, AcTypeState.PRIMED, StateChangeResult.NO_ERROR); assertThat(result).isEqualTo(PrimeOrder.PRIME); - result = acTypeStateResolver.resolve(PrimeOrder.PRIME, AcTypeState.PRIMING); + result = acTypeStateResolver.resolve(PrimeOrder.PRIME, AcTypeState.PRIMING, StateChangeResult.NO_ERROR); assertThat(result).isEqualTo(PrimeOrder.NONE); - result = acTypeStateResolver.resolve(PrimeOrder.PRIME, AcTypeState.DEPRIMING); + result = acTypeStateResolver.resolve(PrimeOrder.PRIME, AcTypeState.DEPRIMING, StateChangeResult.NO_ERROR); assertThat(result).isEqualTo(PrimeOrder.NONE); - result = acTypeStateResolver.resolve(PrimeOrder.DEPRIME, AcTypeState.COMMISSIONED); + result = acTypeStateResolver.resolve(PrimeOrder.DEPRIME, AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR); assertThat(result).isEqualTo(PrimeOrder.DEPRIME); - result = acTypeStateResolver.resolve(PrimeOrder.DEPRIME, AcTypeState.PRIMED); + result = acTypeStateResolver.resolve(PrimeOrder.DEPRIME, AcTypeState.PRIMED, StateChangeResult.NO_ERROR); assertThat(result).isEqualTo(PrimeOrder.DEPRIME); - result = acTypeStateResolver.resolve(PrimeOrder.DEPRIME, AcTypeState.PRIMING); + result = acTypeStateResolver.resolve(PrimeOrder.DEPRIME, AcTypeState.PRIMING, StateChangeResult.NO_ERROR); assertThat(result).isEqualTo(PrimeOrder.NONE); - result = acTypeStateResolver.resolve(PrimeOrder.DEPRIME, AcTypeState.DEPRIMING); + result = acTypeStateResolver.resolve(PrimeOrder.DEPRIME, AcTypeState.DEPRIMING, StateChangeResult.NO_ERROR); assertThat(result).isEqualTo(PrimeOrder.NONE); - result = acTypeStateResolver.resolve(null, null); + result = acTypeStateResolver.resolve(null, null, null); assertThat(result).isEqualTo(PrimeOrder.NONE); } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java index d8eddf558..141207651 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java @@ -30,6 +30,7 @@ import lombok.RequiredArgsConstructor; import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantPrimePublisher; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; +import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.clamp.models.acm.messages.rest.commissioning.AcTypeStateUpdate; import org.onap.policy.clamp.models.acm.messages.rest.commissioning.CommissioningResponse; import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider; @@ -180,7 +181,8 @@ public class CommissioningProvider { throw new PfModelRuntimeException(Status.BAD_REQUEST, "There are instances, Priming/Depriming not allowed"); } var acmDefinition = acDefinitionProvider.getAcDefinition(compositionId); - var stateOrdered = acTypeStateResolver.resolve(acTypeStateUpdate.getPrimeOrder(), acmDefinition.getState()); + var stateOrdered = acTypeStateResolver.resolve(acTypeStateUpdate.getPrimeOrder(), acmDefinition.getState(), + acmDefinition.getStateChangeResult()); switch (stateOrdered) { case PRIME: prime(acmDefinition); @@ -197,21 +199,24 @@ public class CommissioningProvider { } private void prime(AutomationCompositionDefinition acmDefinition) { - var prearation = participantPrimePublisher.prepareParticipantPriming(acmDefinition); + acmDefinition.setStateChangeResult(StateChangeResult.NO_ERROR); + var preparation = participantPrimePublisher.prepareParticipantPriming(acmDefinition); acDefinitionProvider.updateAcDefinition(acmDefinition); executor.execute( - () -> participantPrimePublisher.sendPriming(prearation, acmDefinition.getCompositionId(), null)); + () -> participantPrimePublisher.sendPriming(preparation, acmDefinition.getCompositionId(), null)); } private void deprime(AutomationCompositionDefinition acmDefinition) { - if (!AcTypeState.COMMISSIONED.equals(acmDefinition.getState())) { - for (var elementState : acmDefinition.getElementStateMap().values()) { + acmDefinition.setStateChangeResult(StateChangeResult.NO_ERROR); + for (var elementState : acmDefinition.getElementStateMap().values()) { + if (elementState.getParticipantId() != null) { elementState.setState(AcTypeState.DEPRIMING); } - acmDefinition.setState(AcTypeState.DEPRIMING); - acDefinitionProvider.updateAcDefinition(acmDefinition); } + acmDefinition.setState(AcTypeState.DEPRIMING); + acDefinitionProvider.updateAcDefinition(acmDefinition); + executor.execute(() -> participantPrimePublisher.sendDepriming(acmDefinition.getCompositionId())); } 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 e9f8d6ce5..536e3e246 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 @@ -78,8 +78,8 @@ public class SupervisionAcHandler { automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); automationCompositionProvider.updateAutomationComposition(automationComposition); var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate()); - automationCompositionDeployPublisher.send(automationComposition, acDefinition.getServiceTemplate(), startPhase, - true); + automationCompositionDeployPublisher.send(automationComposition, acDefinition.getServiceTemplate(), + startPhase, true); } /** @@ -207,24 +207,25 @@ public class SupervisionAcHandler { } private void setAcElementStateInDb(AutomationCompositionDeployAck automationCompositionAckMessage) { - var automationComposition = automationCompositionProvider + var automationCompositionOpt = automationCompositionProvider .findAutomationComposition(automationCompositionAckMessage.getAutomationCompositionId()); - if (automationComposition.isEmpty()) { + if (automationCompositionOpt.isEmpty()) { LOGGER.warn("AutomationComposition not found in database {}", automationCompositionAckMessage.getAutomationCompositionId()); return; } + var automationComposition = automationCompositionOpt.get(); if (automationCompositionAckMessage.getAutomationCompositionResultMap() == null || automationCompositionAckMessage.getAutomationCompositionResultMap().isEmpty()) { - if (DeployState.DELETING.equals(automationComposition.get().getDeployState())) { + if (DeployState.DELETING.equals(automationComposition.getDeployState())) { // scenario when Automation Composition instance has never been deployed - for (var element : automationComposition.get().getElements().values()) { + for (var element : automationComposition.getElements().values()) { if (element.getParticipantId().equals(automationCompositionAckMessage.getParticipantId())) { element.setDeployState(DeployState.DELETED); } } - automationCompositionProvider.updateAutomationComposition(automationComposition.get()); + automationCompositionProvider.updateAutomationComposition(automationComposition); } else { LOGGER.warn("Empty AutomationCompositionResultMap {} {}", automationCompositionAckMessage.getAutomationCompositionId(), @@ -233,11 +234,11 @@ public class SupervisionAcHandler { return; } - var updated = updateState(automationComposition.get(), + var updated = updateState(automationComposition, automationCompositionAckMessage.getAutomationCompositionResultMap().entrySet(), automationCompositionAckMessage.getStateChangeResult()); if (updated) { - automationCompositionProvider.updateAutomationComposition(automationComposition.get()); + automationCompositionProvider.updateAutomationComposition(automationComposition); } } @@ -246,7 +247,10 @@ public class SupervisionAcHandler { StateChangeResult stateChangeResult) { var updated = false; var elementInErrors = StateChangeResult.FAILED.equals(stateChangeResult); - boolean inProgress = StateChangeResult.NO_ERROR.equals(automationComposition.getStateChangeResult()); + boolean inProgress = !StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult()); + if (elementInErrors && inProgress) { + automationComposition.setStateChangeResult(StateChangeResult.FAILED); + } for (var acElementAck : automationCompositionResultSet) { var element = automationComposition.getElements().get(acElementAck.getKey()); @@ -255,16 +259,11 @@ public class SupervisionAcHandler { element.setOutProperties(acElementAck.getValue().getOutProperties()); element.setOperationalState(acElementAck.getValue().getOperationalState()); element.setUseState(acElementAck.getValue().getUseState()); + element.setDeployState(acElementAck.getValue().getDeployState()); + element.setLockState(acElementAck.getValue().getLockState()); 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/SupervisionHandler.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java index 6a1e12f70..862672f3b 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java @@ -24,6 +24,8 @@ package org.onap.policy.clamp.acm.runtime.supervision; import io.micrometer.core.annotation.Timed; import lombok.AllArgsConstructor; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; +import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantPrimeAck; import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider; import org.slf4j.Logger; @@ -61,18 +63,34 @@ public class SupervisionHandler { participantPrimeAckMessage.getCompositionId(), participantPrimeAckMessage.getParticipantId()); return; } - var state = AcTypeState.PRIMING.equals(acDefinition.getState()) ? AcTypeState.PRIMED : AcTypeState.COMMISSIONED; + handleParticipantPrimeAck(participantPrimeAckMessage, acDefinition); + } + + private void handleParticipantPrimeAck(ParticipantPrimeAck participantPrimeAckMessage, + AutomationCompositionDefinition acDefinition) { + var finalState = + AcTypeState.PRIMING.equals(acDefinition.getState()) ? AcTypeState.PRIMED : AcTypeState.COMMISSIONED; + var msgInErrors = StateChangeResult.FAILED.equals(participantPrimeAckMessage.getStateChangeResult()); + boolean inProgress = !StateChangeResult.FAILED.equals(acDefinition.getStateChangeResult()); + if (inProgress && msgInErrors) { + acDefinition.setStateChangeResult(StateChangeResult.FAILED); + } + boolean completed = true; for (var element : acDefinition.getElementStateMap().values()) { if (participantPrimeAckMessage.getParticipantId().equals(element.getParticipantId())) { - element.setState(state); - } else if (!state.equals(element.getState())) { + element.setMessage(participantPrimeAckMessage.getMessage()); + element.setState(participantPrimeAckMessage.getCompositionState()); + } + if (!finalState.equals(element.getState())) { completed = false; } } - if (completed) { - acDefinition.setState(state); + + if (inProgress && !msgInErrors && completed) { + acDefinition.setState(finalState); } acDefinitionProvider.updateAcDefinition(acDefinition); } + } 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 6988cd3c4..1f63c3da8 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 @@ -53,9 +53,10 @@ class SupervisionAcHandlerTest { @Test void testHandleAutomationCompositionStateChangeAckMessage() { - var automationCompositionProvider = mock(AutomationCompositionProvider.class); var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud"); + automationComposition.setInstanceId(IDENTIFIER); + var automationCompositionProvider = mock(AutomationCompositionProvider.class); when(automationCompositionProvider.findAutomationComposition(IDENTIFIER)) .thenReturn(Optional.of(automationComposition)); @@ -64,38 +65,39 @@ class SupervisionAcHandlerTest { mock(AcElementPropertiesPublisher.class)); var automationCompositionAckMessage = - new AutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK); + getAutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK, + automationComposition, DeployState.DEPLOYED, LockState.UNLOCKED); + handler.handleAutomationCompositionStateChangeAckMessage(automationCompositionAckMessage); + + verify(automationCompositionProvider).updateAutomationComposition(any(AutomationComposition.class)); + } + + private AutomationCompositionDeployAck getAutomationCompositionDeployAck(ParticipantMessageType messageType, + AutomationComposition automationComposition, DeployState deployState, LockState lockState) { + var automationCompositionAckMessage = new AutomationCompositionDeployAck(messageType); for (var elementEntry : automationComposition.getElements().entrySet()) { - var acElementDeployAck = - new AcElementDeployAck(DeployState.DEPLOYED, LockState.UNLOCKED, "", "", Map.of(), true, ""); + var acElementDeployAck = new AcElementDeployAck(deployState, lockState, "", "", Map.of(), true, ""); automationCompositionAckMessage.getAutomationCompositionResultMap().put(elementEntry.getKey(), acElementDeployAck); } - automationCompositionAckMessage.setAutomationCompositionId(IDENTIFIER); - - handler.handleAutomationCompositionStateChangeAckMessage(automationCompositionAckMessage); - - verify(automationCompositionProvider).updateAutomationComposition(any(AutomationComposition.class)); + automationCompositionAckMessage.setAutomationCompositionId(automationComposition.getInstanceId()); + automationCompositionAckMessage.setParticipantId(CommonTestData.getParticipantId()); + return automationCompositionAckMessage; } @Test void testHandleAutomationCompositionUpdateAckMessage() { - var automationCompositionProvider = mock(AutomationCompositionProvider.class); var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud"); + automationComposition.setInstanceId(IDENTIFIER); + var automationCompositionProvider = mock(AutomationCompositionProvider.class); when(automationCompositionProvider.findAutomationComposition(IDENTIFIER)) .thenReturn(Optional.of(automationComposition)); var automationCompositionAckMessage = - new AutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_DEPLOY_ACK); - for (var elementEntry : automationComposition.getElements().entrySet()) { - var acElementDeployAck = - new AcElementDeployAck(DeployState.DEPLOYED, LockState.LOCKED, "", "", Map.of(), true, ""); - automationCompositionAckMessage - .setAutomationCompositionResultMap(Map.of(elementEntry.getKey(), acElementDeployAck)); - } + getAutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_DEPLOY_ACK, + automationComposition, DeployState.DEPLOYED, LockState.LOCKED); automationCompositionAckMessage.setParticipantId(CommonTestData.getParticipantId()); - automationCompositionAckMessage.setAutomationCompositionId(IDENTIFIER); var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AutomationCompositionDeployPublisher.class), mock(AutomationCompositionStateChangePublisher.class), @@ -108,11 +110,11 @@ class SupervisionAcHandlerTest { @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); + var automationCompositionProvider = mock(AutomationCompositionProvider.class); when(automationCompositionProvider.findAutomationComposition(IDENTIFIER)) .thenReturn(Optional.of(automationComposition)); diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandlerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandlerTest.java index d4cc5e310..9ce63b005 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandlerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandlerTest.java @@ -32,6 +32,7 @@ import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils; import org.onap.policy.clamp.acm.runtime.util.CommonTestData; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.ParticipantState; +import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantPrimeAck; import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider; @@ -78,6 +79,32 @@ class SupervisionHandlerTest { var acDefinition = CommonTestData.createAcDefinition( InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML), AcTypeState.PRIMING); participantPrimeAckMessage.setCompositionId(acDefinition.getCompositionId()); + acDefinition.getElementStateMap().values().iterator().next() + .setParticipantId(CommonTestData.getParticipantId()); + + var acDefinitionProvider = mock(AcDefinitionProvider.class); + when(acDefinitionProvider.findAcDefinition(acDefinition.getCompositionId())) + .thenReturn(Optional.of(acDefinition)); + + var handler = new SupervisionHandler(acDefinitionProvider); + + handler.handleParticipantMessage(participantPrimeAckMessage); + verify(acDefinitionProvider).findAcDefinition(any()); + verify(acDefinitionProvider).updateAcDefinition(any()); + } + + @Test + void testParticipantPrimeAckFailed() { + var participantPrimeAckMessage = new ParticipantPrimeAck(); + participantPrimeAckMessage.setParticipantId(CommonTestData.getParticipantId()); + participantPrimeAckMessage.setState(ParticipantState.ON_LINE); + participantPrimeAckMessage.setStateChangeResult(StateChangeResult.FAILED); + + var acDefinition = CommonTestData.createAcDefinition( + InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML), AcTypeState.PRIMING); + participantPrimeAckMessage.setCompositionId(acDefinition.getCompositionId()); + acDefinition.getElementStateMap().values().iterator().next() + .setParticipantId(CommonTestData.getParticipantId()); var acDefinitionProvider = mock(AcDefinitionProvider.class); when(acDefinitionProvider.findAcDefinition(acDefinition.getCompositionId())) |