summaryrefslogtreecommitdiffstats
path: root/catalog-be/src/main/java
diff options
context:
space:
mode:
authoraribeiro <anderson.ribeiro@est.tech>2020-02-27 13:15:28 +0000
committerOfir Sonsino <ofir.sonsino@intl.att.com>2020-03-22 10:04:50 +0000
commit13a7f6743fbcc736c871d8168d2a7dcbda1daaba (patch)
treea7a71a96f74143b2bf0409c697a2f1d60dc158b4 /catalog-be/src/main/java
parent815674c947f970e9e57e06c8907758f88032b30a (diff)
Include derived_from types in generated csar
Issue-ID: SDC-2775 Change-Id: I7b90ff78c389e5680cacafda2065669f6baf1735 Signed-off-by: aribeiro <anderson.ribeiro@est.tech>
Diffstat (limited to 'catalog-be/src/main/java')
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java209
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java161
2 files changed, 275 insertions, 95 deletions
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<byte[], ResponseFormat> 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<ZipOutputStream, ResponseFormat> addSchemaFilesFromCassandra = addSchemaFilesFromCassandra(zip, latestSchemaFilesFromCassandra.left().value());
+ final byte[] schemaFileZip = latestSchemaFilesFromCassandra.left().value();
- if(addSchemaFilesFromCassandra.isRight()){
- return addSchemaFilesFromCassandra;
- }
+ final List<String> nodesFromPackage = findNonRootNodesFromPackage(dependencies);
+
+ //add files from retrieved SDC.zip to Definitions folder in CSAR
+ addSchemaFilesFromCassandra(zip, schemaFileZip, nodesFromPackage);
Either<CsarDefinition, ResponseFormat> collectedComponentCsarDefinition = collectComponentCsarDefinition(component);
@@ -311,8 +316,8 @@ public class CsarUtils {
for (CsarEntryGenerator generator: generators) {
log.debug("Invoking CsarEntryGenerator: {}", generator.getClass().getName());
for (Entry<String, byte[]> 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<String> findNonRootNodesFromPackage(final List<Triple<String, String, Component>> dependencies) {
+ final List<String> 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<String, Object> 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<String, Object>) 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<String, Object> updateNodeYml(final List<String> nodesFromPackage,
+ final Map<String, Object> nodesFromArtifactFile) {
+
+ if (MapUtils.isNotEmpty(nodesFromArtifactFile)) {
+ final String nodeTypeBlock = ToscaTagNamesEnum.NODE_TYPES.getElementName();
+ final Map<String, Object> nodeTypes = (Map<String, Object>) 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<String, Object> nodesYaml) throws IOException {
+ if (MapUtils.isNotEmpty(nodesYaml)) {
+ byteArrayOutputStream.write(new YamlUtil().objectToYaml(nodesYaml).getBytes());
+ }
+ }
+
private Either<ZipOutputStream, ResponseFormat> getZipOutputStreamResponseFormatEither(ZipOutputStream zip, List<Triple<String, String, Component>> dependencies, Map<String, ImmutableTriple<String, String, Component>> innerComponentsCache) throws IOException {
String fileName;
if (dependencies != null && !dependencies.isEmpty()) {
@@ -374,43 +457,57 @@ public class CsarUtils {
return null;
}
- private Either<ZipOutputStream, ResponseFormat> 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<String> 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<String> nodesFromPackage) throws IOException {
+ final Map<String, Object> nodesFromArtifactFile = readYamlZipEntry(zipInputStream);
+ final Map<String, Object> nodesYaml = updateNodeYml(nodesFromPackage, nodesFromArtifactFile);
+ updateZipEntry(byteArrayOutputStream, nodesYaml);
+ }
private void addInnerComponentsToCache(Map<String, ImmutableTriple<String, String, Component>> 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<Map<String, Map<String, String>>> 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<String, Component> componentCache, List<Map<String, Map<String, String>>> imports,
- List<Triple<String, String, Component>> dependecies, ComponentInstance ci) {
- Map<String, String> files = new HashMap<>();
- Map<String, Map<String, String>> importsListMember = new HashMap<>();
- StringBuilder keyNameBuilder;
-
- Component componentRI = componentCache.get(ci.getComponentUid());
+ private void createDependency(final Map<String, Component> componentCache,
+ final List<Map<String, Map<String, String>>> imports,
+ final List<Triple<String, String, Component>> 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<Component, StorageOperationStatus> resource = toscaOperationFacade
- .getToscaFullElement(ci.getComponentUid());
+ final Either<Component, StorageOperationStatus> 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<String, Component> componentCache,
+ final ComponentInstance componentInstance,
+ final Component fetchedComponent) {
+ componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent);
+ if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
+ final Either<Component, StorageOperationStatus> 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<Component, StorageOperationStatus> 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<Map<String, Map<String, String>>> imports,
+ final List<Triple<String, String, Component>> dependencies,
+ final Component fetchedComponent) {
+ final Set<Component> componentsList = new LinkedHashSet<>();
+ if (fetchedComponent instanceof Resource) {
+ log.debug("fetchedComponent is a resource {}",fetchedComponent);
+
+ final Optional<Map<String, String>> 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<Resource, StorageOperationStatus> 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<Map<String, String>> getDerivedFromMapOfIdToName(final Component fetchedComponent,
+ final Set<Component> componentsList) {
+ final Resource parentResource = (Resource) fetchedComponent;
+ Map<String, String> derivedFromMapOfIdToName = new HashMap<>();
+ if(CollectionUtils.isNotEmpty(parentResource.getComponentInstances())) {
+ componentsList.add(fetchedComponent);
+ for (final ComponentInstance componentInstance : parentResource.getComponentInstances()) {
+ final Either<Resource, StorageOperationStatus> resourcefetched = toscaOperationFacade
+ .getToscaElement(componentInstance.getComponentUid());
+ if (resourcefetched != null && resourcefetched.isLeft()) {
+ final Map<String, String> 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<String, ArtifactDefinition> 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<Map<String, Map<String, String>>> imports,
+ final List<Triple<String, String, Component>> dependencies,
+ final Set<Component> componentsList) {
+ componentsList.forEach(component -> {
+ final Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
+ final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE);
if (artifactDefinition != null) {
- String artifactName = artifactDefinition.getArtifactName();
+ final Map<String, String> 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<String, String> interfaceFiles = new HashMap<>();
+ keyNameBuilder.append(component.getName());
+ addImports(imports, keyNameBuilder, files);
+ dependencies
+ .add(new ImmutableTriple<String, String, Component>(artifactName, artifactDefinition.getEsId(),
+ component));
+
+ if (!ModelConverter.isAtomicComponent(component)) {
+ final Map<String, String> 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<Map<String, Map<String, String>>> imports,
+ final StringBuilder keyNameBuilder,
+ final Map<String, String> files) {
+ final String mapKey = keyNameBuilder.toString();
+ if (imports.stream().allMatch(stringMapMap -> stringMapMap.get(mapKey) == null)) {
+ final Map<String, Map<String, String>> 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;