From 5a92f5dc2d2066635d59a0b986ec77487198a821 Mon Sep 17 00:00:00 2001 From: rameshiyer27 Date: Fri, 22 Sep 2023 15:46:30 +0100 Subject: Allow customisation in element and composition names in TOSCA User defined values can be provided in the spring properties file for runtime-acm. The same values will be expected from the TOSCA template. If not configured in application properties, default values will be used. Issue-ID: POLICY-4827 Signed-off-by: zrrmmua Change-Id: I17bfe811c2531c65e90679e95de9732129b54898 --- .../base/ToscaServiceTemplateValidation.java | 23 +++++++++--------- .../JpaAutomationCompositionDefinition.java | 2 -- .../persistence/provider/AcDefinitionProvider.java | 28 +++++++++++++++++----- .../policy/clamp/models/acm/utils/AcmUtils.java | 18 ++++++-------- .../provider/AcDefinitionProviderTest.java | 14 +++++++---- .../clamp/models/acm/utils/AcmUtilsTest.java | 27 ++++++++++++++------- 6 files changed, 70 insertions(+), 42 deletions(-) (limited to 'models') diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/document/base/ToscaServiceTemplateValidation.java b/models/src/main/java/org/onap/policy/clamp/models/acm/document/base/ToscaServiceTemplateValidation.java index c265e6458..ff580c7c2 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/document/base/ToscaServiceTemplateValidation.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/document/base/ToscaServiceTemplateValidation.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation. + * Copyright (C) 2022-2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,6 @@ import lombok.NonNull; import org.onap.policy.clamp.models.acm.document.concepts.DocToscaEntity; import org.onap.policy.clamp.models.acm.document.concepts.DocToscaServiceTemplate; import org.onap.policy.clamp.models.acm.document.concepts.DocToscaTopologyTemplate; -import org.onap.policy.clamp.models.acm.utils.AcmUtils; import org.onap.policy.common.parameters.BeanValidationResult; import org.onap.policy.common.parameters.ValidationStatus; import org.onap.policy.models.base.Validated; @@ -39,8 +38,6 @@ import org.onap.policy.models.base.Validated; public final class ToscaServiceTemplateValidation { private static final String ROOT_KEY_NAME_SUFFIX = ".Root"; - private static final String AC_NODE_TYPE_NOT_PRESENT = - "NodeTemplate with type " + AcmUtils.AUTOMATION_COMPOSITION_NODE_TYPE + " must exist!"; /** * validate a serviceTemplate. @@ -48,7 +45,8 @@ public final class ToscaServiceTemplateValidation { * @param result the result * @param serviceTemplate the serviceTemplate to validate */ - public static void validate(final BeanValidationResult result, DocToscaServiceTemplate serviceTemplate) { + public static void validate(final BeanValidationResult result, DocToscaServiceTemplate serviceTemplate, + String toscaCompositionName) { var references = DocUtil.getToscaReferences(serviceTemplate); @@ -66,7 +64,7 @@ public final class ToscaServiceTemplateValidation { } } - validateToscaTopologyTemplate(result, serviceTemplate.getToscaTopologyTemplate()); + validateToscaTopologyTemplate(result, serviceTemplate.getToscaTopologyTemplate(), toscaCompositionName); if (serviceTemplate.getToscaTopologyTemplate() != null) { validEntityTypeAncestors(serviceTemplate.getToscaTopologyTemplate().getNodeTemplates(), @@ -98,21 +96,24 @@ public final class ToscaServiceTemplateValidation { * @param topologyTemplate the ToscaServiceTemplate */ public static void validateToscaTopologyTemplate(BeanValidationResult result, - DocToscaTopologyTemplate topologyTemplate) { + DocToscaTopologyTemplate topologyTemplate, String toscaCompositionName) { + String acNodeTypeNotPresent = + "NodeTemplate with type " + toscaCompositionName + " must exist!"; + if (topologyTemplate != null && topologyTemplate.getNodeTemplates() != null) { var nodeTemplates = topologyTemplate.getNodeTemplates(); var acNumber = nodeTemplates.values().stream().filter( - nodeTemplate -> AcmUtils.AUTOMATION_COMPOSITION_NODE_TYPE.equals(nodeTemplate.getType())) + nodeTemplate -> toscaCompositionName.equals(nodeTemplate.getType())) .count(); if (acNumber == 0) { - result.addResult("TopologyTemplate", nodeTemplates, ValidationStatus.INVALID, AC_NODE_TYPE_NOT_PRESENT); + result.addResult("TopologyTemplate", nodeTemplates, ValidationStatus.INVALID, acNodeTypeNotPresent); } if (acNumber > 1) { result.addResult("TopologyTemplate", nodeTemplates, ValidationStatus.INVALID, "NodeTemplate with type " - + AcmUtils.AUTOMATION_COMPOSITION_NODE_TYPE + " not allowed to be more than one!"); + + toscaCompositionName + " not allowed to be more than one!"); } } else { - result.addResult("TopologyTemplate", topologyTemplate, ValidationStatus.INVALID, AC_NODE_TYPE_NOT_PRESENT); + result.addResult("TopologyTemplate", topologyTemplate, ValidationStatus.INVALID, acNodeTypeNotPresent); } } 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 641c9ad15..4069d7bb1 100755 --- 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 @@ -138,8 +138,6 @@ public class JpaAutomationCompositionDefinition extends Validated @Override public BeanValidationResult validate(@NonNull String fieldName) { var result = super.validate(fieldName); - ToscaServiceTemplateValidation.validate(result, serviceTemplate); - if (!result.isValid()) { return result; } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java index 588039b07..9f267d32d 100755 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java @@ -28,10 +28,12 @@ import java.util.UUID; import lombok.RequiredArgsConstructor; 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.document.base.ToscaServiceTemplateValidation; import org.onap.policy.clamp.models.acm.document.concepts.DocToscaServiceTemplate; import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionDefinition; import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionDefinitionRepository; import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.onap.policy.common.parameters.BeanValidationResult; import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.springframework.data.domain.Example; @@ -53,7 +55,7 @@ public class AcDefinitionProvider { * @return the created ACM Definition */ public AutomationCompositionDefinition createAutomationCompositionDefinition( - final ToscaServiceTemplate serviceTemplate) { + final ToscaServiceTemplate serviceTemplate, final String toscaElementName, String toscaCompositionName) { var acmDefinition = new AutomationCompositionDefinition(); var compositionId = UUID.randomUUID(); acmDefinition.setCompositionId(compositionId); @@ -63,10 +65,16 @@ public class AcDefinitionProvider { } serviceTemplate.getMetadata().put("compositionId", compositionId); acmDefinition.setServiceTemplate(serviceTemplate); - var acElements = AcmUtils.extractAcElementsFromServiceTemplate(serviceTemplate); + var acElements = AcmUtils.extractAcElementsFromServiceTemplate(serviceTemplate, toscaElementName); acmDefinition.setElementStateMap(AcmUtils.createElementStateMap(acElements, AcTypeState.COMMISSIONED)); var jpaAcmDefinition = ProviderUtils.getJpaAndValidate(acmDefinition, JpaAutomationCompositionDefinition::new, "AutomationCompositionDefinition"); + var validationResult = new BeanValidationResult("AutomationCompositionDefinition", acmDefinition); + ToscaServiceTemplateValidation.validate(validationResult, jpaAcmDefinition.getServiceTemplate(), + toscaCompositionName); + if (! validationResult.isValid()) { + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult()); + } var result = acmDefinitionRepository.save(jpaAcmDefinition); return result.toAuthorative(); @@ -78,14 +86,16 @@ public class AcDefinitionProvider { * @param compositionId The UUID of the automation composition definition to delete * @param serviceTemplate the service template to be created */ - public void updateServiceTemplate(UUID compositionId, ToscaServiceTemplate serviceTemplate) { + public void updateServiceTemplate(UUID compositionId, ToscaServiceTemplate serviceTemplate, String toscaElementName, + String toscaCompositionName) { var acmDefinition = new AutomationCompositionDefinition(); acmDefinition.setCompositionId(compositionId); acmDefinition.setState(AcTypeState.COMMISSIONED); acmDefinition.setServiceTemplate(serviceTemplate); - var acElements = AcmUtils.extractAcElementsFromServiceTemplate(serviceTemplate); + var acElements = + AcmUtils.extractAcElementsFromServiceTemplate(serviceTemplate, toscaElementName); acmDefinition.setElementStateMap(AcmUtils.createElementStateMap(acElements, AcTypeState.COMMISSIONED)); - updateAcDefinition(acmDefinition); + updateAcDefinition(acmDefinition, toscaCompositionName); } /** @@ -93,9 +103,15 @@ public class AcDefinitionProvider { * * @param acDefinition the AutomationCompositionDefinition to be updated */ - public void updateAcDefinition(AutomationCompositionDefinition acDefinition) { + public void updateAcDefinition(AutomationCompositionDefinition acDefinition, String toscaCompositionName) { var jpaAcmDefinition = ProviderUtils.getJpaAndValidate(acDefinition, JpaAutomationCompositionDefinition::new, "AutomationCompositionDefinition"); + var validationResult = new BeanValidationResult("AutomationCompositionDefinition", acDefinition); + ToscaServiceTemplateValidation.validate(validationResult, jpaAcmDefinition.getServiceTemplate(), + toscaCompositionName); + if (! validationResult.isValid()) { + throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult()); + } acmDefinitionRepository.save(jpaAcmDefinition); acmDefinitionRepository.flush(); } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java index fe44050d5..c3d8fc4a4 100755 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java @@ -65,10 +65,6 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate; */ @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class AcmUtils { - - public static final String AUTOMATION_COMPOSITION_ELEMENT = - "org.onap.policy.clamp.acm.AutomationCompositionElement"; - public static final String AUTOMATION_COMPOSITION_NODE_TYPE = "org.onap.policy.clamp.acm.AutomationComposition"; public static final String ENTRY = "entry "; /** @@ -99,15 +95,15 @@ public final class AcmUtils { * @return true if the NodeTemplate is an AutomationCompositionElement */ public static boolean checkIfNodeTemplateIsAutomationCompositionElement(ToscaNodeTemplate nodeTemplate, - ToscaServiceTemplate toscaServiceTemplate) { - if (nodeTemplate.getType().contains(AUTOMATION_COMPOSITION_ELEMENT)) { + ToscaServiceTemplate toscaServiceTemplate, String toscaElementName) { + if (nodeTemplate.getType().contains(toscaElementName)) { return true; } else { var nodeType = toscaServiceTemplate.getNodeTypes().get(nodeTemplate.getType()); if (nodeType != null) { var derivedFrom = nodeType.getDerivedFrom(); if (derivedFrom != null) { - return derivedFrom.contains(AUTOMATION_COMPOSITION_ELEMENT); + return derivedFrom.contains(toscaElementName); } } } @@ -167,10 +163,10 @@ public final class AcmUtils { * @return the list of Entry of AutomationCompositionElement */ public static List> extractAcElementsFromServiceTemplate( - ToscaServiceTemplate serviceTemplate) { + ToscaServiceTemplate serviceTemplate, String toscaElementName) { return serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().entrySet().stream().filter( nodeTemplateEntry -> checkIfNodeTemplateIsAutomationCompositionElement(nodeTemplateEntry.getValue(), - serviceTemplate)) + serviceTemplate, toscaElementName)) .toList(); } @@ -203,13 +199,13 @@ public final class AcmUtils { * @return the result of validation */ public static BeanValidationResult validateAutomationComposition(AutomationComposition automationComposition, - ToscaServiceTemplate serviceTemplate) { + ToscaServiceTemplate serviceTemplate, String toscaCompositionName) { var result = new BeanValidationResult(ENTRY + automationComposition.getName(), automationComposition); var map = getMapToscaNodeTemplates(serviceTemplate); var nodeTemplateGet = map.values().stream() - .filter(nodeTemplate -> AUTOMATION_COMPOSITION_NODE_TYPE.equals(nodeTemplate.getType())).findFirst(); + .filter(nodeTemplate -> toscaCompositionName.equals(nodeTemplate.getType())).findFirst(); if (nodeTemplateGet.isEmpty()) { result.addResult(new ObjectValidationResult("ToscaServiceTemplate", serviceTemplate.getName(), diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java index f907892f9..2d0803a8a 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java @@ -52,6 +52,9 @@ class AcDefinitionProviderTest { private static final String TOSCA_SERVICE_TEMPLATE_YAML_PROP = "clamp/acm/test/tosca-template-additional-properties.yaml"; + private static final String ELEMENT_NAME = "org.onap.policy.clamp.acm.AutomationCompositionElement"; + private static final String NODE_TYPE = "org.onap.policy.clamp.acm.AutomationComposition"; + private static ToscaServiceTemplate inputServiceTemplate; @BeforeAll @@ -87,7 +90,8 @@ class AcDefinitionProviderTest { .thenReturn(new JpaAutomationCompositionDefinition(acmDefinition)); var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository); - var result = acDefinitionProvider.createAutomationCompositionDefinition(inputServiceTemplate); + var result = acDefinitionProvider + .createAutomationCompositionDefinition(inputServiceTemplate, ELEMENT_NAME, NODE_TYPE); assertThat(result.getServiceTemplate()).isEqualTo(docServiceTemplate.toAuthorative()); assertThat(result.getServiceTemplate().getMetadata()).isNotNull(); @@ -104,7 +108,9 @@ class AcDefinitionProviderTest { .thenReturn(new JpaAutomationCompositionDefinition(acmDefinition)); var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository); - var result = acDefinitionProvider.createAutomationCompositionDefinition(inputServiceTemplate); + inputServiceTemplate.setMetadata(new HashMap<>()); + var result = acDefinitionProvider + .createAutomationCompositionDefinition(inputServiceTemplate, ELEMENT_NAME, NODE_TYPE); assertThat(result.getServiceTemplate()).isEqualTo(docServiceTemplate.toAuthorative()); assertThat(result.getServiceTemplate().getMetadata()).isNotNull(); @@ -114,7 +120,7 @@ class AcDefinitionProviderTest { void testUpdateServiceTemplate() { var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class); var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository); - acDefinitionProvider.updateServiceTemplate(UUID.randomUUID(), inputServiceTemplate); + acDefinitionProvider.updateServiceTemplate(UUID.randomUUID(), inputServiceTemplate, ELEMENT_NAME, NODE_TYPE); verify(acmDefinitionRepository).save(any(JpaAutomationCompositionDefinition.class)); } @@ -123,7 +129,7 @@ class AcDefinitionProviderTest { var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class); var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository); var acmDefinition = getAcDefinition(new DocToscaServiceTemplate(inputServiceTemplate)); - acDefinitionProvider.updateAcDefinition(acmDefinition); + acDefinitionProvider.updateAcDefinition(acmDefinition, NODE_TYPE); verify(acmDefinitionRepository).save(any(JpaAutomationCompositionDefinition.class)); } diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java index e0e5a2edc..8e10e81ad 100755 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java @@ -59,6 +59,10 @@ class AcmUtilsTest { private static final String PARTICIPANT_AUTOMATION_COMPOSITION_ELEMENT = "org.onap.policy.clamp.acm.Participant"; private static final String TOSCA_TEMPLATE_YAML = "clamp/acm/pmsh/funtional-pmsh-usecase.yaml"; + public static final String AUTOMATION_COMPOSITION_ELEMENT = + "org.onap.policy.clamp.acm.AutomationCompositionElement"; + public static final String AUTOMATION_COMPOSITION_NODE_TYPE = "org.onap.policy.clamp.acm.AutomationComposition"; + @Test void testIsInTransitionalState() { assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.LOCKED)).isFalse(); @@ -75,21 +79,25 @@ class AcmUtilsTest { void testCheckIfNodeTemplateIsAutomationCompositionElement() { var serviceTemplate = CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML); var nodeTemplate = new ToscaNodeTemplate(); - nodeTemplate.setType(AcmUtils.AUTOMATION_COMPOSITION_ELEMENT); - assertThat(AcmUtils.checkIfNodeTemplateIsAutomationCompositionElement(nodeTemplate, serviceTemplate)).isTrue(); + nodeTemplate.setType(AUTOMATION_COMPOSITION_ELEMENT); + assertThat(AcmUtils.checkIfNodeTemplateIsAutomationCompositionElement(nodeTemplate, serviceTemplate, + AUTOMATION_COMPOSITION_ELEMENT)).isTrue(); nodeTemplate.setType(POLICY_AUTOMATION_COMPOSITION_ELEMENT); - assertThat(AcmUtils.checkIfNodeTemplateIsAutomationCompositionElement(nodeTemplate, serviceTemplate)).isTrue(); + assertThat(AcmUtils.checkIfNodeTemplateIsAutomationCompositionElement(nodeTemplate, serviceTemplate, + AUTOMATION_COMPOSITION_ELEMENT)).isTrue(); nodeTemplate.setType(PARTICIPANT_AUTOMATION_COMPOSITION_ELEMENT); - assertThat(AcmUtils.checkIfNodeTemplateIsAutomationCompositionElement(nodeTemplate, serviceTemplate)).isFalse(); + assertThat(AcmUtils.checkIfNodeTemplateIsAutomationCompositionElement(nodeTemplate, serviceTemplate, + AUTOMATION_COMPOSITION_ELEMENT)).isFalse(); } @Test void testPrepareParticipantPriming() { var serviceTemplate = CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML); - var acElements = AcmUtils.extractAcElementsFromServiceTemplate(serviceTemplate); + var acElements = + AcmUtils.extractAcElementsFromServiceTemplate(serviceTemplate, AUTOMATION_COMPOSITION_ELEMENT); Map map = new HashMap<>(); var participantId = UUID.randomUUID(); assertThatThrownBy(() -> AcmUtils.prepareParticipantPriming(acElements, map)).hasMessageMatching( @@ -126,7 +134,8 @@ class AcmUtilsTest { void testValidateAutomationComposition() { var automationComposition = getDummyAutomationComposition(); var toscaServiceTemplate = getDummyToscaServiceTemplate(); - var result = AcmUtils.validateAutomationComposition(automationComposition, toscaServiceTemplate); + var result = AcmUtils.validateAutomationComposition(automationComposition, + toscaServiceTemplate, AUTOMATION_COMPOSITION_NODE_TYPE); assertNotNull(result); assertFalse(result.isValid()); @@ -135,11 +144,13 @@ class AcmUtilsTest { nodeTemplate.setType("org.onap.policy.clamp.acm.AutomationComposition"); nodeTemplates.put("org.onap.dcae.acm.DCAEMicroserviceAutomationCompositionParticipant", nodeTemplate); toscaServiceTemplate.getToscaTopologyTemplate().setNodeTemplates(nodeTemplates); - result = AcmUtils.validateAutomationComposition(automationComposition, toscaServiceTemplate); + result = AcmUtils.validateAutomationComposition(automationComposition, toscaServiceTemplate, + AUTOMATION_COMPOSITION_NODE_TYPE); assertFalse(result.isValid()); var doc = new DocToscaServiceTemplate(CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML)); - result = AcmUtils.validateAutomationComposition(automationComposition, doc.toAuthorative()); + result = AcmUtils.validateAutomationComposition(automationComposition, doc.toAuthorative(), + AUTOMATION_COMPOSITION_NODE_TYPE); assertFalse(result.isValid()); } -- cgit 1.2.3-korg