From aba3f2a1c64d755bfed2f278d40a74f9a4f9ab1e Mon Sep 17 00:00:00 2001 From: rameshiyer27 Date: Fri, 18 Feb 2022 17:27:13 +0000 Subject: [PATCH] Add support for populating metadataSet in PAP tosca policy MetadataSet fetched from the db and added to the policy metadata map with the key "metadataSet" before sending to PDPs Issue-ID: POLICY-3832 Signed-off-by: zrrmmua Change-Id: I14064d82ba6877bd7560af7de7572b4813a98385 --- .../repository/ToscaNodeTemplateRepository.java | 31 ++++++++ .../pap/main/service/ToscaNodeTemplateService.java | 70 +++++++++++++++++ .../main/service/ToscaServiceTemplateService.java | 25 ++++++ .../main/service/ToscaNodeTemplateServiceTest.java | 89 ++++++++++++++++++++++ .../service/ToscaServiceTemplateServiceTest.java | 55 +++++++++++-- main/src/test/resources/e2e/policyMetadataSet.yaml | 20 +++++ 6 files changed, 285 insertions(+), 5 deletions(-) create mode 100644 main/src/main/java/org/onap/policy/pap/main/repository/ToscaNodeTemplateRepository.java create mode 100644 main/src/main/java/org/onap/policy/pap/main/service/ToscaNodeTemplateService.java create mode 100644 main/src/test/java/org/onap/policy/pap/main/service/ToscaNodeTemplateServiceTest.java create mode 100644 main/src/test/resources/e2e/policyMetadataSet.yaml diff --git a/main/src/main/java/org/onap/policy/pap/main/repository/ToscaNodeTemplateRepository.java b/main/src/main/java/org/onap/policy/pap/main/repository/ToscaNodeTemplateRepository.java new file mode 100644 index 00000000..c132e388 --- /dev/null +++ b/main/src/main/java/org/onap/policy/pap/main/repository/ToscaNodeTemplateRepository.java @@ -0,0 +1,31 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2022, Nordix Foundation. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.main.repository; + +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplate; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ToscaNodeTemplateRepository extends JpaRepository { + +} diff --git a/main/src/main/java/org/onap/policy/pap/main/service/ToscaNodeTemplateService.java b/main/src/main/java/org/onap/policy/pap/main/service/ToscaNodeTemplateService.java new file mode 100644 index 00000000..9b097ccb --- /dev/null +++ b/main/src/main/java/org/onap/policy/pap/main/service/ToscaNodeTemplateService.java @@ -0,0 +1,70 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2022, Nordix Foundation. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.main.service; + +import java.util.Optional; +import javax.ws.rs.core.Response; +import lombok.RequiredArgsConstructor; +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.base.PfModelRuntimeException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplate; +import org.onap.policy.pap.main.repository.ToscaNodeTemplateRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class ToscaNodeTemplateService { + + private static final Logger LOGGER = LoggerFactory.getLogger(ToscaNodeTemplateService.class); + + private final ToscaNodeTemplateRepository nodeTemplateRepository; + + /** + * Get node templates. + * + * @param name the name of the node template to get + * @param version the version of the node template to get + * @return the node templates found + * @throws PfModelRuntimeException on errors getting node templates + */ + public ToscaNodeTemplate getToscaNodeTemplate(final String name, final String version) + throws PfModelRuntimeException { + + LOGGER.debug("->getNodeTemplate: name={}, version={}", name, version); + + Optional jpaToscaNodeTemplate = nodeTemplateRepository + .findById(new PfConceptKey(name, version)); + if (jpaToscaNodeTemplate.isPresent()) { + var nodeTemplate = jpaToscaNodeTemplate.get().toAuthorative(); + LOGGER.debug("<-NodeTemplate: name={}, version={}, nodeTemplate={}", name, version, nodeTemplate); + return nodeTemplate; + } else { + throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE, + "node template for " + name + ":" + version + " do not exist in the database"); + } + } + +} diff --git a/main/src/main/java/org/onap/policy/pap/main/service/ToscaServiceTemplateService.java b/main/src/main/java/org/onap/policy/pap/main/service/ToscaServiceTemplateService.java index e71045f6..ef0fc603 100644 --- a/main/src/main/java/org/onap/policy/pap/main/service/ToscaServiceTemplateService.java +++ b/main/src/main/java/org/onap/policy/pap/main/service/ToscaServiceTemplateService.java @@ -1,6 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2022 Bell Canada. All rights reserved. + * Modifications Copyright (C) 2022 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +33,7 @@ import org.onap.policy.models.base.PfConceptKey; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType; import org.onap.policy.models.tosca.authorative.concepts.ToscaTypedEntityFilter; @@ -51,8 +53,14 @@ public class ToscaServiceTemplateService { private static final Logger LOGGER = LoggerFactory.getLogger(ToscaServiceTemplateService.class); + private static final String METADATASET_NAME = "metadataSetName"; + private static final String METADATASET_VERSION = "metadataSetVersion"; + private static final String METADATASET = "metadataSet"; + private final ToscaServiceTemplateRepository serviceTemplateRepository; + private final ToscaNodeTemplateService nodeTemplateService; + /** * Get policies. * @@ -71,6 +79,7 @@ public class ToscaServiceTemplateService { List> policies = getToscaServiceTemplate(name, version, "policy").toAuthorative() .getToscaTopologyTemplate().getPolicies(); policyList = policies.stream().flatMap(policy -> policy.values().stream()).collect(Collectors.toList()); + populateMetadataSet(policyList); } catch (PfModelRuntimeException pfme) { return handlePfModelRuntimeException(pfme); } catch (Exception exc) { @@ -186,4 +195,20 @@ public class ToscaServiceTemplateService { } } + /** + * Populates metadataSet in policy->metadata if metadataSet reference is provided. + * + * @param policies List of policies + */ + private void populateMetadataSet(List policies) { + for (ToscaPolicy policy : policies) { + if (policy.getMetadata().keySet().containsAll(List.of(METADATASET_NAME, METADATASET_VERSION))) { + var name = String.valueOf(policy.getMetadata().get(METADATASET_NAME)); + var version = String.valueOf(policy.getMetadata().get(METADATASET_VERSION)); + policy.getMetadata().putIfAbsent(METADATASET, + nodeTemplateService.getToscaNodeTemplate(name, version).getMetadata()); + } + } + } + } diff --git a/main/src/test/java/org/onap/policy/pap/main/service/ToscaNodeTemplateServiceTest.java b/main/src/test/java/org/onap/policy/pap/main/service/ToscaNodeTemplateServiceTest.java new file mode 100644 index 00000000..cf8aa73b --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/service/ToscaNodeTemplateServiceTest.java @@ -0,0 +1,89 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP PAP + * ================================================================================ + * Copyright (C) 2022, Nordix Foundation. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.pap.main.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +import java.util.Optional; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.coder.StandardYamlCoder; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.base.PfModelRuntimeException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplate; +import org.onap.policy.pap.main.repository.ToscaNodeTemplateRepository; + +@RunWith(MockitoJUnitRunner.class) +public class ToscaNodeTemplateServiceTest { + + private static final String NODE_TEMPLATE_NAME = "tca_metadata"; + private static final String NODE_TEMPLATE_VERSION = "1.0.0"; + + @Mock + private ToscaNodeTemplateRepository nodeTemplateRepository; + + @InjectMocks + private ToscaNodeTemplateService nodeTemplateService; + + private ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate(); + + private StandardCoder coder = new StandardYamlCoder(); + + /** + * Set up for tests. + * + */ + @Before + public void setup() throws CoderException { + coder.decode(ResourceUtils.getResourceAsString("e2e/policyMetadataSet.yaml"), + ToscaServiceTemplate.class).getToscaTopologyTemplate().getNodeTemplates() + .forEach((key, value) -> nodeTemplate = value); + + Mockito.when(nodeTemplateRepository.findById(new PfConceptKey(NODE_TEMPLATE_NAME, NODE_TEMPLATE_VERSION))) + .thenReturn(Optional.of(new JpaToscaNodeTemplate(nodeTemplate))); + } + + @Test + public void testGetToscaNodeTemplate() { + assertDoesNotThrow(() -> nodeTemplateService.getToscaNodeTemplate(NODE_TEMPLATE_NAME, NODE_TEMPLATE_VERSION)); + + assertThat(nodeTemplateService.getToscaNodeTemplate(NODE_TEMPLATE_NAME, NODE_TEMPLATE_VERSION).getMetadata()) + .containsEntry("policyModel", nodeTemplate.getMetadata().get("policyModel").toString()); + + assertThatThrownBy(() -> nodeTemplateService.getToscaNodeTemplate("invalid_name", "1.0.0")) + .isInstanceOf(PfModelRuntimeException.class) + .hasMessage("node template for invalid_name:1.0.0 do not exist in the database"); + + } + +} diff --git a/main/src/test/java/org/onap/policy/pap/main/service/ToscaServiceTemplateServiceTest.java b/main/src/test/java/org/onap/policy/pap/main/service/ToscaServiceTemplateServiceTest.java index 04c1a281..b64ad287 100644 --- a/main/src/test/java/org/onap/policy/pap/main/service/ToscaServiceTemplateServiceTest.java +++ b/main/src/test/java/org/onap/policy/pap/main/service/ToscaServiceTemplateServiceTest.java @@ -1,6 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2022 Bell Canada. All rights reserved. + * Modifications Copyright (C) 2022 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +24,10 @@ package org.onap.policy.pap.main.service; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import java.util.List; +import java.util.Map; import java.util.Optional; +import javax.ws.rs.core.Response; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -38,6 +42,8 @@ import org.onap.policy.common.utils.resources.ResourceUtils; import org.onap.policy.models.base.PfConceptKey; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.base.PfModelRuntimeException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate; import org.onap.policy.pap.main.repository.ToscaServiceTemplateRepository; @@ -54,14 +60,22 @@ public class ToscaServiceTemplateServiceTest { private static final String INVALID_VERSION_ERR_MSG = "parameter \"version\": value \"version\", does not match regular expression \"^(\\d+.){2}\\d+$\""; + private static final String NODE_TEMPLATE_NAME = "tca_metadata"; + private static final String NODE_TEMPLATE_VERSION = "1.0.0"; + @Mock private ToscaServiceTemplateRepository toscaRepository; @InjectMocks private ToscaServiceTemplateService toscaService; + @Mock + private ToscaNodeTemplateService nodeTemplateService; + private ToscaServiceTemplate serviceTemplate; + private ToscaNodeTemplate nodeTemplate; + private StandardCoder coder = new StandardYamlCoder(); /** @@ -71,16 +85,31 @@ public class ToscaServiceTemplateServiceTest { */ @Before public void setup() throws CoderException { - ToscaServiceTemplate toscaPolicyType = coder - .decode(ResourceUtils.getResourceAsString("e2e/monitoring.policy-type.yaml"), ToscaServiceTemplate.class); + + coder.decode(ResourceUtils.getResourceAsString("e2e/policyMetadataSet.yaml"), + ToscaServiceTemplate.class).getToscaTopologyTemplate().getNodeTemplates() + .forEach((key, value) -> nodeTemplate = value); + + ToscaServiceTemplate toscaPolicyType = + coder.decode(ResourceUtils.getResourceAsString("e2e/monitoring.policy-type.yaml"), + ToscaServiceTemplate.class); ToscaServiceTemplate toscaPolicy = - coder.decode(ResourceUtils.getResourceAsString("e2e/monitoring.policy.yaml"), ToscaServiceTemplate.class); + coder.decode(ResourceUtils.getResourceAsString("e2e/monitoring.policy.yaml"), + ToscaServiceTemplate.class); + // Add metadataSet reference to the policy metadata + toscaPolicy.getToscaTopologyTemplate().getPolicies().forEach(e -> e.entrySet().iterator().next().getValue() + .getMetadata().putAll(Map.of("metadataSetName", NODE_TEMPLATE_NAME, + "metadataSetVersion", NODE_TEMPLATE_VERSION))); serviceTemplate = new ToscaServiceTemplate(toscaPolicyType); serviceTemplate.setToscaTopologyTemplate(toscaPolicy.getToscaTopologyTemplate()); Mockito .when(toscaRepository.findById( new PfConceptKey(JpaToscaServiceTemplate.DEFAULT_NAME, JpaToscaServiceTemplate.DEFAULT_VERSION))) .thenReturn(Optional.of(new JpaToscaServiceTemplate(serviceTemplate))); + + Mockito + .when(nodeTemplateService.getToscaNodeTemplate(NODE_TEMPLATE_NAME, NODE_TEMPLATE_VERSION)) + .thenReturn(nodeTemplate); } @@ -89,17 +118,33 @@ public class ToscaServiceTemplateServiceTest { assertThatThrownBy(() -> toscaService.getPolicyList(NAME, VERSION)) .isInstanceOf(PfModelRuntimeException.class).hasRootCauseMessage(INVALID_VERSION_ERR_MSG); - assertThat(toscaService.getPolicyList(NAME, VERSION_1)).hasSize(0); + assertThat(toscaService.getPolicyList(NAME, VERSION_1)).isEmpty(); assertThat(toscaService.getPolicyList("onap.restart.tca", VERSION_1)).hasSize(1); } + @Test + public void testPolicyForMetadataSet() throws PfModelException { + List policies = toscaService.getPolicyList("onap.restart.tca", VERSION_1); + + assertThat(policies.get(0).getMetadata()).containsEntry("metadataSet", nodeTemplate.getMetadata()); + + Mockito + .when(nodeTemplateService.getToscaNodeTemplate(NODE_TEMPLATE_NAME, NODE_TEMPLATE_VERSION)) + .thenThrow(new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE, + "node template for onap.restart.tca:1.0.0 do not exist in the database")); + + assertThatThrownBy(() -> toscaService.getPolicyList("onap.restart.tca", VERSION_1)) + .isInstanceOf(PfModelRuntimeException.class) + .hasMessage("node template for onap.restart.tca:1.0.0 do not exist in the database"); + } + @Test public void testGetPolicyTypeList() throws PfModelException { assertThatThrownBy(() -> toscaService.getPolicyTypeList(NAME, VERSION)) .isInstanceOf(PfModelRuntimeException.class).hasRootCauseMessage(INVALID_VERSION_ERR_MSG); - assertThat(toscaService.getPolicyTypeList(NAME, VERSION_1)).hasSize(0); + assertThat(toscaService.getPolicyTypeList(NAME, VERSION_1)).isEmpty(); assertThat(toscaService.getPolicyTypeList("onap.policies.monitoring.cdap.tca.hi.lo.app", VERSION_1)).hasSize(2); assertThat(toscaService.getPolicyTypeList("onap.policies.Monitoring", VERSION_1)).hasSize(1); diff --git a/main/src/test/resources/e2e/policyMetadataSet.yaml b/main/src/test/resources/e2e/policyMetadataSet.yaml new file mode 100644 index 00000000..8d9575b1 --- /dev/null +++ b/main/src/test/resources/e2e/policyMetadataSet.yaml @@ -0,0 +1,20 @@ +--- +tosca_definitions_version: tosca_simple_yaml_1_1_0 +node_types: + org.onap.nodetypes.policy.MetadataSet: + derived_from: tosca.nodetypes.Root + version: 1.0.0 +topology_template: + node_templates: + tca_metadata: + version: 1.0.0 + type: org.onap.nodetypes.policy.MetadataSet + type_version: 1.0.0 + description: Metadata set for tca + metadata: + policyModel: + key: + name: tcaModel + version: 1.0.0 + threshold: 3.14 + state: active -- 2.16.6