From 13a7f6743fbcc736c871d8168d2a7dcbda1daaba Mon Sep 17 00:00:00 2001 From: aribeiro Date: Thu, 27 Feb 2020 13:15:28 +0000 Subject: [PATCH] Include derived_from types in generated csar Issue-ID: SDC-2775 Change-Id: I7b90ff78c389e5680cacafda2065669f6baf1735 Signed-off-by: aribeiro --- .../java/org/openecomp/sdc/be/tosca/CsarUtils.java | 209 +++++++++++++++------ .../openecomp/sdc/be/tosca/ToscaExportHandler.java | 161 ++++++++++++---- .../org/openecomp/sdc/be/tosca/CsarUtilsTest.java | 97 ++++++---- catalog-be/src/test/resources/sdc.zip | Bin 0 -> 28382 bytes .../java/org/openecomp/sdc/be/model/Resource.java | 176 ++++++----------- .../model/jsonjanusgraph/datamodel/NodeType.java | 48 +---- .../operations/NodeTypeOperation.java | 30 +-- .../model/jsonjanusgraph/utils/ModelConverter.java | 75 ++++++-- .../org/openecomp/sdc/be/model/ResourceTest.java | 19 +- 9 files changed, 481 insertions(+), 334 deletions(-) create mode 100644 catalog-be/src/test/resources/sdc.zip diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java index 2721fda2c5..e50523854d 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java @@ -22,14 +22,36 @@ package org.openecomp.sdc.be.tosca; import fj.data.Either; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; import org.apache.commons.codec.binary.Base64; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.commons.lang.WordUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.ImmutableTriple; import org.apache.commons.lang3.tuple.Triple; +import org.onap.sdc.tosca.services.YamlUtil; import org.openecomp.sdc.be.components.impl.ImportUtils; +import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException; import org.openecomp.sdc.be.config.Configuration.ArtifactTypeConfig; import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.api.ActionStatus; @@ -45,6 +67,7 @@ import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.ComponentInstance; import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Product; import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.Service; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade; @@ -57,6 +80,7 @@ import org.openecomp.sdc.be.resources.data.SdcSchemaFilesData; import org.openecomp.sdc.be.tosca.model.ToscaTemplate; import org.openecomp.sdc.be.tosca.utils.OperationArtifactUtil; import org.openecomp.sdc.be.utils.CommonBeUtils; +import org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum; import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; import org.openecomp.sdc.common.api.ArtifactTypeEnum; import org.openecomp.sdc.common.impl.ExternalConfiguration; @@ -69,26 +93,7 @@ import org.openecomp.sdc.common.util.ValidationUtils; import org.openecomp.sdc.common.zip.ZipUtils; import org.openecomp.sdc.exception.ResponseFormat; import org.springframework.beans.factory.annotation.Autowired; - -import java.io.BufferedOutputStream; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; -import java.util.zip.ZipOutputStream; +import org.yaml.snakeyaml.Yaml; /** * @author tg851x @@ -290,16 +295,16 @@ public class CsarUtils { Either latestSchemaFilesFromCassandra = getLatestSchemaFilesFromCassandra(); if(latestSchemaFilesFromCassandra.isRight()){ - log.error("Error retrieving SDC Schema files from cassandra" ); + log.error("Error retrieving SDC Schema files from cassandra"); return Either.right(latestSchemaFilesFromCassandra.right().value()); } - //add files from retrieved SDC.zip to Definitions folder in CSAR - Either addSchemaFilesFromCassandra = addSchemaFilesFromCassandra(zip, latestSchemaFilesFromCassandra.left().value()); + final byte[] schemaFileZip = latestSchemaFilesFromCassandra.left().value(); - if(addSchemaFilesFromCassandra.isRight()){ - return addSchemaFilesFromCassandra; - } + final List nodesFromPackage = findNonRootNodesFromPackage(dependencies); + + //add files from retrieved SDC.zip to Definitions folder in CSAR + addSchemaFilesFromCassandra(zip, schemaFileZip, nodesFromPackage); Either collectedComponentCsarDefinition = collectComponentCsarDefinition(component); @@ -311,8 +316,8 @@ public class CsarUtils { for (CsarEntryGenerator generator: generators) { log.debug("Invoking CsarEntryGenerator: {}", generator.getClass().getName()); for (Entry pluginGeneratedFile : generator.generateCsarEntries(component).entrySet()) { - zip.putNextEntry(new ZipEntry(pluginGeneratedFile.getKey())); - zip.write(pluginGeneratedFile.getValue()); + zip.putNextEntry(new ZipEntry(pluginGeneratedFile.getKey())); + zip.write(pluginGeneratedFile.getValue()); } } } @@ -320,6 +325,84 @@ public class CsarUtils { return writeAllFilesToCsar(component, collectedComponentCsarDefinition.left().value(), zip, isInCertificationRequest); } + /** + * Create a list of all derived nodes found on the package + * + * @param dependencies all node dependencies + * @return a list of nodes + */ + private List findNonRootNodesFromPackage(final List> dependencies) { + final List nodes = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(dependencies)) { + final String NATIVE_ROOT = "tosca.nodes.Root"; + dependencies.forEach(dependency -> { + if (dependency.getRight() instanceof Resource) { + final Resource resource = (Resource) dependency.getRight(); + if (CollectionUtils.isNotEmpty(resource.getDerivedList())) { + resource.getDerivedList().stream() + .filter(node -> !nodes.contains(node) && !NATIVE_ROOT.equalsIgnoreCase(node)) + .forEach(node -> nodes.add(node)); + } + } + }); + } + return nodes; + } + + /** + * Writes a new zip entry + * + * @param zipInputStream the zip entry to be read + * @return a map of the given zip entry + */ + private Map readYamlZipEntry(final ZipInputStream zipInputStream) throws IOException { + final int initSize = 2048; + final StringBuilder zipEntry = new StringBuilder(); + final byte[] buffer = new byte[initSize]; + int read = 0; + while ((read = zipInputStream.read(buffer, 0, initSize)) >= 0) { + zipEntry.append(new String(buffer, 0, read)); + } + + return (Map) new Yaml().load(zipEntry.toString()); + } + + /** + * Filters and removes all duplicated nodes found + * + * @param nodesFromPackage a List of all derived nodes found on the given package + * @param nodesFromArtifactFile represents the nodes.yml file stored in Cassandra + * @return a nodes Map updated + */ + private Map updateNodeYml(final List nodesFromPackage, + final Map nodesFromArtifactFile) { + + if (MapUtils.isNotEmpty(nodesFromArtifactFile)) { + final String nodeTypeBlock = ToscaTagNamesEnum.NODE_TYPES.getElementName(); + final Map nodeTypes = (Map) nodesFromArtifactFile.get(nodeTypeBlock); + nodesFromPackage.stream() + .filter(nodeTypes::containsKey) + .forEach(nodeTypes::remove); + + nodesFromArtifactFile.replace(nodeTypeBlock, nodeTypes); + } + + return nodesFromArtifactFile; + } + + /** + * Updates the zip entry from the given parameters + * + * @param byteArrayOutputStream an output stream in which the data is written into a byte array. + * @param nodesYaml a Map of nodes to be written + */ + private void updateZipEntry(final ByteArrayOutputStream byteArrayOutputStream, + final Map nodesYaml) throws IOException { + if (MapUtils.isNotEmpty(nodesYaml)) { + byteArrayOutputStream.write(new YamlUtil().objectToYaml(nodesYaml).getBytes()); + } + } + private Either getZipOutputStreamResponseFormatEither(ZipOutputStream zip, List> dependencies, Map> innerComponentsCache) throws IOException { String fileName; if (dependencies != null && !dependencies.isEmpty()) { @@ -374,43 +457,57 @@ public class CsarUtils { return null; } - private Either addSchemaFilesFromCassandra(ZipOutputStream zip, byte[] schemaFileZip) { - - final int initSize = 2048; - - log.debug("Starting copy from Schema file zip to CSAR zip"); - try (final ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(schemaFileZip)); - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - final BufferedOutputStream bos = new BufferedOutputStream(out, initSize)) { - - ZipEntry entry; - while ((entry = zipStream.getNextEntry()) != null) { - ZipUtils.checkForZipSlipInRead(entry); - final String entryName = entry.getName(); - int readSize = initSize; - final byte[] entryData = new byte[initSize]; - + private void addSchemaFilesFromCassandra(final ZipOutputStream zip, + final byte[] schemaFileZip, + final List nodesFromPackage) { + final int initSize = 2048; + log.debug("Starting copy from Schema file zip to CSAR zip"); + try (final ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(schemaFileZip)); + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + final BufferedOutputStream bos = new BufferedOutputStream(out, initSize)) { + + ZipEntry entry; + while ((entry = zipStream.getNextEntry()) != null) { + ZipUtils.checkForZipSlipInRead(entry); + final String entryName = entry.getName(); + int readSize = initSize; + final byte[] entryData = new byte[initSize]; + if (entryName.equalsIgnoreCase("nodes.yml")) { + handleNode(zipStream, out, nodesFromPackage); + } else { while ((readSize = zipStream.read(entryData, 0, readSize)) != -1) { bos.write(entryData, 0, readSize); } - bos.flush(); - out.flush(); - zip.putNextEntry(new ZipEntry(DEFINITIONS_PATH + entryName)); - zip.write(out.toByteArray()); - zip.flush(); - out.reset(); } - } catch (final Exception e) { - log.error("Error while writing the SDC schema file to the CSAR", e); - return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + out.flush(); + zip.putNextEntry(new ZipEntry(DEFINITIONS_PATH + entryName)); + zip.write(out.toByteArray()); + zip.flush(); + out.reset(); } - - log.debug("Finished coppy from Schema file zip to CSAR zip"); - return Either.left(zip); + } catch (final Exception e) { + log.error("Error while writing the SDC schema file to the CSAR", e); + throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); } + log.debug("Finished copy from Schema file zip to CSAR zip"); + } + /** + * Handles the nodes.yml zip entry, updating the nodes.yml to avoid duplicated nodes on it. + * + * @param zipInputStream the zip entry to be read + * @param byteArrayOutputStream an output stream in which the data is written into a byte array. + * @param nodesFromPackage list of all nodes found on the onboarded package + */ + private void handleNode(final ZipInputStream zipInputStream, + final ByteArrayOutputStream byteArrayOutputStream, + final List nodesFromPackage) throws IOException { + final Map nodesFromArtifactFile = readYamlZipEntry(zipInputStream); + final Map nodesYaml = updateNodeYml(nodesFromPackage, nodesFromArtifactFile); + updateZipEntry(byteArrayOutputStream, nodesYaml); + } private void addInnerComponentsToCache(Map> componentCache, Component childComponent) { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java index 976842136f..64afee7904 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java @@ -163,7 +163,8 @@ public class ToscaExportHandler { private static final String FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION = "convertToToscaTemplate - failed to get Default Imports section from configuration"; private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}"; private static final List>> DEFAULT_IMPORTS = ConfigurationManager - .getConfigurationManager().getConfiguration().getDefaultImports(); + .getConfigurationManager().getConfiguration().getDefaultImports(); + private static final String NATIVE_ROOT = "tosca.nodes.Root"; private static YamlUtil yamlUtil = new YamlUtil(); public ToscaExportHandler(){} @@ -505,60 +506,142 @@ public class ToscaExportHandler { return Either.left(new ImmutablePair<>(toscaTemplate, componentCache)); } - private void createDependency(Map componentCache, List>> imports, - List> dependecies, ComponentInstance ci) { - Map files = new HashMap<>(); - Map> importsListMember = new HashMap<>(); - StringBuilder keyNameBuilder; - - Component componentRI = componentCache.get(ci.getComponentUid()); + private void createDependency(final Map componentCache, + final List>> imports, + final List> dependencies, + final ComponentInstance componentInstance) { + log.debug("createDependency componentCache {}",componentCache); + final Component componentRI = componentCache.get(componentInstance.getComponentUid()); if (componentRI == null) { // all resource must be only once! - Either resource = toscaOperationFacade - .getToscaFullElement(ci.getComponentUid()); + final Either resource = toscaOperationFacade + .getToscaFullElement(componentInstance.getComponentUid()); if ((resource.isRight()) && (log.isDebugEnabled())) { - log.debug("Failed to fetch resource with id {} for instance {}",ci.getComponentUid() ,ci.getUniqueId()); + log.debug("Failed to fetch resource with id {} for instance {}", componentInstance.getComponentUid(), + componentInstance.getUniqueId()); return ; } + final Component fetchedComponent = resource.left().value(); + setComponentCache(componentCache, componentInstance, fetchedComponent); + addDependencies(imports, dependencies, fetchedComponent); + } + } - Component fetchedComponent = resource.left().value(); - componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent); + /** + * Sets a componentCache from the given component/resource. + */ + private void setComponentCache(final Map componentCache, + final ComponentInstance componentInstance, + final Component fetchedComponent) { + componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent); + if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) { + final Either sourceService = toscaOperationFacade + .getToscaFullElement(componentInstance.getSourceModelUid()); + if (sourceService.isRight() && (log.isDebugEnabled())) { + log.debug("Failed to fetch source service with id {} for proxy {}", + componentInstance.getSourceModelUid(), componentInstance.getUniqueId()); + } + final Component fetchedSource = sourceService.left().value(); + componentCache.put(fetchedSource.getUniqueId(), fetchedSource); + } + } - if (ci.getOriginType() == OriginTypeEnum.ServiceProxy){ - Either sourceService = toscaOperationFacade - .getToscaFullElement(ci.getSourceModelUid()); - if (sourceService.isRight() && (log.isDebugEnabled())) { - log.debug("Failed to fetch source service with id {} for proxy {}", ci.getSourceModelUid(), ci.getUniqueId()); - } - Component fetchedSource = sourceService.left().value(); - componentCache.put(fetchedSource.getUniqueId(), fetchedSource); + /** + * Retrieves all derived_from nodes and stores it in a predictable order. + */ + private void addDependencies(final List>> imports, + final List> dependencies, + final Component fetchedComponent) { + final Set componentsList = new LinkedHashSet<>(); + if (fetchedComponent instanceof Resource) { + log.debug("fetchedComponent is a resource {}",fetchedComponent); + + final Optional> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent, componentsList); + if (derivedFromMapOfIdToName.isPresent()) { + derivedFromMapOfIdToName.get().entrySet().forEach(entry -> { + log.debug("Started entry.getValue() : {}",entry.getValue()); + if (!NATIVE_ROOT.equals(entry.getValue())) { + Either resourcefetched = toscaOperationFacade + .getToscaElement(entry.getKey()); + if (resourcefetched != null && resourcefetched.isLeft()) { + componentsList.add(resourcefetched.left().value()); + } + } + }); } + setImports(imports, dependencies, componentsList); + } + } - componentRI = fetchedComponent; + /** + * Returns all derived_from nodes found. + */ + private Optional> getDerivedFromMapOfIdToName(final Component fetchedComponent, + final Set componentsList) { + final Resource parentResource = (Resource) fetchedComponent; + Map derivedFromMapOfIdToName = new HashMap<>(); + if(CollectionUtils.isNotEmpty(parentResource.getComponentInstances())) { + componentsList.add(fetchedComponent); + for (final ComponentInstance componentInstance : parentResource.getComponentInstances()) { + final Either resourcefetched = toscaOperationFacade + .getToscaElement(componentInstance.getComponentUid()); + if (resourcefetched != null && resourcefetched.isLeft()) { + final Map derivedWithId = resourcefetched.left().value().getDerivedFromMapOfIdToName(); + if (MapUtils.isNotEmpty(derivedWithId)) { + derivedFromMapOfIdToName.putAll(derivedWithId); + } + } + } + } else { + derivedFromMapOfIdToName = parentResource.getDerivedFromMapOfIdToName(); + } + log.debug("Started derivedFromMapOfIdToName: {}", derivedFromMapOfIdToName); + return Optional.ofNullable(derivedFromMapOfIdToName); + } - Map toscaArtifacts = componentRI.getToscaArtifacts(); - ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE); + /** + * Creates a resource map and adds it to the import list. + */ + private void setImports(final List>> imports, + final List> dependencies, + final Set componentsList) { + componentsList.forEach(component -> { + final Map toscaArtifacts = component.getToscaArtifacts(); + final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE); if (artifactDefinition != null) { - String artifactName = artifactDefinition.getArtifactName(); + final Map files = new HashMap<>(); + final String artifactName = artifactDefinition.getArtifactName(); files.put(IMPORTS_FILE_KEY, artifactName); - keyNameBuilder = new StringBuilder(); - keyNameBuilder.append(fetchedComponent.getComponentType().toString().toLowerCase()); + final StringBuilder keyNameBuilder = new StringBuilder(); + keyNameBuilder.append(component.getComponentType().toString().toLowerCase()); keyNameBuilder.append("-"); - keyNameBuilder.append(ci.getComponentName()); - importsListMember.put(keyNameBuilder.toString(), files); - imports.add(importsListMember); - dependecies.add(new ImmutableTriple<>(artifactName, - artifactDefinition.getEsId(), fetchedComponent)); - - if (!ModelConverter.isAtomicComponent(componentRI)) { - importsListMember = new HashMap<>(); - Map interfaceFiles = new HashMap<>(); + keyNameBuilder.append(component.getName()); + addImports(imports, keyNameBuilder, files); + dependencies + .add(new ImmutableTriple(artifactName, artifactDefinition.getEsId(), + component)); + + if (!ModelConverter.isAtomicComponent(component)) { + final Map interfaceFiles = new HashMap<>(); interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName)); keyNameBuilder.append("-interface"); - importsListMember.put(keyNameBuilder.toString(), interfaceFiles); - imports.add(importsListMember); + addImports(imports, keyNameBuilder, interfaceFiles); } } + }); + } + + /** + * Adds the found resource to the import definition list. + */ + private void addImports(final List>> imports, + final StringBuilder keyNameBuilder, + final Map files) { + final String mapKey = keyNameBuilder.toString(); + if (imports.stream().allMatch(stringMapMap -> stringMapMap.get(mapKey) == null)) { + final Map> importsListMember = new HashMap<>(); + importsListMember.put(keyNameBuilder.toString(), files); + imports.add(importsListMember); } } @@ -952,7 +1035,7 @@ public class ToscaExportHandler { toscaNodeType.setDescription(component.getDescription()); } else { String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType() - : "tosca.nodes.Root"; + : NATIVE_ROOT; toscaNodeType.setDerived_from(derivedFrom); } return toscaNodeType; diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/CsarUtilsTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/CsarUtilsTest.java index a838ded853..cdea369fe8 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/CsarUtilsTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/CsarUtilsTest.java @@ -20,12 +20,34 @@ package org.openecomp.sdc.be.tosca; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import fj.data.Either; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; import mockit.Deencapsulation; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.ImmutableTriple; import org.apache.commons.lang3.tuple.Triple; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.InjectMocks; @@ -60,23 +82,6 @@ import org.openecomp.sdc.common.api.ArtifactTypeEnum; import org.openecomp.sdc.common.impl.ExternalConfiguration; import org.openecomp.sdc.exception.ResponseFormat; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - public class CsarUtilsTest extends BeConfDependentTest { @InjectMocks @@ -107,6 +112,8 @@ public class CsarUtilsTest extends BeConfDependentTest { } + private final List nodesFromPackage = Arrays.asList("tosca.nodes.Root", "tosca.nodes.Container.Application"); + private NonMetaArtifactInfo createNonMetaArtifactInfoTestSubject() { return new CsarUtils.NonMetaArtifactInfo("mock", "mock", ArtifactTypeEnum.AAI_SERVICE_MODEL, ArtifactGroupTypeEnum.DEPLOYMENT, new byte[0], "mock", true); @@ -475,27 +482,6 @@ public class CsarUtilsTest extends BeConfDependentTest { } } - - @Test - public void testAddSchemaFilesFromCassandra() throws IOException { - try (ByteArrayOutputStream out = new ByteArrayOutputStream(); - ZipOutputStream zip = new ZipOutputStream(out); - ByteArrayOutputStream outMockStream = new ByteArrayOutputStream(); - ZipOutputStream outMock = new ZipOutputStream(outMockStream);) { - - outMock.putNextEntry(new ZipEntry("mock1")); - outMock.write(new byte[1]); - outMock.putNextEntry(new ZipEntry("mock2")); - outMock.write(new byte[3]); - outMock.close(); - byte[] byteArray = outMockStream.toByteArray(); - Deencapsulation.invoke(testSubject, "addSchemaFilesFromCassandra", zip, byteArray); - } catch (Exception e) { - e.printStackTrace(); - } - - } - @Test public void testAddInnerComponentsToCache() { Map> componentCache = new HashMap<>(); @@ -957,4 +943,39 @@ public class CsarUtilsTest extends BeConfDependentTest { assertTrue(eitherNonMetaArtifact.isRight()); assertTrue(!collectedWarningMessages.isEmpty()); } + + @Test(expected = IOException.class) + public void testAddSchemaFilesFromCassandraAddingDuplicatedEntry() throws IOException { + final String rootPath = System.getProperty("user.dir"); + final Path path = Paths.get(rootPath + "/src/test/resources/sdc.zip"); + try { + final byte[] data = Files.readAllBytes(path); + try (final ByteArrayOutputStream out = new ByteArrayOutputStream(); + final ZipOutputStream zip = new ZipOutputStream(out);) { + Deencapsulation.invoke(testSubject, "addSchemaFilesFromCassandra", + zip, data, nodesFromPackage); + zip.putNextEntry(new ZipEntry("Definitions/nodes.yml")); + zip.finish(); + } + } catch (final IOException e) { + Assert.assertTrue("duplicate entry: Definitions/nodes.yml".equals(e.getMessage())); + throw new IOException("Could not add Schema Files From Cassandra", e); + } + } + + @Test + public void testFindNonRootNodesFromPackage() { + final Resource resource = new Resource(); + resource.setDerivedList(nodesFromPackage); + final Component component = resource; + final List> dependencies = new ArrayList<>(); + final Triple triple = Triple.of("fileName", "cassandraId", component); + dependencies.add(triple); + final List expectedResult = Arrays.asList("tosca.nodes.Container.Application"); + final List result = Deencapsulation.invoke(testSubject, + "findNonRootNodesFromPackage", dependencies); + assertTrue(CollectionUtils.isNotEmpty(result)); + assertEquals(expectedResult, result); + } + } diff --git a/catalog-be/src/test/resources/sdc.zip b/catalog-be/src/test/resources/sdc.zip new file mode 100644 index 0000000000000000000000000000000000000000..55a351508f7c9b47b30628357066258a92395493 GIT binary patch literal 28382 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 literal 0 HcmV?d00001 diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java index 8100f988a2..a38095a3ce 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java @@ -20,6 +20,14 @@ package org.openecomp.sdc.be.model; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.utils.MapUtil; import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; @@ -27,18 +35,26 @@ import org.openecomp.sdc.be.datatypes.elements.InterfaceInstanceDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; - +@Getter +@Setter +@EqualsAndHashCode +@ToString public class Resource extends Component { + /** + * Please note that more than one "derivedFrom" resource is not currently supported by the app. The first list + * element is always addressed. + */ private List derivedFrom; + /** + * The derivedList is a chain of derivedFrom. e.g. if resource C is derived from resource B that is derived from + * resource A - then A, B is the "DerivedList" of resource C + */ private List derivedList; + private Map derivedFromMapOfIdToName; + private List attributes; private Map instInterfaces; @@ -48,7 +64,7 @@ public class Resource extends Component { public Resource() { super(new ResourceMetadataDefinition()); this.getComponentMetadataDefinition().getMetadataDataDefinition() - .setComponentType(ComponentTypeEnum.RESOURCE); + .setComponentType(ComponentTypeEnum.RESOURCE); } public Resource(ComponentMetadataDefinition componentMetadataDefinition) { @@ -59,82 +75,30 @@ public class Resource extends Component { this.getComponentMetadataDefinition().getMetadataDataDefinition().setComponentType(ComponentTypeEnum.RESOURCE); } - /** - * Please note that more than one "derivedFrom" resource is not currently - * supported by the app. The first list element is always addressed. - * - * @return - */ - public List getDerivedFrom() { - return derivedFrom; - } - - public void setDerivedFrom(List derivedFrom) { - this.derivedFrom = derivedFrom; - } - - /** - * The derivedList is a chain of derivedFrom. e.g. if resource C is derived - * from resource B that is derived from resource A - then A, B is the - * "DerivedList" of resource C - * - * @return - */ - public List getDerivedList() { - return derivedList; - } - - public void setDerivedList(List derivedList) { - this.derivedList = derivedList; - } - + @Override public List getProperties() { return properties; } + @Override public void setProperties(List properties) { this.properties = properties; } - public List getAttributes() { - return attributes; - } - - public void setAttributes(List attributes) { - this.attributes = attributes; - } - - public Map getInstInterfaces() { - return instInterfaces; - } - - public void setInstInterfaces( - Map instInterfaces) { - this.instInterfaces = instInterfaces; - } - public Boolean isAbstract() { return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition() - .getMetadataDataDefinition()) - .isAbstract(); + .getMetadataDataDefinition()) + .isAbstract(); } public void setAbstract(Boolean isAbstract) { ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) - .setAbstract(isAbstract); - } - - public List getDefaultCapabilities() { - return defaultCapabilities; - } - - public void setDefaultCapabilities(List defaultCapabilities) { - this.defaultCapabilities = defaultCapabilities; + .setAbstract(isAbstract); } public String getCost() { return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) - .getCost(); + .getCost(); } public void setCost(String cost) { @@ -143,103 +107,72 @@ public class Resource extends Component { public String getLicenseType() { return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) - .getLicenseType(); + .getLicenseType(); } public void setLicenseType(String licenseType) { ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) - .setLicenseType(licenseType); + .setLicenseType(licenseType); } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + super.hashCode(); - result = prime * result + ((attributes == null) ? 0 : attributes.hashCode()); - result = prime * result + ((defaultCapabilities == null) ? 0 : defaultCapabilities.hashCode()); - result = prime * result + ((derivedFrom == null) ? 0 : derivedFrom.hashCode()); - result = prime * result + ((properties == null) ? 0 : properties.hashCode()); - result = prime * result + ((derivedList == null) ? 0 : derivedList.hashCode()); - return result; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - Resource resource = (Resource) o; - return Objects.equals(derivedFrom, resource.derivedFrom) && - Objects.equals(derivedList, resource.derivedList) && - Objects.equals(properties, resource.properties) && - Objects.equals(attributes, resource.attributes) && - Objects.equals(defaultCapabilities, resource.defaultCapabilities); - } - - - @Override - public String toString() { - return "Resource [derivedFrom=" + derivedFrom + ", properties=" + properties + ", attributes=" + attributes - + ", defaultCapabilities=" + defaultCapabilities + ", additionalInformation=" + additionalInformation - + "Metadata [" + getComponentMetadataDefinition().getMetadataDataDefinition().toString() + "]"; - } public String getToscaResourceName() { return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) - .getToscaResourceName(); + .getToscaResourceName(); } public void setToscaResourceName(String toscaResourceName) { ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) - .setToscaResourceName(toscaResourceName); + .setToscaResourceName(toscaResourceName); } public ResourceTypeEnum getResourceType() { return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) - .getResourceType(); + .getResourceType(); } public void setResourceType(ResourceTypeEnum resourceType) { ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) - .setResourceType(resourceType); + .setResourceType(resourceType); } public void setVendorName(String vendorName) { ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) - .setVendorName(vendorName); + .setVendorName(vendorName); } public void setVendorRelease(String vendorRelease) { ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) - .setVendorRelease(vendorRelease); + .setVendorRelease(vendorRelease); } public void setResourceVendorModelNumber(String resourceVendorModelNumber) { ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()). - setResourceVendorModelNumber(resourceVendorModelNumber); + setResourceVendorModelNumber(resourceVendorModelNumber); } public String getVendorName() { return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) - .getVendorName(); + .getVendorName(); } public String getVendorRelease() { return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) - .getVendorRelease(); + .getVendorRelease(); } public String getResourceVendorModelNumber() { return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) - .getResourceVendorModelNumber(); + .getResourceVendorModelNumber(); } @Override public String fetchGenericTypeToscaNameFromConfig() { String result = super.fetchGenericTypeToscaNameFromConfig(); - if (null == result) - result = ConfigurationManager.getConfigurationManager().getConfiguration().getGenericAssetNodeTypes().get(ResourceTypeEnum.VFC.getValue()); + if (null == result) { + result = ConfigurationManager.getConfigurationManager().getConfiguration().getGenericAssetNodeTypes() + .get(ResourceTypeEnum.VFC.getValue()); + } return result; } @@ -249,24 +182,23 @@ public class Resource extends Component { } @Override - public boolean shouldGenerateInputs(){ + public boolean shouldGenerateInputs() { return !(this.getResourceType().isAtomicType()); } @Override public boolean deriveFromGeneric() { - return this.shouldGenerateInputs() || (derivedFrom != null && derivedFrom.contains(fetchGenericTypeToscaNameFromConfig())); + return this.shouldGenerateInputs() || (derivedFrom != null && derivedFrom + .contains(fetchGenericTypeToscaNameFromConfig())); } public Map> groupRelationsFromCsarByInstanceName(Resource resource) { - List componentInstanceRelationsFromCsar = resource.getComponentInstancesRelations().stream().filter(r->!r.isOriginUI()).collect(Collectors.toList()); - Map> relationsByInstanceId = MapUtil.groupListBy(componentInstanceRelationsFromCsar, RequirementCapabilityRelDef::getFromNode); - return MapUtil.convertMapKeys(relationsByInstanceId, instId -> getInstanceInvariantNameFromInstanceId(resource, instId)); - } - - private String getInstanceNameFromInstanceId(Resource resource, String instId) { - Optional componentInstanceById = resource.getComponentInstanceById(instId); - return componentInstanceById.isPresent() ? componentInstanceById.get().getName() : null; + List componentInstanceRelationsFromCsar = resource.getComponentInstancesRelations() + .stream().filter(r -> !r.isOriginUI()).collect(Collectors.toList()); + Map> relationsByInstanceId = MapUtil + .groupListBy(componentInstanceRelationsFromCsar, RequirementCapabilityRelDef::getFromNode); + return MapUtil + .convertMapKeys(relationsByInstanceId, instId -> getInstanceInvariantNameFromInstanceId(resource, instId)); } private String getInstanceInvariantNameFromInstanceId(Resource resource, String instId) { diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/datamodel/NodeType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/datamodel/NodeType.java index 9c3b76d556..296e80b674 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/datamodel/NodeType.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/datamodel/NodeType.java @@ -7,9 +7,9 @@ * 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. @@ -20,12 +20,16 @@ package org.openecomp.sdc.be.model.jsonjanusgraph.datamodel; -import org.openecomp.sdc.be.datatypes.elements.*; - import java.util.List; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; -public class NodeType extends ToscaElement{ +@Getter +@Setter +public class NodeType extends ToscaElement { public NodeType() { super(ToscaElementTypeEnum.NODE_TYPE); @@ -33,39 +37,7 @@ public class NodeType extends ToscaElement{ private List derivedFrom; private List derivedList; + private Map derivedFromMapOfIdToName; private Map attributes; private Map interfaceArtifacts; - - public List getDerivedList() { - return derivedList; - } - - public void setDerivedList(List derivedList) { - this.derivedList = derivedList; - } - - public List getDerivedFrom() { - return derivedFrom; - } - - public void setDerivedFrom(List derivedFrom) { - this.derivedFrom = derivedFrom; - } - - public Map getAttributes() { - return attributes; - } - - public void setAttributes(Map attributes) { - this.attributes = attributes; - } - - public Map getInterfaceArtifacts() { - return interfaceArtifacts; - } - - public void setInterfaceArtifacts(Map interfaceArtifacts) { - this.interfaceArtifacts = interfaceArtifacts; - } - } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeTypeOperation.java index 96242e32a3..9a70e9c837 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeTypeOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeTypeOperation.java @@ -321,42 +321,48 @@ public class NodeTypeOperation extends ToscaElementOperation { return JanusGraphOperationStatus.OK; } - private JanusGraphOperationStatus setResourceDerivedFromGraph(GraphVertex componentV, NodeType toscaElement) { - List derivedFromList = new ArrayList<>(); + private JanusGraphOperationStatus setResourceDerivedFromGraph(final GraphVertex componentV, + final NodeType toscaElement) { + final List derivedFromList = new ArrayList<>(); + final Map derivedFromMapOfIdToName = new LinkedHashMap<>(); - JanusGraphOperationStatus - listFromGraphStatus = findResourcesPathRecursively(componentV, derivedFromList); + final JanusGraphOperationStatus listFromGraphStatus = findResourcesPathRecursively(componentV, derivedFromList, + derivedFromMapOfIdToName); if (JanusGraphOperationStatus.OK != listFromGraphStatus) { return listFromGraphStatus; } if (!derivedFromList.isEmpty()) { if (derivedFromList.size() > 1) { - List lastDerivedFrom = new ArrayList<>(); + final List lastDerivedFrom = new ArrayList<>(); lastDerivedFrom.add(derivedFromList.get(1)); toscaElement.setDerivedFrom(lastDerivedFrom); - toscaElement.setDerivedList(derivedFromList); } else { toscaElement.setDerivedFrom(null); - toscaElement.setDerivedList(derivedFromList); } - + toscaElement.setDerivedList(derivedFromList); + toscaElement.setDerivedFromMapOfIdToName(derivedFromMapOfIdToName); } return JanusGraphOperationStatus.OK; } - protected JanusGraphOperationStatus findResourcesPathRecursively(GraphVertex nodeTypeV, List resourcesPathList) { + private JanusGraphOperationStatus findResourcesPathRecursively(final GraphVertex nodeTypeV, + final List resourcesPathList, + final Map derivedFromMapOfIdToName) { Either parentResourceRes = janusGraphDao .getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse); resourcesPathList.add((String) nodeTypeV.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME)); + derivedFromMapOfIdToName.put(nodeTypeV.getUniqueId(), + (String) nodeTypeV.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME)); while (parentResourceRes.isLeft()) { - - GraphVertex parent = parentResourceRes.left().value(); + final GraphVertex parent = parentResourceRes.left().value(); resourcesPathList.add((String) parent.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME)); + derivedFromMapOfIdToName + .put(parent.getUniqueId(), (String) parent.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME)); parentResourceRes = janusGraphDao .getChildVertex(parent, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse); } - JanusGraphOperationStatus operationStatus = parentResourceRes.right().value(); + final JanusGraphOperationStatus operationStatus = parentResourceRes.right().value(); if (operationStatus != JanusGraphOperationStatus.NOT_FOUND) { return operationStatus; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/utils/ModelConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/utils/ModelConverter.java index 39d3548279..c16c8a98e5 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/utils/ModelConverter.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/utils/ModelConverter.java @@ -22,6 +22,18 @@ package org.openecomp.sdc.be.model.jsonjanusgraph.utils; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.BooleanUtils; @@ -34,14 +46,60 @@ import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionaryExtractor; import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition; import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.*; +import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.MapCapabilityProperty; +import org.openecomp.sdc.be.datatypes.elements.MapGroupsDataDefinition; import org.openecomp.sdc.be.datatypes.elements.MapInterfaceDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.MapListCapabilityDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.MapListRequirementDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PolicyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ProductMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.RelationshipInstDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.CreatedFrom; -import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFieldsExtractor; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; +import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFieldsExtractor; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; -import org.openecomp.sdc.be.model.*; +import org.openecomp.sdc.be.model.AdditionalInformationDefinition; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.CapabilityRequirementRelationship; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstanceInterface; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.DistributionStatusEnum; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.GroupInstance; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.MapInterfaceInstanceDataDefinition; +import org.openecomp.sdc.be.model.PolicyDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.RelationshipImpl; +import org.openecomp.sdc.be.model.RelationshipInfo; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.NodeType; import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.TopologyTemplate; import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElement; @@ -54,16 +112,6 @@ import org.openecomp.sdc.be.resources.data.ResourceMetadataData; import org.openecomp.sdc.be.resources.data.ServiceMetadataData; import org.openecomp.sdc.common.log.wrappers.Logger; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import java.util.*; -import java.util.Map.Entry; -import java.util.function.Function; -import java.util.stream.Collectors; - public class ModelConverter { public static final String CAP_PROP_DELIM = "#"; private static final Logger log = Logger.getLogger(ModelConverter.class); @@ -196,6 +244,7 @@ public class ModelConverter { NodeType nodeType = (NodeType) toscaElement; resource.setDerivedFrom(nodeType.getDerivedFrom()); resource.setDerivedList(nodeType.getDerivedList()); + resource.setDerivedFromMapOfIdToName(nodeType.getDerivedFromMapOfIdToName()); resource.setAbstract((Boolean) nodeType.getMetadataValue(JsonPresentationFields.IS_ABSTRACT)); convertAttributes(nodeType, resource); convertCapabilities(nodeType, resource); diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ResourceTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ResourceTest.java index 790ce10653..c53e4e00bb 100644 --- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/ResourceTest.java +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/ResourceTest.java @@ -20,16 +20,14 @@ package org.openecomp.sdc.be.model; -import mockit.Deencapsulation; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; import org.junit.Assert; import org.junit.Test; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; import org.openecomp.sdc.be.unittests.utils.ModelConfDependentTest; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - public class ResourceTest extends ModelConfDependentTest{ private Resource createTestSubject() { @@ -447,15 +445,4 @@ public class ResourceTest extends ModelConfDependentTest{ result = testSubject.groupRelationsFromCsarByInstanceName(resource); } - @Test - public void testGetInstanceNameFromInstanceId() throws Exception { - Resource testSubject; - Resource resource = new Resource(); - String instId = "mock"; - boolean result; - - // default test - testSubject = createTestSubject(); - Deencapsulation.invoke(testSubject, "getInstanceNameFromInstanceId", resource, instId); - } } -- 2.16.6