diff options
author | FrancescoFioraEst <francesco.fiora@est.tech> | 2023-06-02 12:36:45 +0100 |
---|---|---|
committer | Francesco Fiora <francesco.fiora@est.tech> | 2023-06-06 08:32:42 +0000 |
commit | d58c0ca04ae993702b2c399afd52b01e503ec0fe (patch) | |
tree | 45ab9c6019c79ed3a0814258e06d98219787f03d /participant/participant-impl/participant-impl-a1pms/src | |
parent | ebb4d0cf867d752ae148880dd0109fc3cf6d6025 (diff) |
Add Failure handling support in all ACM-participants
In any transition (like deploy, undeploy, lock, unlock, update, delete) a participant should respond with the final state of transition, a status indicator (stateChaneResult) indicating if error has occurred and a message.
Issue-ID: POLICY-4706
Change-Id: I424bc6d620f476392baee8904e21d3a6c7aa8d6b
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
Diffstat (limited to 'participant/participant-impl/participant-impl-a1pms/src')
2 files changed, 155 insertions, 27 deletions
diff --git a/participant/participant-impl/participant-impl-a1pms/src/main/java/org/onap/policy/clamp/acm/participant/a1pms/handler/AutomationCompositionElementHandler.java b/participant/participant-impl/participant-impl-a1pms/src/main/java/org/onap/policy/clamp/acm/participant/a1pms/handler/AutomationCompositionElementHandler.java index 8401b934b..665071bdf 100755 --- a/participant/participant-impl/participant-impl-a1pms/src/main/java/org/onap/policy/clamp/acm/participant/a1pms/handler/AutomationCompositionElementHandler.java +++ b/participant/participant-impl/participant-impl-a1pms/src/main/java/org/onap/policy/clamp/acm/participant/a1pms/handler/AutomationCompositionElementHandler.java @@ -22,6 +22,7 @@ package org.onap.policy.clamp.acm.participant.a1pms.handler; import java.lang.invoke.MethodHandles; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; import javax.validation.Validation; @@ -37,7 +38,11 @@ import org.onap.policy.clamp.acm.participant.a1pms.webclient.AcA1PmsClient; import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener; import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; +import org.onap.policy.clamp.models.acm.concepts.AcTypeState; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition; 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.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; @@ -81,7 +86,8 @@ public class AutomationCompositionElementHandler implements AutomationCompositio acA1PmsClient.deleteService(configurationEntity.getPolicyServiceEntities()); configRequestMap.remove(automationCompositionElementId); intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, - automationCompositionElementId, DeployState.UNDEPLOYED, null, "Undeployed"); + automationCompositionElementId, DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, + "Undeployed"); } else { LOGGER.warn("Failed to connect with A1PMS. Service configuration is: {}", configurationEntity); throw new A1PolicyServiceException(HttpStatus.SC_SERVICE_UNAVAILABLE, "Unable to connect with A1PMS"); @@ -107,7 +113,7 @@ public class AutomationCompositionElementHandler implements AutomationCompositio configRequestMap.put(element.getId(), configurationEntity); intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(), - DeployState.DEPLOYED, null, "Deployed"); + DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed"); } else { LOGGER.error("Failed to connect with A1PMS"); throw new A1PolicyServiceException(HttpStatus.SC_SERVICE_UNAVAILABLE, @@ -121,4 +127,41 @@ public class AutomationCompositionElementHandler implements AutomationCompositio throw new A1PolicyServiceException(HttpStatus.SC_BAD_REQUEST, "Invalid Configuration", e); } } + + @Override + public void lock(UUID instanceId, UUID elementId) throws PfModelException { + intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, null, LockState.LOCKED, + StateChangeResult.NO_ERROR, "Locked"); + } + + @Override + public void unlock(UUID instanceId, UUID elementId) throws PfModelException { + intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, null, LockState.UNLOCKED, + StateChangeResult.NO_ERROR, "Unlocked"); + } + + @Override + public void delete(UUID instanceId, UUID elementId) throws PfModelException { + intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, DeployState.DELETED, null, + StateChangeResult.NO_ERROR, "Deleted"); + } + + @Override + public void update(UUID instanceId, AcElementDeploy element, Map<String, Object> properties) + throws PfModelException { + intermediaryApi.updateAutomationCompositionElementState(instanceId, element.getId(), DeployState.DEPLOYED, null, + StateChangeResult.NO_ERROR, "Update not supported"); + } + + @Override + public void prime(UUID compositionId, List<AutomationCompositionElementDefinition> elementDefinitionList) + throws PfModelException { + intermediaryApi.updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.NO_ERROR, "Primed"); + } + + @Override + public void deprime(UUID compositionId) throws PfModelException { + intermediaryApi.updateCompositionState(compositionId, AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR, + "Deprimed"); + } } diff --git a/participant/participant-impl/participant-impl-a1pms/src/test/java/org/onap/policy/clamp/acm/participant/a1pms/handler/AcElementHandlerTest.java b/participant/participant-impl/participant-impl-a1pms/src/test/java/org/onap/policy/clamp/acm/participant/a1pms/handler/AcElementHandlerTest.java index a39076697..77f41cb60 100755 --- a/participant/participant-impl/participant-impl-a1pms/src/test/java/org/onap/policy/clamp/acm/participant/a1pms/handler/AcElementHandlerTest.java +++ b/participant/participant-impl/participant-impl-a1pms/src/test/java/org/onap/policy/clamp/acm/participant/a1pms/handler/AcElementHandlerTest.java @@ -20,38 +20,35 @@ package org.onap.policy.clamp.acm.participant.a1pms.handler; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.util.List; import java.util.Map; +import java.util.UUID; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Spy; import org.onap.policy.clamp.acm.participant.a1pms.exception.A1PolicyServiceException; import org.onap.policy.clamp.acm.participant.a1pms.utils.CommonTestData; import org.onap.policy.clamp.acm.participant.a1pms.utils.ToscaUtils; import org.onap.policy.clamp.acm.participant.a1pms.webclient.AcA1PmsClient; import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.models.acm.concepts.AcTypeState; +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.models.base.PfModelException; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; -import org.springframework.test.context.junit.jupiter.SpringExtension; -@ExtendWith(SpringExtension.class) class AcElementHandlerTest { private final AcA1PmsClient acA1PmsClient = mock(AcA1PmsClient.class); - @InjectMocks - @Spy - private AutomationCompositionElementHandler automationCompositionElementHandler = - new AutomationCompositionElementHandler(acA1PmsClient); - private final CommonTestData commonTestData = new CommonTestData(); private static ToscaServiceTemplate serviceTemplate; @@ -65,57 +62,145 @@ class AcElementHandlerTest { @BeforeEach void startMocks() throws A1PolicyServiceException { - automationCompositionElementHandler.setIntermediaryApi(mock(ParticipantIntermediaryApi.class)); when(acA1PmsClient.isPmsHealthy()).thenReturn(Boolean.TRUE); doNothing().when(acA1PmsClient).createService(any()); } @Test void test_automationCompositionElementStateChange() throws A1PolicyServiceException { + var automationCompositionElementHandler = new AutomationCompositionElementHandler(acA1PmsClient); + var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class); + automationCompositionElementHandler.setIntermediaryApi(participantIntermediaryApi); + var automationCompositionId = commonTestData.getAutomationCompositionId(); var element = commonTestData.getAutomationCompositionElement(); var automationCompositionElementId = element.getId(); var nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates(); - automationCompositionElementHandler.deploy( - commonTestData.getAutomationCompositionId(), element, + automationCompositionElementHandler.deploy(commonTestData.getAutomationCompositionId(), element, nodeTemplatesMap.get(A1_AUTOMATION_COMPOSITION_ELEMENT).getProperties()); + verify(participantIntermediaryApi).updateAutomationCompositionElementState(automationCompositionId, + automationCompositionElementId, DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed"); - assertDoesNotThrow(() -> automationCompositionElementHandler.undeploy( - automationCompositionId, automationCompositionElementId)); + automationCompositionElementHandler.undeploy(automationCompositionId, automationCompositionElementId); + verify(participantIntermediaryApi).updateAutomationCompositionElementState(automationCompositionId, + automationCompositionElementId, DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed"); when(acA1PmsClient.isPmsHealthy()).thenReturn(Boolean.FALSE); - assertThrows(A1PolicyServiceException.class, - () -> automationCompositionElementHandler.undeploy( - automationCompositionId, automationCompositionElementId)); + assertThrows(A1PolicyServiceException.class, () -> automationCompositionElementHandler + .undeploy(automationCompositionId, automationCompositionElementId)); } @Test - void test_AutomationCompositionElementUpdate() { + void test_AutomationCompositionElementUpdate() throws A1PolicyServiceException { + var automationCompositionElementHandler = new AutomationCompositionElementHandler(acA1PmsClient); + var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class); + automationCompositionElementHandler.setIntermediaryApi(participantIntermediaryApi); var element = commonTestData.getAutomationCompositionElement(); var nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates(); - assertDoesNotThrow(() -> automationCompositionElementHandler.deploy( - commonTestData.getAutomationCompositionId(), element, - nodeTemplatesMap.get(A1_AUTOMATION_COMPOSITION_ELEMENT).getProperties())); + automationCompositionElementHandler.deploy(commonTestData.getAutomationCompositionId(), element, + nodeTemplatesMap.get(A1_AUTOMATION_COMPOSITION_ELEMENT).getProperties()); + verify(participantIntermediaryApi).updateAutomationCompositionElementState( + commonTestData.getAutomationCompositionId(), element.getId(), DeployState.DEPLOYED, null, + StateChangeResult.NO_ERROR, "Deployed"); } @Test void test_AutomationCompositionElementUpdateWithUnhealthyA1pms() { + var automationCompositionElementHandler = new AutomationCompositionElementHandler(acA1PmsClient); + automationCompositionElementHandler.setIntermediaryApi(mock(ParticipantIntermediaryApi.class)); var element = commonTestData.getAutomationCompositionElement(); when(acA1PmsClient.isPmsHealthy()).thenReturn(Boolean.FALSE); var nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates(); assertThrows(A1PolicyServiceException.class, - () -> automationCompositionElementHandler.deploy( - commonTestData.getAutomationCompositionId(), element, + () -> automationCompositionElementHandler.deploy(commonTestData.getAutomationCompositionId(), element, nodeTemplatesMap.get(A1_AUTOMATION_COMPOSITION_ELEMENT).getProperties())); } @Test void test_AutomationCompositionElementUpdateWithInvalidConfiguration() { + var automationCompositionElementHandler = new AutomationCompositionElementHandler(acA1PmsClient); + automationCompositionElementHandler.setIntermediaryApi(mock(ParticipantIntermediaryApi.class)); var element = commonTestData.getAutomationCompositionElement(); assertThrows(A1PolicyServiceException.class, () -> automationCompositionElementHandler .deploy(commonTestData.getAutomationCompositionId(), element, Map.of())); } + + @Test + void testLock() throws PfModelException { + var automationCompositionElementHandler = new AutomationCompositionElementHandler(acA1PmsClient); + var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class); + automationCompositionElementHandler.setIntermediaryApi(participantIntermediaryApi); + var automationCompositionId = UUID.randomUUID(); + var elementId = UUID.randomUUID(); + automationCompositionElementHandler.lock(automationCompositionId, elementId); + + verify(participantIntermediaryApi).updateAutomationCompositionElementState(automationCompositionId, elementId, + null, LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked"); + } + + @Test + void testUnlock() throws PfModelException { + var automationCompositionElementHandler = new AutomationCompositionElementHandler(acA1PmsClient); + var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class); + automationCompositionElementHandler.setIntermediaryApi(participantIntermediaryApi); + var automationCompositionId = UUID.randomUUID(); + var elementId = UUID.randomUUID(); + automationCompositionElementHandler.unlock(automationCompositionId, elementId); + + verify(participantIntermediaryApi).updateAutomationCompositionElementState(automationCompositionId, elementId, + null, LockState.UNLOCKED, StateChangeResult.NO_ERROR, "Unlocked"); + } + + @Test + void testUpdate() throws PfModelException { + var automationCompositionElementHandler = new AutomationCompositionElementHandler(acA1PmsClient); + var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class); + automationCompositionElementHandler.setIntermediaryApi(participantIntermediaryApi); + var automationCompositionId = UUID.randomUUID(); + var element = commonTestData.getAutomationCompositionElement(); + automationCompositionElementHandler.update(automationCompositionId, element, Map.of()); + + verify(participantIntermediaryApi).updateAutomationCompositionElementState(automationCompositionId, + element.getId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Update not supported"); + } + + @Test + void testDelete() throws PfModelException { + var automationCompositionElementHandler = new AutomationCompositionElementHandler(acA1PmsClient); + var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class); + automationCompositionElementHandler.setIntermediaryApi(participantIntermediaryApi); + var automationCompositionId = UUID.randomUUID(); + var elementId = UUID.randomUUID(); + automationCompositionElementHandler.delete(automationCompositionId, elementId); + + verify(participantIntermediaryApi).updateAutomationCompositionElementState(automationCompositionId, elementId, + DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted"); + } + + @Test + void testPrime() throws PfModelException { + var automationCompositionElementHandler = new AutomationCompositionElementHandler(acA1PmsClient); + var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class); + automationCompositionElementHandler.setIntermediaryApi(participantIntermediaryApi); + var compositionId = UUID.randomUUID(); + automationCompositionElementHandler.prime(compositionId, List.of()); + + verify(participantIntermediaryApi).updateCompositionState(compositionId, AcTypeState.PRIMED, + StateChangeResult.NO_ERROR, "Primed"); + } + + @Test + void testDeprime() throws PfModelException { + var automationCompositionElementHandler = new AutomationCompositionElementHandler(acA1PmsClient); + var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class); + automationCompositionElementHandler.setIntermediaryApi(participantIntermediaryApi); + var compositionId = UUID.randomUUID(); + automationCompositionElementHandler.deprime(compositionId); + + verify(participantIntermediaryApi).updateCompositionState(compositionId, AcTypeState.COMMISSIONED, + StateChangeResult.NO_ERROR, "Deprimed"); + } } |