From 70dbf7a387b0e5d00f50a954751c4d4b4e54d7e2 Mon Sep 17 00:00:00 2001 From: liamfallon Date: Mon, 3 Feb 2020 14:37:33 +0000 Subject: [PATCH] Add merge utility for service templates This utility function allows a TOSCA service template fragment to be merged with an exsiting service template and will be tbe backbone of "create" methods on the API from now on. Issue-ID: POLICY-1402 Change-Id: I3381cb2a1bd30621a639dedc213c546eeb2bf9aa Signed-off-by: liamfallon --- .../policy/models/base/PfConceptContainer.java | 5 +- .../policy/models/base/PfConceptContainerTest.java | 19 +- .../simple/concepts/JpaToscaServiceTemplate.java | 44 +++-- .../simple/concepts/JpaToscaTopologyTemplate.java | 30 ++- .../tosca/utils/ToscaServiceTemplateUtils.java | 152 +++++++++++++++ .../tosca/simple/concepts/JpaToscaModelTest.java | 12 +- .../tosca/utils/ToscaServiceTemplateUtilsTest.java | 206 +++++++++++++++++++++ 7 files changed, 424 insertions(+), 44 deletions(-) create mode 100644 models-tosca/src/main/java/org/onap/policy/models/tosca/utils/ToscaServiceTemplateUtils.java create mode 100644 models-tosca/src/test/java/org/onap/policy/models/tosca/utils/ToscaServiceTemplateUtilsTest.java diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfConceptContainer.java b/models-base/src/main/java/org/onap/policy/models/base/PfConceptContainer.java index 2ecf8c1c6..949cb96dc 100644 --- a/models-base/src/main/java/org/onap/policy/models/base/PfConceptContainer.java +++ b/models-base/src/main/java/org/onap/policy/models/base/PfConceptContainer.java @@ -234,10 +234,7 @@ public class PfConceptContainer ex result = key.validate(result); - if (conceptMap.isEmpty()) { - result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, - "conceptMap may not be empty")); - } else { + if (!conceptMap.isEmpty()) { result = validateConceptMap(result); } diff --git a/models-base/src/test/java/org/onap/policy/models/base/PfConceptContainerTest.java b/models-base/src/test/java/org/onap/policy/models/base/PfConceptContainerTest.java index 5e84dff9a..b760e17c0 100644 --- a/models-base/src/test/java/org/onap/policy/models/base/PfConceptContainerTest.java +++ b/models-base/src/test/java/org/onap/policy/models/base/PfConceptContainerTest.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2019 Nordix Foundation. + * Copyright (C) 2019-2020 Nordix Foundation. * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -33,6 +33,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; + import org.junit.Test; import org.onap.policy.models.base.testconcepts.DummyAuthorativeConcept; import org.onap.policy.models.base.testconcepts.DummyBadPfConceptContainer; @@ -54,7 +55,7 @@ public class PfConceptContainerTest { private static final String DUMMY_VALUE = "Dummy"; private static final String VERSION0 = "0.0.1"; - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({"unchecked", "rawtypes"}) @Test public void testConceptContainer() { DummyPfConceptContainer container = new DummyPfConceptContainer(); @@ -74,10 +75,10 @@ public class PfConceptContainerTest { assertThatThrownBy(() -> new DummyPfConceptContainer((PfConceptKey) null, null)).hasMessage(KEY_IS_NULL); assertThatThrownBy(() -> new DummyPfConceptContainer(new PfConceptKey(), null)) - .hasMessage("conceptMap is marked @NonNull but is null"); + .hasMessage("conceptMap is marked @NonNull but is null"); assertThatThrownBy(() -> new DummyPfConceptContainer(null, new TreeMap())) - .hasMessage(KEY_IS_NULL); + .hasMessage(KEY_IS_NULL); container.getKey().setName(DUMMY_VALUE); DummyPfConceptContainer clonedContainer = new DummyPfConceptContainer(container); @@ -85,7 +86,7 @@ public class PfConceptContainerTest { assertEquals(DUMMY_VALUE, clonedContainer.getKey().getName()); assertThatThrownBy(() -> new DummyPfConceptContainer((DummyPfConceptContainer) null)) - .hasMessage("copyConcept is marked @NonNull but is null"); + .hasMessage("copyConcept is marked @NonNull but is null"); List keyList = container.getKeys(); assertEquals(1, keyList.size()); @@ -114,7 +115,7 @@ public class PfConceptContainerTest { assertEquals(0, container.compareTo(clonedContainer)); assertThatThrownBy(() -> new DummyPfConceptContainer((DummyPfConceptContainer) null)) - .isInstanceOf(NullPointerException.class); + .isInstanceOf(NullPointerException.class); assertFalse(container.compareTo(null) == 0); assertEquals(0, container.compareTo(container)); @@ -136,7 +137,7 @@ public class PfConceptContainerTest { DummyPfConceptContainer validateContainer = new DummyPfConceptContainer(); assertFalse(validateContainer.validate(new PfValidationResult()).isOk()); validateContainer.setKey(new PfConceptKey("VCKey", VERSION0)); - assertFalse(validateContainer.validate(new PfValidationResult()).isOk()); + assertTrue(validateContainer.validate(new PfValidationResult()).isOk()); validateContainer.getConceptMap().put(testConceptKey, new DummyPfConcept(testConceptKey)); assertTrue(validateContainer.validate(new PfValidationResult()).isOk()); @@ -194,11 +195,11 @@ public class PfConceptContainerTest { DummyBadPfConceptContainer badContainer = new DummyBadPfConceptContainer(); assertThatThrownBy(() -> badContainer.fromAuthorative(authorativeList)) - .hasMessage("failed to instantiate instance of container concept class"); + .hasMessage("failed to instantiate instance of container concept class"); authorativeList.clear(); assertThatThrownBy(() -> container.fromAuthorative(authorativeList)) - .hasMessage("An incoming list of concepts must have at least one entry"); + .hasMessage("An incoming list of concepts must have at least one entry"); } @Test(expected = NullPointerException.class) diff --git a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaServiceTemplate.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaServiceTemplate.java index 31c7df047..f6139ab2d 100644 --- a/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaServiceTemplate.java +++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaServiceTemplate.java @@ -277,26 +277,13 @@ public class JpaToscaServiceTemplate extends JpaToscaEntityType The type of container + * + * @param compositeContainer the original container + * @param fragmentContainer the fragment being added to the original container + * @return the composite container with the result + */ + @SuppressWarnings("unchecked") + // @formatter:off + private static + , ? extends ToscaEntity>> + S addFragmentEntitites(final S compositeContainer, final S fragmentContainer, + final PfValidationResult result) { + + if (compositeContainer == null) { + return fragmentContainer; + } + + if (fragmentContainer == null) { + return compositeContainer; + } + + for (Entry> fragmentEntry : fragmentContainer + .getConceptMap().entrySet()) { + JpaToscaEntityType containerEntry = + compositeContainer.getConceptMap().get(fragmentEntry.getKey()); + if (containerEntry != null && !containerEntry.equals(fragmentEntry.getValue())) { + result.addValidationMessage(new PfValidationMessage(fragmentEntry.getKey(), + ToscaServiceTemplateUtils.class, + ValidationResult.INVALID, "entity in incoming fragment does not equal existing entity")); + } + } + + // This use of a generic map is required to get around typing errors in directly adding the fragment map to the + // original map + @SuppressWarnings("rawtypes") + Map originalContainerMap = compositeContainer.getConceptMap(); + originalContainerMap.putAll(fragmentContainer.getConceptMap()); + + return compositeContainer; + } + // @formatter:on +} diff --git a/models-tosca/src/test/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaModelTest.java b/models-tosca/src/test/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaModelTest.java index 74a4e7c7f..839f0f8ca 100644 --- a/models-tosca/src/test/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaModelTest.java +++ b/models-tosca/src/test/java/org/onap/policy/models/tosca/simple/concepts/JpaToscaModelTest.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2019 Nordix Foundation. + * Copyright (C) 2019-2020 Nordix Foundation. * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -29,6 +29,7 @@ import static org.junit.Assert.assertTrue; import java.util.Map; import java.util.TreeMap; + import org.junit.Test; import org.onap.policy.models.base.PfConceptKey; import org.onap.policy.models.base.PfModelService; @@ -58,10 +59,10 @@ public class JpaToscaModelTest { assertThatThrownBy(() -> new JpaToscaModel(null, new JpaToscaServiceTemplates())).hasMessage(KEY_IS_NULL); assertThatThrownBy(() -> new JpaToscaModel(new PfConceptKey(), null)) - .hasMessage("serviceTemplates is marked @NonNull but is null"); + .hasMessage("serviceTemplates is marked @NonNull but is null"); assertThatThrownBy(() -> new JpaToscaModel((JpaToscaModel) null)) - .hasMessage("copyConcept is marked @NonNull but is null"); + .hasMessage("copyConcept is marked @NonNull but is null"); PfConceptKey tstsKey = new PfConceptKey("tsts", VERSION_001); Map tstMap = new TreeMap<>(); @@ -90,8 +91,7 @@ public class JpaToscaModelTest { otherDt.setServiceTemplates(tsts); assertEquals(0, tm.compareTo(otherDt)); - assertThatThrownBy(() -> new JpaToscaModel((JpaToscaModel) null)) - .isInstanceOf(NullPointerException.class); + assertThatThrownBy(() -> new JpaToscaModel((JpaToscaModel) null)).isInstanceOf(NullPointerException.class); assertEquals(2, tm.getKeys().size()); assertEquals(2, new JpaToscaModel().getKeys().size()); @@ -101,7 +101,7 @@ public class JpaToscaModelTest { assertEquals(tttClone0, tm); assertFalse(new JpaToscaModel().validate(new PfValidationResult()).isValid()); - assertFalse(tm.validate(new PfValidationResult()).isValid()); + assertTrue(tm.validate(new PfValidationResult()).isValid()); tm.register(); assertTrue(PfModelService.existsModel(tm.getServiceTemplates().getId())); diff --git a/models-tosca/src/test/java/org/onap/policy/models/tosca/utils/ToscaServiceTemplateUtilsTest.java b/models-tosca/src/test/java/org/onap/policy/models/tosca/utils/ToscaServiceTemplateUtilsTest.java new file mode 100644 index 000000000..cc6f8f0d0 --- /dev/null +++ b/models-tosca/src/test/java/org/onap/policy/models/tosca/utils/ToscaServiceTemplateUtilsTest.java @@ -0,0 +1,206 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.tosca.utils; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; + +import java.util.Iterator; + +import org.junit.Test; +import org.onap.policy.models.base.PfConceptKey; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaDataType; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaDataTypes; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicies; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicy; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyType; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyTypes; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaTopologyTemplate; + +/** + * Import the {@link ToscaServiceTemplateUtilsTest} class. + * + * @author Liam Fallon (liam.fallon@est.tech) + */ +public class ToscaServiceTemplateUtilsTest { + @Test + public void testAddFragmentNulls() { + assertThatThrownBy(() -> { + ToscaServiceTemplateUtils.addFragment(null, null); + }).hasMessageMatching("originalTemplate is marked .*on.*ull but is null"); + + assertThatThrownBy(() -> { + ToscaServiceTemplateUtils.addFragment(null, new JpaToscaServiceTemplate()); + }).hasMessageMatching("originalTemplate is marked .*on.*ull but is null"); + + assertThatThrownBy(() -> { + ToscaServiceTemplateUtils.addFragment(new JpaToscaServiceTemplate(), null); + }).hasMessageMatching("fragmentTemplate is marked .*on.*ull but is null"); + + assertEquals(new JpaToscaServiceTemplate(), + ToscaServiceTemplateUtils.addFragment(new JpaToscaServiceTemplate(), new JpaToscaServiceTemplate())); + } + + @Test + public void testAddFragment() { + JpaToscaServiceTemplate originalTemplate = new JpaToscaServiceTemplate(); + JpaToscaServiceTemplate fragmentTemplate00 = new JpaToscaServiceTemplate(); + + assertEquals(originalTemplate, ToscaServiceTemplateUtils.addFragment(originalTemplate, originalTemplate)); + assertEquals(originalTemplate, ToscaServiceTemplateUtils.addFragment(originalTemplate, fragmentTemplate00)); + assertEquals(originalTemplate, ToscaServiceTemplateUtils.addFragment(fragmentTemplate00, originalTemplate)); + assertEquals(originalTemplate, ToscaServiceTemplateUtils.addFragment(fragmentTemplate00, fragmentTemplate00)); + assertEquals(fragmentTemplate00, ToscaServiceTemplateUtils.addFragment(originalTemplate, originalTemplate)); + assertEquals(fragmentTemplate00, ToscaServiceTemplateUtils.addFragment(originalTemplate, fragmentTemplate00)); + assertEquals(fragmentTemplate00, ToscaServiceTemplateUtils.addFragment(fragmentTemplate00, originalTemplate)); + assertEquals(fragmentTemplate00, ToscaServiceTemplateUtils.addFragment(fragmentTemplate00, fragmentTemplate00)); + + fragmentTemplate00.setDataTypes(new JpaToscaDataTypes()); + fragmentTemplate00.setPolicyTypes(new JpaToscaPolicyTypes()); + + JpaToscaServiceTemplate compositeTemplate00 = + ToscaServiceTemplateUtils.addFragment(originalTemplate, fragmentTemplate00); + assertEquals(compositeTemplate00, + ToscaServiceTemplateUtils.addFragment(compositeTemplate00, fragmentTemplate00)); + assertEquals(compositeTemplate00, + ToscaServiceTemplateUtils.addFragment(compositeTemplate00, new JpaToscaServiceTemplate())); + assertEquals(compositeTemplate00, + ToscaServiceTemplateUtils.addFragment(new JpaToscaServiceTemplate(), compositeTemplate00)); + + JpaToscaDataType dt0 = new JpaToscaDataType(); + dt0.setKey(new PfConceptKey("dt0", "0.0.1")); + dt0.setDescription("dt0 description"); + JpaToscaServiceTemplate fragmentTemplate01 = new JpaToscaServiceTemplate(); + fragmentTemplate01.setDataTypes(new JpaToscaDataTypes()); + fragmentTemplate01.getDataTypes().getConceptMap().put(dt0.getKey(), dt0); + + JpaToscaServiceTemplate compositeTemplate01 = + ToscaServiceTemplateUtils.addFragment(originalTemplate, fragmentTemplate01); + assertEquals(compositeTemplate01, + ToscaServiceTemplateUtils.addFragment(compositeTemplate01, fragmentTemplate01)); + assertEquals(compositeTemplate01, + ToscaServiceTemplateUtils.addFragment(compositeTemplate01, new JpaToscaServiceTemplate())); + assertEquals(compositeTemplate01, + ToscaServiceTemplateUtils.addFragment(new JpaToscaServiceTemplate(), compositeTemplate01)); + + JpaToscaServiceTemplate compositeTemplate02 = + ToscaServiceTemplateUtils.addFragment(compositeTemplate00, fragmentTemplate01); + assertEquals(compositeTemplate02, + ToscaServiceTemplateUtils.addFragment(compositeTemplate02, fragmentTemplate01)); + assertEquals(compositeTemplate02, + ToscaServiceTemplateUtils.addFragment(compositeTemplate02, new JpaToscaServiceTemplate())); + assertEquals(compositeTemplate02, + ToscaServiceTemplateUtils.addFragment(new JpaToscaServiceTemplate(), compositeTemplate02)); + + JpaToscaDataType otherDt0 = new JpaToscaDataType(); + otherDt0.setKey(new PfConceptKey("dt0", "0.0.1")); + otherDt0.setDescription("dt0 description"); + JpaToscaServiceTemplate fragmentTemplate02 = new JpaToscaServiceTemplate(); + fragmentTemplate02.setDataTypes(new JpaToscaDataTypes()); + fragmentTemplate02.getDataTypes().getConceptMap().put(otherDt0.getKey(), otherDt0); + + compositeTemplate00 = ToscaServiceTemplateUtils.addFragment(compositeTemplate00, fragmentTemplate02); + assertEquals(compositeTemplate00, + ToscaServiceTemplateUtils.addFragment(compositeTemplate00, fragmentTemplate02)); + + JpaToscaDataType badOtherDt0 = new JpaToscaDataType(); + badOtherDt0.setKey(new PfConceptKey("dt0", "0.0.1")); + badOtherDt0.setDescription("dt0 bad description"); + JpaToscaServiceTemplate fragmentTemplate03 = new JpaToscaServiceTemplate(); + fragmentTemplate03.setDataTypes(new JpaToscaDataTypes()); + fragmentTemplate03.getDataTypes().getConceptMap().put(otherDt0.getKey(), otherDt0); + fragmentTemplate03.getDataTypes().getConceptMap().put(badOtherDt0.getKey(), badOtherDt0); + + final JpaToscaServiceTemplate compositeTestTemplate = new JpaToscaServiceTemplate(compositeTemplate00); + assertThatThrownBy(() -> { + ToscaServiceTemplateUtils.addFragment(compositeTestTemplate, fragmentTemplate03); + }).hasMessageContaining("entity in incoming fragment does not equal existing entity"); + + JpaToscaServiceTemplate fragmentTemplate04 = new JpaToscaServiceTemplate(); + fragmentTemplate04.setDescription("Another service template"); + assertThatThrownBy(() -> { + ToscaServiceTemplateUtils.addFragment(compositeTestTemplate, fragmentTemplate04); + }).hasMessageContaining("service template in incoming fragment does not equal existing service template"); + + JpaToscaServiceTemplate fragmentTemplate05 = new JpaToscaServiceTemplate(); + fragmentTemplate05.setTopologyTemplate(new JpaToscaTopologyTemplate()); + fragmentTemplate05.getTopologyTemplate().setDescription("topology template description"); + JpaToscaServiceTemplate compositeTemplate03 = + ToscaServiceTemplateUtils.addFragment(compositeTemplate02, fragmentTemplate05); + assertEquals(fragmentTemplate05.getTopologyTemplate(), compositeTemplate03.getTopologyTemplate()); + + JpaToscaServiceTemplate fragmentTemplate06 = new JpaToscaServiceTemplate(); + fragmentTemplate06.setTopologyTemplate(new JpaToscaTopologyTemplate()); + fragmentTemplate06.getTopologyTemplate().setDescription("topology template description"); + JpaToscaServiceTemplate compositeTemplate04 = + ToscaServiceTemplateUtils.addFragment(compositeTemplate03, fragmentTemplate06); + assertEquals(fragmentTemplate06.getTopologyTemplate(), compositeTemplate04.getTopologyTemplate()); + + JpaToscaServiceTemplate fragmentTemplate07 = new JpaToscaServiceTemplate(); + fragmentTemplate07.setTopologyTemplate(new JpaToscaTopologyTemplate()); + fragmentTemplate07.getTopologyTemplate().setDescription("topology template other description"); + assertThatThrownBy(() -> { + ToscaServiceTemplateUtils.addFragment(compositeTemplate04, fragmentTemplate07); + }).hasMessageContaining("topology template in incoming fragment does not equal existing topology template"); + + JpaToscaDataType dt1 = new JpaToscaDataType(); + dt1.setKey(new PfConceptKey("dt1", "0.0.1")); + dt1.setDescription("dt1 description"); + + JpaToscaPolicyType pt0 = new JpaToscaPolicyType(); + pt0.setKey(new PfConceptKey("pt0", "0.0.1")); + pt0.setDescription("pt0 description"); + + JpaToscaPolicy p0 = new JpaToscaPolicy(); + p0.setKey(new PfConceptKey("p0", "0.0.1")); + p0.setDescription("pt0 description"); + + JpaToscaServiceTemplate fragmentTemplate08 = new JpaToscaServiceTemplate(); + + fragmentTemplate08.setDataTypes(new JpaToscaDataTypes()); + fragmentTemplate08.getDataTypes().getConceptMap().put(dt1.getKey(), dt1); + + fragmentTemplate08.setPolicyTypes(new JpaToscaPolicyTypes()); + fragmentTemplate08.getPolicyTypes().getConceptMap().put(pt0.getKey(), pt0); + + fragmentTemplate08.setTopologyTemplate(new JpaToscaTopologyTemplate()); + fragmentTemplate08.getTopologyTemplate().setDescription("topology template description"); + + fragmentTemplate08.getTopologyTemplate().setPolicies(new JpaToscaPolicies()); + fragmentTemplate08.getTopologyTemplate().getPolicies().getConceptMap().put(p0.getKey(), p0); + + assertThatThrownBy(() -> { + ToscaServiceTemplateUtils.addFragment(compositeTemplate04, fragmentTemplate08); + }).hasMessageContaining("JpaToscaPolicy:INVALID:type is null or a null key"); + + p0.setType(pt0.getKey()); + + JpaToscaServiceTemplate compositeTemplate05 = + ToscaServiceTemplateUtils.addFragment(compositeTemplate04, fragmentTemplate08); + Iterator dtIterator = compositeTemplate05.getDataTypes().getAll(null).iterator(); + assertEquals(dt0, dtIterator.next()); + assertEquals(dt1, dtIterator.next()); + assertEquals(pt0, compositeTemplate05.getPolicyTypes().getAll(null).iterator().next()); + assertEquals(p0, compositeTemplate05.getTopologyTemplate().getPolicies().getAll(null).iterator().next()); + + } +} -- 2.16.6