From a6ae7294ecd336d7e88f915710b08e2658eaee00 Mon Sep 17 00:00:00 2001 From: vasraz Date: Sun, 21 Mar 2021 20:48:30 +0000 Subject: Enable selection of base type of service Signed-off-by: MichaelMorris Issue-ID: SDC-3506 Change-Id: Iaba39955fac9056cb0d0f1eccd223c05dfb9c5b4 Signed-off-by: Vasyl Razinkov --- .../java/org/openecomp/sdc/be/model/BaseType.java | 58 ++++++++++++ .../operations/ToscaOperationFacade.java | 21 +++++ .../be/model/operations/api/IElementOperation.java | 4 + .../be/model/operations/impl/ElementOperation.java | 63 ++++++++++++- .../sdc/be/ui/model/UiComponentDataTransfer.java | 3 + .../operations/impl/ElementOperationTest.java | 103 ++++++++++++++++++++- 6 files changed, 250 insertions(+), 2 deletions(-) create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/BaseType.java (limited to 'catalog-model') diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/BaseType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/BaseType.java new file mode 100644 index 0000000000..5c88101b2f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/BaseType.java @@ -0,0 +1,58 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.openecomp.sdc.be.model; + +import com.vdurmont.semver4j.Semver; +import com.vdurmont.semver4j.Semver.SemverType; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import lombok.Getter; +import lombok.Setter; + + +public class BaseType { + @Getter + @Setter + private String toscaResourceName; + + private List versions = new ArrayList<>(); + + public BaseType(final String toscaResourceName) { + this.toscaResourceName = toscaResourceName; + } + + public BaseType(final String toscaResourceName, final List versions) { + this.toscaResourceName = toscaResourceName; + versions.forEach(version -> this.versions.add(new Semver(version, SemverType.LOOSE))); + } + + public void addVersion(final String version) { + versions.add(new Semver(version, SemverType.LOOSE)); + } + + public List getVersions(){ + Collections.sort(versions); + final List versionsAsStrings = new ArrayList<>(); + this.versions.forEach(version -> versionsAsStrings.add(version.getValue())); + return versionsAsStrings; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaOperationFacade.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaOperationFacade.java index 3858912660..06e23f04ea 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaOperationFacade.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaOperationFacade.java @@ -445,6 +445,27 @@ public class ToscaOperationFacade { }); } + public Either getByToscaResourceNameAndVersion(final String toscaResourceName, final String version) { + Either result; + + Map hasProperties = new EnumMap<>(GraphPropertyEnum.class); + Map hasNotProperties = new EnumMap<>(GraphPropertyEnum.class); + + hasProperties.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName); + hasProperties.put(GraphPropertyEnum.VERSION, version); + hasNotProperties.put(GraphPropertyEnum.IS_DELETED, true); + + Either, JanusGraphOperationStatus> getResourceRes = janusGraphDao + .getByCriteria(VertexTypeEnum.NODE_TYPE, hasProperties, hasNotProperties, JsonParseFlagEnum.ParseAll); + if (getResourceRes.isRight()) { + JanusGraphOperationStatus status = getResourceRes.right().value(); + log.debug("failed to find resource with toscaResourceName {}, version {}. Status is {} ", toscaResourceName, version, status); + result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status)); + return result; + } + return getToscaElementByOperation(getResourceRes.left().value().get(0)); + } + private Map> getVendorVersionPredicate(final String vendorRelease) { Map> predicateCriteria = new HashMap<>(); if (!"1.0".equals(vendorRelease)) { diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IElementOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IElementOperation.java index b3f1306a04..aac14625c5 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IElementOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IElementOperation.java @@ -20,6 +20,7 @@ package org.openecomp.sdc.be.model.operations.api; import fj.data.Either; +import java.util.ArrayList; import java.util.List; import java.util.Map; import org.openecomp.sdc.be.config.Configuration; @@ -27,6 +28,7 @@ import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.model.ArtifactType; +import org.openecomp.sdc.be.model.BaseType; import org.openecomp.sdc.be.model.PropertyScope; import org.openecomp.sdc.be.model.Tag; import org.openecomp.sdc.be.model.category.CategoryDefinition; @@ -83,6 +85,8 @@ public interface IElementOperation { boolean inTransaction); Either, ActionStatus> getAllCategories(NodeTypeEnum nodeType, boolean inTransaction); + + List getBaseTypes(String categoryName); Either getCategory(NodeTypeEnum nodeType, String categoryId); diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ElementOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ElementOperation.java index 60ffa1b0f7..054788a519 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ElementOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ElementOperation.java @@ -21,8 +21,10 @@ package org.openecomp.sdc.be.model.operations.impl; import fj.data.Either; import java.util.ArrayList; +import java.util.EnumMap; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -40,14 +42,22 @@ import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; +import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; +import org.openecomp.sdc.be.dao.jsongraph.HealingJanusGraphDao; +import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum; +import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; +import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; import org.openecomp.sdc.be.datatypes.category.CategoryDataDefinition; import org.openecomp.sdc.be.datatypes.category.GroupingDataDefinition; import org.openecomp.sdc.be.datatypes.category.SubCategoryDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; import org.openecomp.sdc.be.model.ArtifactType; +import org.openecomp.sdc.be.model.BaseType; +import org.openecomp.sdc.be.model.LifecycleStateEnum; import org.openecomp.sdc.be.model.PropertyScope; import org.openecomp.sdc.be.model.Tag; import org.openecomp.sdc.be.model.category.CategoryDefinition; @@ -71,10 +81,12 @@ public class ElementOperation implements IElementOperation { private static final String UNKNOWN_CATEGORY_TYPE = "Unknown category type {}"; private static final Logger log = Logger.getLogger(ElementOperation.class.getName()); private JanusGraphGenericDao janusGraphGenericDao; + private HealingJanusGraphDao janusGraphDao; - public ElementOperation(@Qualifier("janusgraph-generic-dao") JanusGraphGenericDao janusGraphGenericDao) { + public ElementOperation(@Qualifier("janusgraph-generic-dao") JanusGraphGenericDao janusGraphGenericDao, @Qualifier("janusgraph-dao") HealingJanusGraphDao janusGraphDao) { super(); this.janusGraphGenericDao = janusGraphGenericDao; + this.janusGraphDao = janusGraphDao; } private static NodeTypeEnum getChildNodeType(NodeTypeEnum parentTypeEnum) { @@ -367,6 +379,55 @@ public class ElementOperation implements IElementOperation { } } + @Override + public List getBaseTypes(final String categoryName){ + final ArrayList baseTypes = new ArrayList<>(); + final Map categoriesSpecificBaseTypes = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceNodeTypes(); + final String categorySpecificBaseType = categoriesSpecificBaseTypes == null ? null : categoriesSpecificBaseTypes.get(categoryName); + final String generalBaseType = ConfigurationManager.getConfigurationManager().getConfiguration().getGenericAssetNodeTypes().get("Service"); + final String baseToscaResourceName = categorySpecificBaseType == null? generalBaseType : categorySpecificBaseType; + + final Map props = new EnumMap<>(GraphPropertyEnum.class); + props.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, baseToscaResourceName); + props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name()); + final Either, JanusGraphOperationStatus> baseTypeVertex = janusGraphDao + .getByCriteria(VertexTypeEnum.NODE_TYPE, props, JsonParseFlagEnum.ParseAll); + + if (baseTypeVertex.isLeft()) { + BaseType baseType = new BaseType(baseToscaResourceName); + baseTypes.add(baseType); + + final Map> typesDerivedFromBaseType = new LinkedHashMap<>(); + baseTypeVertex.left().value().forEach(v -> { + baseType.addVersion((String)v.getMetadataProperty(GraphPropertyEnum.VERSION)); + addTypesDerivedFromVertex(typesDerivedFromBaseType, v); + }); + + typesDerivedFromBaseType.forEach((k,v) -> baseTypes.add(new BaseType(k, v))); + } + + return baseTypes; + } + + private Map> addTypesDerivedFromVertex(final Map> types, final GraphVertex vertex) { + final Either, JanusGraphOperationStatus> derivedFromVertex = + janusGraphDao.getParentVertices(vertex, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.ParseAll); + if (derivedFromVertex.isLeft()) { + derivedFromVertex.left().value().stream().filter(v -> v.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED.name())) + .forEach(v -> { + addBaseTypeVersion(types, (String) v.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME), (String) v.getMetadataProperty(GraphPropertyEnum.VERSION)); + addTypesDerivedFromVertex(types, v); + }); + } + return types; + } + + private void addBaseTypeVersion(final Map> baseTypes, final String baseTypeToscaResourceName, final String baseTypeVersion) { + List versions = baseTypes.get(baseTypeToscaResourceName) == null ? new ArrayList<>(): baseTypes.get(baseTypeToscaResourceName); + versions.add(baseTypeVersion); + baseTypes.put(baseTypeToscaResourceName, versions); + } + private JanusGraphOperationStatus setSubCategories(NodeTypeEnum parentNodeType, CategoryDefinition parentCategory) { NodeTypeEnum childNodeType = getChildNodeType(parentNodeType); if (childNodeType != null) { diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiComponentDataTransfer.java b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiComponentDataTransfer.java index f9741fc234..92149143e6 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiComponentDataTransfer.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiComponentDataTransfer.java @@ -79,4 +79,7 @@ public class UiComponentDataTransfer { private List properties; private List attributes; private Map> componentInstancesInterfaces; + private String derivedFromGenericType; + private String derivedFromGenericVersion; + } diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ElementOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ElementOperationTest.java index 3597d02834..230fbe1aba 100644 --- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ElementOperationTest.java +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ElementOperationTest.java @@ -27,10 +27,20 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.openecomp.sdc.be.config.ArtifactConfiguration; import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.impl.HealingPipelineDao; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphClient; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; +import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; +import org.openecomp.sdc.be.dao.jsongraph.HealingJanusGraphDao; +import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum; +import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; +import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.model.ArtifactType; +import org.openecomp.sdc.be.model.BaseType; +import org.openecomp.sdc.be.model.LifecycleStateEnum; import org.openecomp.sdc.be.model.ModelTestBase; import org.openecomp.sdc.be.model.PropertyScope; import org.openecomp.sdc.be.model.Tag; @@ -44,12 +54,16 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; import java.util.List; import java.util.Map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.*; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:application-context-test.xml") @@ -123,7 +137,7 @@ public class ElementOperationTest extends ModelTestBase { } private ElementOperation createTestSubject() { - return new ElementOperation(new JanusGraphGenericDao(new JanusGraphClient())); + return new ElementOperation(new JanusGraphGenericDao(new JanusGraphClient()), new HealingJanusGraphDao(new HealingPipelineDao(), new JanusGraphClient())); } @@ -454,4 +468,91 @@ public class ElementOperationTest extends ModelTestBase { name = ""; result = testSubject.getNewCategoryData(name, type, null); } + + @Test + public void testBaseTypes_serviceSpecific() { + Map preExistingServiceNodeTypes = configurationManager.getConfiguration().getServiceNodeTypes(); + Map preExistingGenericNodeTypes = + configurationManager.getConfiguration().getGenericAssetNodeTypes(); + + try { + Map serviceNodeTypes = new HashMap<>(); + serviceNodeTypes.put("serviceCategoryA", "org.base.type"); + configurationManager.getConfiguration().setServiceNodeTypes(serviceNodeTypes); + + Map genericNodeTypes = new HashMap<>(); + genericNodeTypes.put("service", "org.service.default"); + configurationManager.getConfiguration().setGenericAssetNodeTypes(genericNodeTypes); + + HealingJanusGraphDao healingJanusGraphDao = mock(HealingJanusGraphDao.class); + ElementOperation elementOperation = + new ElementOperation(new JanusGraphGenericDao(new JanusGraphClient()), healingJanusGraphDao); + + GraphVertex baseTypeVertex = mock(GraphVertex.class); + when(baseTypeVertex.getMetadataProperty(GraphPropertyEnum.VERSION)).thenReturn("1.0"); + when(healingJanusGraphDao.getByCriteria(any(), any(), any())) + .thenReturn(Either.left(Collections.singletonList(baseTypeVertex))); + + GraphVertex derivedTypeVertex = mock(GraphVertex.class); + when(derivedTypeVertex.getMetadataProperty(GraphPropertyEnum.STATE)).thenReturn(LifecycleStateEnum.CERTIFIED.name()); + when(derivedTypeVertex.getMetadataProperty(GraphPropertyEnum.VERSION)).thenReturn("1.0"); + + GraphVertex derivedTypeVertexUncertified = mock(GraphVertex.class); + when(derivedTypeVertexUncertified.getMetadataProperty(GraphPropertyEnum.STATE)).thenReturn(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN.name()); + when(derivedTypeVertexUncertified.getMetadataProperty(GraphPropertyEnum.VERSION)).thenReturn("1.1"); + + when(healingJanusGraphDao.getParentVertices(baseTypeVertex, EdgeLabelEnum.DERIVED_FROM, + JsonParseFlagEnum.ParseAll)).thenReturn(Either.left(Collections.singletonList(derivedTypeVertex))); + when(healingJanusGraphDao.getParentVertices(derivedTypeVertex, EdgeLabelEnum.DERIVED_FROM, + JsonParseFlagEnum.ParseAll)).thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND)); + when(derivedTypeVertex.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME)) + .thenReturn("org.parent.type"); + + List baseTypes = elementOperation.getBaseTypes("serviceCategoryA"); + + assertEquals(2, baseTypes.size()); + assertEquals("org.base.type", baseTypes.get(0).getToscaResourceName()); + assertEquals(1, baseTypes.get(0).getVersions().size()); + assertEquals("1.0", baseTypes.get(0).getVersions().get(0)); + assertEquals("org.parent.type", baseTypes.get(1).getToscaResourceName()); + } finally { + configurationManager.getConfiguration().setServiceNodeTypes(preExistingServiceNodeTypes); + configurationManager.getConfiguration().setGenericAssetNodeTypes(preExistingGenericNodeTypes); + } + } + + @Test + public void testBaseTypes_default() { + Map preExistingServiceNodeTypes = configurationManager.getConfiguration().getServiceNodeTypes(); + Map preExistingGenericNodeTypes = + configurationManager.getConfiguration().getGenericAssetNodeTypes(); + + try { + Map genericNodeTypes = new HashMap<>(); + genericNodeTypes.put("Service", "org.service.default"); + configurationManager.getConfiguration().setGenericAssetNodeTypes(genericNodeTypes); + configurationManager.getConfiguration().setServiceNodeTypes(null); + + HealingJanusGraphDao healingJanusGraphDao = mock(HealingJanusGraphDao.class); + ElementOperation elementOperation = + new ElementOperation(new JanusGraphGenericDao(new JanusGraphClient()), healingJanusGraphDao); + + GraphVertex baseTypeVertex = mock(GraphVertex.class); + when(baseTypeVertex.getMetadataProperty(GraphPropertyEnum.VERSION)).thenReturn("1.0"); + when(healingJanusGraphDao.getByCriteria(any(), any(), any())) + .thenReturn(Either.left(Collections.singletonList(baseTypeVertex))); + + when(healingJanusGraphDao.getParentVertices(baseTypeVertex, EdgeLabelEnum.DERIVED_FROM, + JsonParseFlagEnum.ParseAll)).thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND)); + + List baseTypes = elementOperation.getBaseTypes("serviceCategoryA"); + + assertEquals(1, baseTypes.size()); + assertEquals("org.service.default", baseTypes.get(0).getToscaResourceName()); + assertEquals(1, baseTypes.get(0).getVersions().size()); + } finally { + configurationManager.getConfiguration().setServiceNodeTypes(preExistingServiceNodeTypes); + configurationManager.getConfiguration().setGenericAssetNodeTypes(preExistingGenericNodeTypes); + } + } } -- cgit 1.2.3-korg