diff options
author | FrancescoFioraEst <francesco.fiora@est.tech> | 2024-11-26 14:23:39 +0000 |
---|---|---|
committer | Francesco Fiora <francesco.fiora@est.tech> | 2024-11-26 17:45:52 +0000 |
commit | 66ccb9814f2105b8c37a8ec47b9595fc09e4c5e7 (patch) | |
tree | 75099d312177d8e3080e13814e6063ac21fd0cf4 | |
parent | 69486c769a936881a1d11d2ff1f0f11e7be7e9df (diff) |
Fix undeploy issue after migration failure in ACM-R
Issue-ID: POLICY-5177
Change-Id: Ic49dc15a9fd2a92f358eb60a440a8efb5080bbde
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
7 files changed, 105 insertions, 8 deletions
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtils.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtils.java index 9c827d701..12c21f52c 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtils.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtils.java @@ -48,7 +48,9 @@ public final class ParticipantUtils { for (var element : automationComposition.getElements().values()) { var toscaNodeTemplate = toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates() .get(element.getDefinition().getName()); - int startPhase = ParticipantUtils.findStartPhase(toscaNodeTemplate.getProperties()); + int startPhase = toscaNodeTemplate != null + && element.getDefinition().getVersion().equals(toscaNodeTemplate.getVersion()) + ? ParticipantUtils.findStartPhase(toscaNodeTemplate.getProperties()) : 0; minStartPhase = Math.min(minStartPhase, startPhase); maxStartPhase = Math.max(maxStartPhase, startPhase); } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolver.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolver.java index 7bffdd966..9239b3ae9 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolver.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolver.java @@ -139,6 +139,8 @@ public class AcInstanceStateResolver { this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE, UNDEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE, TIMEOUT}, UNDEPLOY); this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE, + UNDEPLOYING, LOCKED, SUB_STATE_NONE, TIMEOUT}, UNDEPLOY); + this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE, UPDATING, LOCKED, SUB_STATE_NONE, TIMEOUT}, UNDEPLOY); this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE, MIGRATING, LOCKED, SUB_STATE_NONE, TIMEOUT}, UNDEPLOY); diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtilsTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtilsTest.java index bac0842f1..9a8316cdb 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtilsTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtilsTest.java @@ -67,6 +67,45 @@ class ParticipantUtilsTest { } @Test + void testGetFirstStartPhaseWithNull() throws CoderException { + var serviceTemplate = CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML); + var automationComposition = + CODER.decode(ResourceUtils.getResourceAsString(AUTOMATION_COMPOSITION_JSON), AutomationCompositions.class) + .getAutomationCompositionList().get(0); + automationComposition.setDeployState(DeployState.DEPLOYING); + automationComposition.setLockState(LockState.NONE); + + serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().values() + .forEach(node -> node.setVersion("0.0.0")); + var result = ParticipantUtils.getFirstStartPhase(automationComposition, serviceTemplate); + assertThat(result).isZero(); + + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setLockState(LockState.UNLOCKING); + result = ParticipantUtils.getFirstStartPhase(automationComposition, serviceTemplate); + assertThat(result).isZero(); + + automationComposition.setDeployState(DeployState.UNDEPLOYING); + automationComposition.setLockState(LockState.NONE); + result = ParticipantUtils.getFirstStartPhase(automationComposition, serviceTemplate); + assertThat(result).isZero(); + + serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().clear(); + result = ParticipantUtils.getFirstStartPhase(automationComposition, serviceTemplate); + assertThat(result).isZero(); + + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setLockState(LockState.UNLOCKING); + result = ParticipantUtils.getFirstStartPhase(automationComposition, serviceTemplate); + assertThat(result).isZero(); + + automationComposition.setDeployState(DeployState.UNDEPLOYING); + automationComposition.setLockState(LockState.NONE); + result = ParticipantUtils.getFirstStartPhase(automationComposition, serviceTemplate); + assertThat(result).isZero(); + } + + @Test void testGetFirstStage() throws CoderException { var serviceTemplate = CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML); var automationCompositions = diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java index 3837ec629..b9e33c92d 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java @@ -45,6 +45,7 @@ import org.onap.policy.clamp.models.acm.concepts.ParticipantSupportedElementType import org.onap.policy.clamp.models.acm.concepts.SubState; import org.onap.policy.models.base.PfUtils; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.springframework.stereotype.Component; @@ -140,7 +141,8 @@ public class CacheProvider { var automationComposition = automationCompositions.get(instanceId); var map = acElementsDefinitions.get(automationComposition.getCompositionId()); var element = automationComposition.getElements().get(acElementId); - return map.get(element.getDefinition()).getAutomationCompositionElementToscaNodeTemplate().getProperties(); + return getAcElementDefinition(map, element.getDefinition()) + .getAutomationCompositionElementToscaNodeTemplate().getProperties(); } /** @@ -152,8 +154,20 @@ public class CacheProvider { */ public Map<String, Object> getCommonProperties(@NonNull UUID compositionId, @NonNull ToscaConceptIdentifier definition) { - return acElementsDefinitions.get(compositionId).get(definition) - .getAutomationCompositionElementToscaNodeTemplate().getProperties(); + return getAcElementDefinition(acElementsDefinitions.get(compositionId), definition) + .getAutomationCompositionElementToscaNodeTemplate().getProperties(); + } + + private AutomationCompositionElementDefinition getAcElementDefinition( + Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> map, + ToscaConceptIdentifier definition) { + var nodeTemplate = map.get(definition); + if (nodeTemplate == null) { + nodeTemplate = new AutomationCompositionElementDefinition(); + nodeTemplate.setAutomationCompositionElementToscaNodeTemplate(new ToscaNodeTemplate()); + nodeTemplate.getAutomationCompositionElementToscaNodeTemplate().setProperties(new HashMap<>()); + } + return nodeTemplate; } /** @@ -273,8 +287,8 @@ public class CacheProvider { */ public CompositionElementDto createCompositionElementDto(UUID compositionId, AutomationCompositionElement element, Map<String, Object> compositionInProperties) { - var compositionOutProperties = getAcElementsDefinitions() - .get(compositionId).get(element.getDefinition()).getOutProperties(); + var compositionOutProperties = getAcElementDefinition(acElementsDefinitions + .get(compositionId), element.getDefinition()).getOutProperties(); return new CompositionElementDto(compositionId, element.getDefinition(), compositionInProperties, compositionOutProperties); } @@ -291,7 +305,7 @@ public class CacheProvider { var definitions = acElementsDefinitions.get(compositionId); Map<UUID, CompositionElementDto> map = new HashMap<>(); for (var element : automationComposition.getElements().values()) { - var definition = definitions.get(element.getDefinition()); + var definition = getAcElementDefinition(definitions, element.getDefinition()); var compositionElement = (definition != null) ? new CompositionElementDto(compositionId, element.getDefinition(), definition.getAutomationCompositionElementToscaNodeTemplate().getProperties(), diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProviderTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProviderTest.java index ced2d81e8..96add2025 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProviderTest.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProviderTest.java @@ -65,6 +65,8 @@ class CacheProviderTest { .isInstanceOf(NullPointerException.class); assertThatThrownBy(() -> cacheProvider.getCommonProperties(instanceId, (UUID) null)) .isInstanceOf(NullPointerException.class); + assertThatThrownBy(() -> cacheProvider.getCommonProperties(null, instanceId)) + .isInstanceOf(NullPointerException.class); assertThatThrownBy(() -> cacheProvider.removeAutomationComposition(null)) .isInstanceOf(NullPointerException.class); 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 db67e5eea..de2f37564 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 @@ -173,7 +173,9 @@ public class SupervisionScanner { for (var element : automationComposition.getElements().values()) { var toscaNodeTemplate = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates() .get(element.getDefinition().getName()); - int startPhase = ParticipantUtils.findStartPhase(toscaNodeTemplate.getProperties()); + int startPhase = toscaNodeTemplate != null + && element.getDefinition().getVersion().equals(toscaNodeTemplate.getVersion()) + ? ParticipantUtils.findStartPhase(toscaNodeTemplate.getProperties()) : 0; defaultMin = Math.min(defaultMin, startPhase); defaultMax = Math.max(defaultMax, startPhase); if (AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState(), diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java index 17cc8ad3b..b425c4b80 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java @@ -339,6 +339,42 @@ class SupervisionScannerTest { } @Test + void testStartPhaseWithNull() { + var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud"); + automationComposition.setDeployState(DeployState.DEPLOYING); + automationComposition.setLockState(LockState.NONE); + automationComposition.setPhase(0); + automationComposition.setLastMsg(TimestampHelper.now()); + automationComposition.setCompositionId(compositionId); + for (var element : automationComposition.getElements().values()) { + if (ELEMENT_NAME.equals(element.getDefinition().getName())) { + element.setDeployState(DeployState.DEPLOYING); + element.getDefinition().setName("NotExistElement"); + element.setLockState(LockState.NONE); + } else { + element.setDeployState(DeployState.DEPLOYING); + element.getDefinition().setVersion("0.0.0"); + element.setLockState(LockState.NONE); + } + } + + var automationCompositionProvider = mock(AutomationCompositionProvider.class); + when(automationCompositionProvider.getAcInstancesInTransition()).thenReturn(List.of(automationComposition)); + + var automationCompositionDeployPublisher = mock(AutomationCompositionDeployPublisher.class); + var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner"); + + var supervisionScanner = new SupervisionScanner(automationCompositionProvider, createAcDefinitionProvider(), + mock(AutomationCompositionStateChangePublisher.class), automationCompositionDeployPublisher, + mock(ParticipantSyncPublisher.class), null, acRuntimeParameterGroup); + + supervisionScanner.run(); + + verify(automationCompositionDeployPublisher, times(0)).send(any(AutomationComposition.class), + any(ToscaServiceTemplate.class), anyInt(), anyBoolean()); + } + + @Test void testSendAutomationCompositionMigrate() { var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud"); automationComposition.setDeployState(DeployState.MIGRATING); |