X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=catalog-be%2Fsrc%2Fmain%2Fjava%2Forg%2Fopenecomp%2Fsdc%2Fbe%2Ftosca%2FToscaExportHandler.java;h=4d99b4de98b7aa8c4a993bce30ff0c319c9006ec;hb=438650c3a958c9176db3720204ec1ff9af94fc3a;hp=b4bf4e8d422e5c79e36760ee44386bda04f36773;hpb=5c1f5756bcb5856e2d8b35e3c6ac206f891f8695;p=sdc.git 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 b4bf4e8d42..4d99b4de98 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 @@ -17,26 +17,31 @@ * limitations under the License. * ============LICENSE_END========================================================= */ - package org.openecomp.sdc.be.tosca; import static org.apache.commons.collections.CollectionUtils.isNotEmpty; import static org.apache.commons.collections.MapUtils.isNotEmpty; import static org.openecomp.sdc.be.components.utils.PropertiesUtils.resolvePropertyValueFromInput; -import static org.openecomp.sdc.be.tosca.InterfacesOperationsConverter.addInterfaceTypeElement; import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_ATTRIBUTE; import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_INPUT; import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_PROPERTY; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; +import com.google.common.primitives.Ints; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.stream.JsonReader; import fj.data.Either; -import java.beans.IntrospectionException; + +import java.io.StringReader; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -48,38 +53,47 @@ import java.util.Optional; import java.util.Set; import java.util.function.Supplier; import java.util.stream.Collectors; + import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.StringUtils; 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.datatypes.model.AttributeDefinition; import org.onap.sdc.tosca.services.YamlUtil; import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundException; +import org.openecomp.sdc.be.config.CategoryBaseTypeConfig; +import org.openecomp.sdc.be.config.Configuration; import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; +import org.openecomp.sdc.be.data.model.ToscaImportByModel; import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunction; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; import org.openecomp.sdc.be.exception.ToscaExportException; import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.AttributeDefinition; 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.ComponentInstanceAttribute; import org.openecomp.sdc.be.model.ComponentInstanceInput; import org.openecomp.sdc.be.model.ComponentInstanceInterface; import org.openecomp.sdc.be.model.ComponentInstanceProperty; @@ -100,19 +114,25 @@ import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation; +import org.openecomp.sdc.be.model.operations.impl.ModelOperation; +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.converters.ToscaMapValueConverter; +import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType; import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder; +import org.openecomp.sdc.be.tosca.exception.ToscaConversionException; import org.openecomp.sdc.be.tosca.model.CapabilityFilter; import org.openecomp.sdc.be.tosca.model.NodeFilter; import org.openecomp.sdc.be.tosca.model.SubstitutionMapping; +import org.openecomp.sdc.be.tosca.model.ToscaAttribute; import org.openecomp.sdc.be.tosca.model.ToscaCapability; import org.openecomp.sdc.be.tosca.model.ToscaDataType; import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate; -import org.openecomp.sdc.be.tosca.model.ToscaMetadata; import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate; import org.openecomp.sdc.be.tosca.model.ToscaNodeType; import org.openecomp.sdc.be.tosca.model.ToscaPolicyTemplate; import org.openecomp.sdc.be.tosca.model.ToscaProperty; import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignment; +import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraint; import org.openecomp.sdc.be.tosca.model.ToscaRelationshipTemplate; import org.openecomp.sdc.be.tosca.model.ToscaRequirement; import org.openecomp.sdc.be.tosca.model.ToscaTemplate; @@ -121,8 +141,10 @@ import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement; import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate; import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil; import org.openecomp.sdc.be.tosca.utils.InputConverter; +import org.openecomp.sdc.be.tosca.utils.OutputConverter; +import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode; import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.externalupload.utils.ServiceUtils; +import org.openecomp.sdc.tosca.datatypes.ToscaFunctions; import org.springframework.beans.factory.annotation.Autowired; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.DumperOptions.FlowStyle; @@ -140,108 +162,137 @@ import org.yaml.snakeyaml.representer.Representer; @org.springframework.stereotype.Component("tosca-export-handler") public class ToscaExportHandler { + public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate"; private static final Logger log = Logger.getLogger(ToscaExportHandler.class); - - private ApplicationDataTypeCache dataTypeCache; - private ToscaOperationFacade toscaOperationFacade; - private CapabilityRequirementConverter capabilityRequirementConverter; - private PolicyExportParser policyExportParser; - private GroupExportParser groupExportParser; - private PropertyConvertor propertyConvertor; - private InputConverter inputConverter; - private InterfaceLifecycleOperation interfaceLifecycleOperation; - private InterfacesOperationsConverter interfacesOperationsConverter; + private static final String INVARIANT_UUID = "invariantUUID"; + private static final String TOSCA_VERSION = "tosca_simple_yaml_1_3"; + private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service."; + private static final String IMPORTS_FILE_KEY = "file"; + private static final String TOSCA_INTERFACE_NAME = "-interface.yml"; + 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 String NATIVE_ROOT = "tosca.nodes.Root"; + private static final List EXCLUDED_CATEGORY_SPECIFIC_METADATA = List + .of("Service Function", "Service Role", "Naming Policy", "Service Type"); + private static final YamlUtil yamlUtil = new YamlUtil(); + private final ApplicationDataTypeCache applicationDataTypeCache; + private final ToscaOperationFacade toscaOperationFacade; + private final CapabilityRequirementConverter capabilityRequirementConverter; + private final PolicyExportParser policyExportParser; + private final GroupExportParser groupExportParser; + private final PropertyConvertor propertyConvertor; + private final AttributeConverter attributeConverter; + private final InputConverter inputConverter; + private final OutputConverter outputConverter; + private final InterfaceLifecycleOperation interfaceLifecycleOperation; + private final InterfacesOperationsConverter interfacesOperationsConverter; + private final ModelOperation modelOperation; @Autowired - public ToscaExportHandler(ApplicationDataTypeCache dataTypeCache, ToscaOperationFacade toscaOperationFacade, - CapabilityRequirementConverter capabilityRequirementConverter, - PolicyExportParser policyExportParser, - GroupExportParser groupExportParser, PropertyConvertor propertyConvertor, - InputConverter inputConverter, - InterfaceLifecycleOperation interfaceLifecycleOperation, - InterfacesOperationsConverter interfacesOperationsConverter) { - this.dataTypeCache = dataTypeCache; + public ToscaExportHandler(final ApplicationDataTypeCache applicationDataTypeCache, + final ToscaOperationFacade toscaOperationFacade, + final CapabilityRequirementConverter capabilityRequirementConverter, + final PolicyExportParser policyExportParser, + final GroupExportParser groupExportParser, + final PropertyConvertor propertyConvertor, + final AttributeConverter attributeConverter, + final InputConverter inputConverter, + final OutputConverter outputConverter, + final InterfaceLifecycleOperation interfaceLifecycleOperation, + final InterfacesOperationsConverter interfacesOperationsConverter, + final ModelOperation modelOperation) { + this.applicationDataTypeCache = applicationDataTypeCache; this.toscaOperationFacade = toscaOperationFacade; this.capabilityRequirementConverter = capabilityRequirementConverter; this.policyExportParser = policyExportParser; this.groupExportParser = groupExportParser; this.propertyConvertor = propertyConvertor; + this.attributeConverter = attributeConverter; this.inputConverter = inputConverter; + this.outputConverter = outputConverter; this.interfaceLifecycleOperation = interfaceLifecycleOperation; this.interfacesOperationsConverter = interfacesOperationsConverter; + this.modelOperation = modelOperation; } - private static final String TOSCA_VERSION = "tosca_simple_yaml_1_3"; - private static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service."; - private static final String IMPORTS_FILE_KEY = "file"; - private static final String TOSCA_INTERFACE_NAME = "-interface.yml"; - public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate"; - 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 String NATIVE_ROOT = "tosca.nodes.Root"; - private static YamlUtil yamlUtil = new YamlUtil(); + public static String getInterfaceFilename(String artifactName) { + return artifactName.substring(0, artifactName.lastIndexOf('.')) + TOSCA_INTERFACE_NAME; + } - public ToscaExportHandler() { + private static void removeOperationImplementationForProxyNodeType(Map proxyComponentInterfaces) { + if (MapUtils.isEmpty(proxyComponentInterfaces)) { + return; + } + proxyComponentInterfaces.values().stream().map(InterfaceDataDefinition::getOperations).filter(MapUtils::isNotEmpty) + .forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null))); } public Either exportComponent(Component component) { return convertToToscaTemplate(component).left().map(this::createToscaRepresentation); } - public Either exportComponentInterface(final Component component, - final boolean isAssociatedComponent) { - final List>> defaultToscaImportConfig = getDefaultToscaImportConfig(); - if (CollectionUtils.isEmpty(defaultToscaImportConfig)) { + public Either exportDataType(DataTypeDefinition dataTypeDefinition) { + return convertDataTypeToToscaTemplate(dataTypeDefinition).left().map(this::createToscaRepresentation); + } + + public Either exportComponentInterface(final Component component, final boolean isAssociatedComponent) { + final List>> imports = new ArrayList<>(getDefaultToscaImports(component.getModel())); + if (CollectionUtils.isEmpty(imports)) { log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION); return Either.right(ToscaError.GENERAL_ERROR); } + List> dependencies = new ArrayList<>(); + if (component.getDerivedFromGenericType() != null && !component.getDerivedFromGenericType() + .startsWith("org.openecomp.resource.abstract.nodes.")) { + final Either baseType = toscaOperationFacade + .getByToscaResourceNameAndVersion(component.getDerivedFromGenericType(), component.getDerivedFromGenericVersion(), + component.getModel()); + if (baseType.isLeft() && baseType.left().value() != null) { + addDependencies(imports, dependencies, baseType.left().value()); + } else { + log.debug("Failed to fetch derived from type {}", component.getDerivedFromGenericType()); + } + } String toscaVersion = null; if (component instanceof Resource) { toscaVersion = ((Resource) component).getToscaVersion(); } ToscaTemplate toscaTemplate = new ToscaTemplate(toscaVersion != null ? toscaVersion : TOSCA_VERSION); - toscaTemplate.setImports(new ArrayList<>(defaultToscaImportConfig)); + toscaTemplate.setImports(imports); final Map nodeTypes = new HashMap<>(); - final Either toscaTemplateRes = - convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes, isAssociatedComponent); + final Either toscaTemplateRes = convertInterfaceNodeType(new HashMap<>(), component, toscaTemplate, nodeTypes, + isAssociatedComponent); if (toscaTemplateRes.isRight()) { return Either.right(toscaTemplateRes.right().value()); } - toscaTemplate = toscaTemplateRes.left().value(); + toscaTemplate.setDependencies(dependencies); ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate); return Either.left(toscaRepresentation); } - public ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) { + private ToscaRepresentation createToscaRepresentation(ToscaTemplate toscaTemplate) { CustomRepresenter representer = new CustomRepresenter(); DumperOptions options = new DumperOptions(); options.setAllowReadOnlyProperties(false); options.setPrettyFlow(true); - options.setDefaultFlowStyle(FlowStyle.FLOW); options.setCanonical(false); - representer.addClassTag(toscaTemplate.getClass(), Tag.MAP); - representer.setPropertyUtils(new UnsortedPropertyUtils()); - Yaml yaml = new Yaml(representer, options); + Yaml yaml = new Yaml(representer, options); String yamlAsString = yaml.dumpAsMap(toscaTemplate); - - StringBuilder sb = new StringBuilder(); - sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader()); - sb.append(yamlAsString); - sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter()); - - return ToscaRepresentation.make(sb.toString().getBytes(), toscaTemplate); + String sb = getConfiguration().getHeatEnvArtifactHeader() + + yamlAsString + + getConfiguration().getHeatEnvArtifactFooter(); + return ToscaRepresentation.make(sb.getBytes(), toscaTemplate); } public Either getDependencies(Component component) { ToscaTemplate toscaTemplate = new ToscaTemplate(null); - Either>, ToscaError> fillImports = fillImports(component, - toscaTemplate); + Either>, ToscaError> fillImports = fillImports(component, toscaTemplate); if (fillImports.isRight()) { return Either.right(fillImports.right().value()); } @@ -249,7 +300,7 @@ public class ToscaExportHandler { } public Either convertToToscaTemplate(final Component component) { - final List>> defaultToscaImportConfig = getDefaultToscaImportConfig(); + final List>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel()); if (CollectionUtils.isEmpty(defaultToscaImportConfig)) { log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION); return Either.right(ToscaError.GENERAL_ERROR); @@ -270,44 +321,89 @@ public class ToscaExportHandler { log.trace("convert component as topology template"); return convertToscaTemplate(component, toscaTemplate); } + } + private Either convertDataTypeToToscaTemplate(final DataTypeDefinition dataTypeDefinition) { + final ToscaTemplate toscaTemplate = new ToscaTemplate(TOSCA_VERSION); + return convertDataTypeTosca(dataTypeDefinition, toscaTemplate); } - private Either convertToscaTemplate(Component component, ToscaTemplate toscaNode) { + private Either convertDataTypeTosca(final DataTypeDefinition dataTypeDefinition, final ToscaTemplate toscaTemplate) { + final var dataTypesEither = applicationDataTypeCache.getAll(dataTypeDefinition.getModel()); + if (dataTypesEither.isRight()) { + log.debug("Failed to fetch all data types :", dataTypesEither.right().value()); + return Either.right(ToscaError.GENERAL_ERROR); + } + Map dataTypes = dataTypesEither.left().value(); + if (!dataTypeDefinition.isEmpty()) { + Map toscaDataTypeMap = new HashMap<>(); + ToscaDataType toscaDataType = new ToscaDataType(); + toscaDataType.setDerived_from(dataTypeDefinition.getDerivedFromName()); + toscaDataType.setDescription(dataTypeDefinition.getDescription()); + toscaDataType.setVersion(dataTypeDefinition.getVersion()); + if (CollectionUtils.isNotEmpty(dataTypeDefinition.getProperties())) { + toscaDataType.setProperties(dataTypeDefinition.getProperties().stream() + .collect(Collectors.toMap( + PropertyDataDefinition::getName, + s -> propertyConvertor.convertProperty(dataTypes, s, PropertyType.PROPERTY), + (toscaPropertyTobeValidated, toscaProperty) -> validateToscaProperty((List) dataTypeDefinition, + toscaPropertyTobeValidated, + toscaProperty) + ))); + } + toscaDataTypeMap.put(dataTypeDefinition.getName(), toscaDataType); + toscaTemplate.setData_types(toscaDataTypeMap); + } + return Either.left(toscaTemplate); + } + + private List>> getDefaultToscaImports(final String modelId) { + if (StringUtils.isEmpty(modelId)) { + return getDefaultToscaImportConfig(); + } + + final List allModelImports = modelOperation.findAllModelImports(modelId, true); + final List>> importList = new ArrayList<>(); + final Set addedPathList = new HashSet<>(); + for (final ToscaImportByModel toscaImportByModel : allModelImports) { + var importPath = Path.of(toscaImportByModel.getFullPath()); + if (addedPathList.contains(importPath)) { + importPath = ToscaDefaultImportHelper.addModelAsFilePrefix(importPath, toscaImportByModel.getModelId()); + } + final String fileName = FilenameUtils.getBaseName(importPath.toString()); + importList.add(Map.of(fileName, Map.of("file", importPath.toString()))); + addedPathList.add(importPath); + } + return importList; + } - Either>, ToscaError> importsRes = fillImports(component, - toscaNode); + private Either convertToscaTemplate(Component component, ToscaTemplate toscaNode) { + Either>, ToscaError> importsRes = fillImports(component, toscaNode); if (importsRes.isRight()) { return Either.right(importsRes.right().value()); } toscaNode = importsRes.left().value().left; Map componentCache = importsRes.left().value().right; - Either, ToscaError> nodeTypesMapEither = createProxyNodeTypes(componentCache, - component); + Either, ToscaError> nodeTypesMapEither = createProxyNodeTypes(componentCache, component); if (nodeTypesMapEither.isRight()) { - log.debug("Failed to fetch normative service proxy resource by tosca name, error {}", - nodeTypesMapEither.right().value()); + log.debug("Failed to fetch normative service proxy resource by tosca name, error {}", nodeTypesMapEither.right().value()); return Either.right(nodeTypesMapEither.right().value()); } Map nodeTypesMap = nodeTypesMapEither.left().value(); if (nodeTypesMap != null && !nodeTypesMap.isEmpty()) { toscaNode.setNode_types(nodeTypesMap); } - createServiceSubstitutionNodeTypes(componentCache, component, toscaNode); - Either, ToscaError> proxyInterfaceTypesEither = createProxyInterfaceTypes(component); if (proxyInterfaceTypesEither.isRight()) { - log.debug("Failed to populate service proxy local interface types in tosca, error {}", - nodeTypesMapEither.right().value()); + log.debug("Failed to populate service proxy local interface types in tosca, error {}", nodeTypesMapEither.right().value()); return Either.right(proxyInterfaceTypesEither.right().value()); } Map proxyInterfaceTypes = proxyInterfaceTypesEither.left().value(); if (MapUtils.isNotEmpty(proxyInterfaceTypes)) { toscaNode.setInterface_types(proxyInterfaceTypes); } - - Either, JanusGraphOperationStatus> dataTypesEither = dataTypeCache.getAll(); + Either, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(component.getModel()); if (dataTypesEither.isRight()) { log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value()); return Either.right(ToscaError.GENERAL_ERROR); @@ -316,98 +412,135 @@ public class ToscaExportHandler { ToscaTopolgyTemplate topologyTemplate = new ToscaTopolgyTemplate(); List inputDef = component.getInputs(); Map inputs = inputConverter.convertInputs(inputDef, dataTypes); - if (!inputs.isEmpty()) { topologyTemplate.setInputs(inputs); } - - final List componentInstances = component.getComponentInstances(); - Map> componentInstancesProperties = - component.getComponentInstancesProperties(); - Map> componentInstanceInterfaces = - component.getComponentInstancesInterfaces(); - if (CollectionUtils.isNotEmpty(componentInstances)) { + final Map outputs; + try { + outputs = outputConverter.convert(component.getOutputs(), dataTypes); + } catch (final ToscaConversionException e) { + log.error(EcompLoggerErrorCode.SCHEMA_ERROR, ToscaExportHandler.class.getName(), + "Could not parse component '{}' outputs. Component unique id '{}'.", component.getName(), component.getUniqueId(), e); + return Either.right(ToscaError.GENERAL_ERROR); + } + if (!outputs.isEmpty()) { + topologyTemplate.setOutputs(outputs); + } + if (CollectionUtils.isNotEmpty(component.getComponentInstances())) { final Either, ToscaError> nodeTemplates = - convertNodeTemplates(component, componentInstances, - componentInstancesProperties, componentInstanceInterfaces, - componentCache, dataTypes, topologyTemplate); + convertNodeTemplates(component, componentCache, dataTypes, topologyTemplate); if (nodeTemplates.isRight()) { return Either.right(nodeTemplates.right().value()); } log.debug("node templates converted"); topologyTemplate.setNode_templates(nodeTemplates.left().value()); } - final Map relationshipTemplatesMap = - new ToscaExportRelationshipTemplatesHandler() + final Map relationshipTemplatesMap = new ToscaExportRelationshipTemplatesHandler() .createFrom(topologyTemplate.getNode_templates()); if (!relationshipTemplatesMap.isEmpty()) { topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap); } - - SubstitutionMapping substitutionMapping = new SubstitutionMapping(); - convertSubstitutionMappingFilter(component, substitutionMapping); - addGroupsToTopologyTemplate(component, topologyTemplate); - try { addPoliciesToTopologyTemplate(component, topologyTemplate); } catch (SdcResourceNotFoundException e) { log.debug("Fail to add policies to topology template:", e); return Either.right(ToscaError.GENERAL_ERROR); } + try { + createSubstitutionMapping(component, componentCache).ifPresent(topologyTemplate::setSubstitution_mappings); + } catch (final ToscaExportException e) { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ToscaExportHandler.class.getName(), e.getMessage()); + return Either.right(e.getToscaError()); + } + if (!topologyTemplate.isEmpty()) { + toscaNode.setTopology_template(topologyTemplate); + } + return Either.left(toscaNode); + } - String toscaResourceName; + private Either createComponentToscaName(final Component component) { switch (component.getComponentType()) { case RESOURCE: - toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition() - .getMetadataDataDefinition()).getToscaResourceName(); - break; + final ResourceMetadataDataDefinition resourceMetadata = + (ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition(); + return Either.left(resourceMetadata.getToscaResourceName()); case SERVICE: - toscaResourceName = SERVICE_NODE_TYPE_PREFIX - + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName(); - break; + return Either.left(SERVICE_NODE_TYPE_PREFIX + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName()); default: log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType()); return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE); } - substitutionMapping.setNode_type(toscaResourceName); - Either capabilities = convertCapabilities(component, substitutionMapping, - componentCache); - if (capabilities.isRight()) { - return Either.right(capabilities.right().value()); + } + + private Optional createSubstitutionMapping(final Component component, + final Map componentCache) throws ToscaExportException { + if (component instanceof Service && !((Service) component).isSubstituteCandidate()) { + return Optional.empty(); + } + + final Either toscaResourceNameEither = createComponentToscaName(component); + if (toscaResourceNameEither.isRight()) { + throw new ToscaExportException("Could not create component TOSCA name", toscaResourceNameEither.right().value()); + } + final String toscaResourceName = toscaResourceNameEither.left().value(); + + final SubstitutionMapping substitutionMapping = new SubstitutionMapping(); + if (doNotExtendBaseType(component)) { + substitutionMapping.setNode_type(component.getDerivedFromGenericType()); + } else { + substitutionMapping.setNode_type(toscaResourceName); } - substitutionMapping = capabilities.left().value(); + convertSubstitutionMappingFilter(component).ifPresent(substitutionMapping::setSubstitution_filter); - Either requirements = capabilityRequirementConverter - .convertSubstitutionMappingRequirements(componentCache, component, substitutionMapping); + final Either, ToscaError> capabilitiesEither = convertSubstitutionMappingCapabilities(component, componentCache); + if (capabilitiesEither.isRight()) { + throw new ToscaExportException("Could not convert substitution mapping capabilities", capabilitiesEither.right().value()); + } + final Map capabilityMap = capabilitiesEither.left().value(); + if (!capabilityMap.isEmpty()) { + substitutionMapping.setCapabilities(capabilityMap); + } + final Either, ToscaError> requirements = + capabilityRequirementConverter.convertSubstitutionMappingRequirements(component, componentCache); if (requirements.isRight()) { - return Either.right(requirements.right().value()); + throw new ToscaExportException("Could not convert substitution mapping requirements", requirements.right().value()); + } + final Map requirementMap = requirements.left().value(); + if (MapUtils.isNotEmpty(requirementMap)) { + substitutionMapping.setRequirements(requirementMap); } - substitutionMapping = requirements.left().value(); + final Map propertyMappingMap = buildSubstitutionMappingPropertyMapping(component); - if (!propertyMappingMap.isEmpty()) { + if (MapUtils.isNotEmpty(propertyMappingMap)) { substitutionMapping.setProperties(propertyMappingMap); } final Map attributesMappingMap = buildSubstitutionMappingAttributesMapping(component); - if (!attributesMappingMap.isEmpty()) { + if (MapUtils.isNotEmpty(attributesMappingMap)) { substitutionMapping.setAttributes(attributesMappingMap); } - topologyTemplate.setSubstitution_mappings(substitutionMapping); - - toscaNode.setTopology_template(topologyTemplate); + return Optional.of(substitutionMapping); + } - return Either.left(toscaNode); + private boolean doNotExtendBaseType(final Component component) { + final Map serviceNodeTypesConfig = ConfigurationManager.getConfigurationManager().getConfiguration() + .getServiceBaseNodeTypes(); + List categories = component.getCategories(); + if (CollectionUtils.isNotEmpty(categories) && MapUtils.isNotEmpty(serviceNodeTypesConfig) + && serviceNodeTypesConfig.get(categories.get(0).getName()) != null) { + return serviceNodeTypesConfig.get(categories.get(0).getName()).isDoNotExtendBaseType(); + } + return false; } - private void convertSubstitutionMappingFilter(final Component component, - final SubstitutionMapping substitutionMapping) { - if(component.getSubstitutionFilter() != null - && (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() != null) { - substitutionMapping - .setSubstitution_filter(convertToSubstitutionFilterComponent(component.getSubstitutionFilter())); + private Optional convertSubstitutionMappingFilter(final Component component) { + if (component.getSubstitutionFilter() == null || (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() == null) { + return Optional.empty(); } + + return Optional.ofNullable(convertToSubstitutionFilterComponent(component.getSubstitutionFilter())); } private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) { @@ -417,134 +550,118 @@ public class ToscaExportHandler { } } - private void addPoliciesToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) - throws SdcResourceNotFoundException { + private void addPoliciesToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) throws SdcResourceNotFoundException { Map policies = policyExportParser.getPolicies(component); if (policies != null) { topologyTemplate.addPolicies(policies); } } - private Map convertMetadata(Component component) { + private Map convertMetadata(Component component) { return convertMetadata(component, false, null); } - private Map convertMetadata(Component component, boolean isInstance, - ComponentInstance componentInstance) { - Map toscaMetadata = new LinkedHashMap<>(); - toscaMetadata.put(JsonPresentationFields.INVARIANT_UUID.getPresentation(), component.getInvariantUUID()); + private Map convertMetadata(Component component, boolean isInstance, ComponentInstance componentInstance) { + Map toscaMetadata = new LinkedHashMap<>(); + toscaMetadata.put(convertMetadataKey(JsonPresentationFields.INVARIANT_UUID), component.getInvariantUUID()); toscaMetadata.put(JsonPresentationFields.UUID.getPresentation(), component.getUUID()); - toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName()); + toscaMetadata + .put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName()); toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription()); - List categories = component.getCategories(); CategoryDefinition categoryDefinition = categories.get(0); + toscaMetadata.put(JsonPresentationFields.MODEL.getPresentation(), component.getModel()); toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName()); - if (isInstance) { - toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(),component.getVersion()); + toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), component.getVersion()); toscaMetadata.put(JsonPresentationFields.CUSTOMIZATION_UUID.getPresentation(), componentInstance.getCustomizationUUID()); - if (componentInstance.getSourceModelInvariant() != null - && !componentInstance.getSourceModelInvariant().isEmpty()) { - toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(),componentInstance.getComponentVersion()); - toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(),componentInstance.getSourceModelInvariant()); - toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(),componentInstance.getSourceModelUuid()); - toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(),componentInstance.getSourceModelName()); + if (componentInstance.getSourceModelInvariant() != null && !componentInstance.getSourceModelInvariant().isEmpty()) { + toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), componentInstance.getComponentVersion()); + toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(), componentInstance.getSourceModelInvariant()); + toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(), componentInstance.getSourceModelUuid()); + toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(), componentInstance.getSourceModelName()); if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) { toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(), - componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue()); + componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue()); } else if (componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) { toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(), - componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution - .getDisplayValue()); + componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution.getDisplayValue()); } - toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(),componentInstance.getDescription()); + toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), componentInstance.getDescription()); } - } switch (component.getComponentType()) { case RESOURCE: Resource resource = (Resource) component; - - if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) { + if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy + || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) { toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), componentInstance.getOriginType().getDisplayValue()); } else { toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), resource.getResourceType().name()); } toscaMetadata.put(JsonPresentationFields.SUB_CATEGORY.getPresentation(), categoryDefinition.getSubcategories().get(0).getName()); toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR.getPresentation(), resource.getVendorName()); - toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(),resource.getVendorRelease()); - toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(),resource.getResourceVendorModelNumber()); + if (resource.getTenant() != null) { + toscaMetadata.put(JsonPresentationFields.TENANT.getPresentation(), resource.getTenant()); + } + toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(), resource.getVendorRelease()); + toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(), resource.getResourceVendorModelNumber()); + toscaMetadata.put(resource.isTopologyTemplate() ? JsonPresentationFields.TEMPLATE_VERSION.getPresentation() : JsonPresentationFields.VERSION.getPresentation(), resource.getVersion()); break; case SERVICE: Service service = (Service) component; - toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(),component.getComponentType().getValue()); - toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(),service.getServiceType()); - toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(),service.getServiceRole()); - toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(),service.getServiceFunction()); - toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(),service.getEnvironmentContext()); - toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType()); + toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), component.getComponentType().getValue()); + toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(), service.getServiceType()); + toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(), service.getServiceRole()); + toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(), service.getServiceFunction()); + toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(), service.getEnvironmentContext()); + toscaMetadata.put(JsonPresentationFields.TEMPLATE_VERSION.getPresentation(), service.getVersion()); + toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(), + service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType()); if (!isInstance) { - // DE268546 - toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(),service.isEcompGeneratedNaming().toString()); - toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(),service.isEcompGeneratedNaming().toString()); - toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(),service.getNamingPolicy()); + toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming()); + toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(), service.getNamingPolicy()); } break; default: log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType()); } - - for (final String key: component.getCategorySpecificMetadata().keySet()) { - toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key)); + for (final String key : component.getCategorySpecificMetadata().keySet()) { + if (!EXCLUDED_CATEGORY_SPECIFIC_METADATA.contains(key)) { + toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key)); + } } return toscaMetadata; } - private void resolveInstantiationTypeAndSetItToToscaMetaData(ToscaMetadata toscaMetadata, Service service) { - if (service.getInstantiationType() != null) { - toscaMetadata.setInstantiationType(service.getInstantiationType()); - } else { - toscaMetadata.setInstantiationType(StringUtils.EMPTY); + private String convertMetadataKey(JsonPresentationFields jsonPresentationField) { + if (JsonPresentationFields.INVARIANT_UUID.equals(jsonPresentationField)) { + return INVARIANT_UUID; } + return jsonPresentationField.getPresentation(); } - private Either>, ToscaError> fillImports(Component component, - ToscaTemplate toscaTemplate) { - - final List>> defaultToscaImportConfig = getDefaultToscaImportConfig(); + private Either>, ToscaError> fillImports(Component component, ToscaTemplate toscaTemplate) { + final List>> defaultToscaImportConfig = getDefaultToscaImports(component.getModel()); if (CollectionUtils.isEmpty(defaultToscaImportConfig)) { log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION); return Either.right(ToscaError.GENERAL_ERROR); } Map componentCache = new HashMap<>(); - if (!ModelConverter.isAtomicComponent(component)) { final List>> additionalImports = - toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig) - : new ArrayList<>(toscaTemplate.getImports()); - - List> dependecies = new ArrayList<>(); - + toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig) : new ArrayList<>(toscaTemplate.getImports()); + List> dependencies = new ArrayList<>(); Map toscaArtifacts = component.getToscaArtifacts(); - if (isNotEmpty(toscaArtifacts)) { - ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE); - if (artifactDefinition != null) { - Map> importsListMember = new HashMap<>(); - Map interfaceFiles = new HashMap<>(); - interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName())); - StringBuilder keyNameBuilder = new StringBuilder(); - keyNameBuilder.append(component.getComponentType().toString().toLowerCase()).append("-") - .append(component.getName()).append("-interface"); - importsListMember.put(keyNameBuilder.toString(), interfaceFiles); - additionalImports.add(importsListMember); - } + final Map> substituteTypeImportEntry = generateComponentSubstituteTypeImport(component, toscaArtifacts); + if (!substituteTypeImportEntry.isEmpty()) { + additionalImports.add(substituteTypeImportEntry); } List componentInstances = component.getComponentInstances(); if (componentInstances != null && !componentInstances.isEmpty()) { - componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependecies, ci)); + componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependencies, ci)); } - toscaTemplate.setDependencies(dependecies); + toscaTemplate.setDependencies(dependencies); toscaTemplate.setImports(additionalImports); } else { log.debug("currently imports supported for VF and service only"); @@ -552,93 +669,109 @@ public class ToscaExportHandler { return Either.left(new ImmutablePair<>(toscaTemplate, componentCache)); } + private Map> generateComponentSubstituteTypeImport(final Component component, + final Map toscaArtifacts) { + if (doNotExtendBaseType(component)) { + return Collections.emptyMap(); + } + if (component instanceof Service && !((Service) component).isSubstituteCandidate()) { + return Collections.emptyMap(); + } + if (MapUtils.isEmpty(toscaArtifacts)) { + return Collections.emptyMap(); + } + final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE); + if (artifactDefinition == null) { + return Collections.emptyMap(); + } + final var importEntryName = component.getComponentType().toString().toLowerCase() + "-" + component.getName() + "-interface"; + return Map.of(importEntryName, + Map.of(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName())) + ); + } + private List>> getDefaultToscaImportConfig() { - return ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultImports(); + return getConfiguration().getDefaultImports(); } - private void createDependency(final Map componentCache, - final List>> imports, - final List> dependencies, - final ComponentInstance componentInstance) { + 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()); + Component componentRI = componentCache.get(componentInstance.getComponentUid()); if (componentRI == null || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) { // all resource must be only once! - final Either resource = toscaOperationFacade - .getToscaFullElement(componentInstance.getComponentUid()); + final Either resource = toscaOperationFacade.getToscaFullElement(componentInstance.getComponentUid()); if ((resource.isRight()) && (log.isDebugEnabled())) { log.debug("Failed to fetch resource with id {} for instance {}", componentInstance.getComponentUid(), - componentInstance.getUniqueId()); + componentInstance.getUniqueId()); return; } final Component fetchedComponent = resource.left().value(); - setComponentCache(componentCache, componentInstance, fetchedComponent); - addDependencies(imports, dependencies, fetchedComponent); + componentRI = setComponentCache(componentCache, componentInstance, fetchedComponent); + addDependencies(imports, dependencies, componentRI); } } /** * Sets a componentCache from the given component/resource. */ - private void setComponentCache(final Map componentCache, - final ComponentInstance componentInstance, - final Component fetchedComponent) { + private Component setComponentCache(final Map componentCache, final ComponentInstance componentInstance, + final Component fetchedComponent) { componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent); - if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) { + if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy + || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) { final Either sourceService = toscaOperationFacade - .getToscaFullElement(componentInstance.getSourceModelUid()); + .getToscaFullElement(componentInstance.getSourceModelUid()); if (sourceService.isRight() && (log.isDebugEnabled())) { - log.debug("Failed to fetch source service with id {} for proxy {}", - componentInstance.getSourceModelUid(), componentInstance.getUniqueId()); + 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); + return fetchedSource; } + return fetchedComponent; } /** * Retrieves all derived_from nodes and stores it in a predictable order. */ - private void addDependencies(final List>> imports, - final List> dependencies, + 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()) { + final Optional> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent, componentsList); + if (derivedFromMapOfIdToName.isPresent() && !derivedFromMapOfIdToName.get().isEmpty()) { derivedFromMapOfIdToName.get().entrySet().forEach(entry -> { log.debug("Started entry.getValue() : {}", entry.getValue()); if (!NATIVE_ROOT.equals(entry.getValue())) { - Either resourcefetched = toscaOperationFacade - .getToscaElement(entry.getKey()); + Either resourcefetched = toscaOperationFacade.getToscaElement(entry.getKey()); if (resourcefetched != null && resourcefetched.isLeft()) { componentsList.add(resourcefetched.left().value()); } } }); + setImports(imports, dependencies, componentsList); + } else { + setImports(imports, dependencies, fetchedComponent); } - setImports(imports, dependencies, componentsList); } } /** * Returns all derived_from nodes found. */ - private Optional> getDerivedFromMapOfIdToName(final Component fetchedComponent, - final Set componentsList) { + 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()); + .getToscaElement(componentInstance.getComponentUid()); if (resourcefetched != null && resourcefetched.isLeft()) { - final Map derivedWithId = resourcefetched.left().value() - .getDerivedFromMapOfIdToName(); + final Map derivedWithId = resourcefetched.left().value().getDerivedFromMapOfIdToName(); if (MapUtils.isNotEmpty(derivedWithId)) { derivedFromMapOfIdToName.putAll(derivedWithId); } @@ -654,40 +787,38 @@ public class ToscaExportHandler { /** * Creates a resource map and adds it to the import list. */ - private void setImports(final List>> imports, - final List> dependencies, + 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) { - final Map files = new HashMap<>(); - final String artifactName = artifactDefinition.getArtifactName(); - files.put(IMPORTS_FILE_KEY, artifactName); - final StringBuilder keyNameBuilder = new StringBuilder(); - keyNameBuilder.append(component.getComponentType().toString().toLowerCase()); - keyNameBuilder.append("-"); - 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"); - addImports(imports, keyNameBuilder, interfaceFiles); - } + componentsList.forEach(component -> setImports(imports, dependencies, component)); + } + + private void setImports(final List>> imports, final List> dependencies, + final Component component) { + final Map toscaArtifacts = component.getToscaArtifacts(); + final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE); + if (artifactDefinition != null) { + final Map files = new HashMap<>(); + final String artifactName = artifactDefinition.getArtifactName(); + files.put(IMPORTS_FILE_KEY, artifactName); + final StringBuilder keyNameBuilder = new StringBuilder(); + keyNameBuilder.append(component.getComponentType().toString().toLowerCase()); + keyNameBuilder.append("-"); + 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"); + addImports(imports, keyNameBuilder, interfaceFiles); } - }); + } } /** * Adds the found resource to the import definition list. */ - private void addImports(final List>> imports, - final StringBuilder keyNameBuilder, + 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)) { @@ -697,82 +828,68 @@ public class ToscaExportHandler { } } - public static String getInterfaceFilename(String artifactName) { - return artifactName.substring(0, artifactName.lastIndexOf('.')) + ToscaExportHandler.TOSCA_INTERFACE_NAME; - } - - private Either convertNodeType(Map componentsCache, - Component component, ToscaTemplate toscaNode, + private Either convertNodeType(Map componentsCache, Component component, ToscaTemplate toscaNode, Map nodeTypes) { return convertInterfaceNodeType(componentsCache, component, toscaNode, nodeTypes, false); } - public Either convertInterfaceNodeType(Map componentsCache, - Component component, ToscaTemplate toscaNode, - Map nodeTypes, + public Either convertInterfaceNodeType(Map componentsCache, Component component, + ToscaTemplate toscaNode, Map nodeTypes, boolean isAssociatedComponent) { log.debug("start convert node type for {}", component.getUniqueId()); ToscaNodeType toscaNodeType = createNodeType(component); - - Either, StorageOperationStatus> lifecycleTypeEither = - interfaceLifecycleOperation.getAllInterfaceLifecycleTypes(); - if (lifecycleTypeEither.isRight()) { + Either, StorageOperationStatus> lifecycleTypeEither = interfaceLifecycleOperation + .getAllInterfaceLifecycleTypes(component.getModel()); + if (lifecycleTypeEither.isRight() && !StorageOperationStatus.NOT_FOUND.equals(lifecycleTypeEither.right().value())) { log.debug("Failed to fetch all interface types :", lifecycleTypeEither.right().value()); return Either.right(ToscaError.GENERAL_ERROR); } - List allGlobalInterfaceTypes = lifecycleTypeEither.left().value() - .values() - .stream() - .map(InterfaceDataDefinition::getType) - .collect(Collectors.toList()); - toscaNode.setInterface_types(addInterfaceTypeElement(component, allGlobalInterfaceTypes)); - - Either, JanusGraphOperationStatus> dataTypesEither = dataTypeCache.getAll(); + if (lifecycleTypeEither.isLeft()) { + List allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream().map(InterfaceDataDefinition::getType) + .collect(Collectors.toList()); + toscaNode.setInterface_types(interfacesOperationsConverter.addInterfaceTypeElement(component, allGlobalInterfaceTypes)); + } + final var dataTypesEither = applicationDataTypeCache.getAll(component.getModel()); if (dataTypesEither.isRight()) { log.debug("Failed to fetch all data types :", dataTypesEither.right().value()); return Either.right(ToscaError.GENERAL_ERROR); } - Map dataTypes = dataTypesEither.left().value(); - - List inputDef = component.getInputs(); - Map mergedProperties = new HashMap<>(); - interfacesOperationsConverter - .addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent); - addInputsToProperties(dataTypes, inputDef, mergedProperties); - + interfacesOperationsConverter.addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedComponent); + final var toscaAttributeMap = convertToToscaAttributes(component.getAttributes(), dataTypes); + if (!toscaAttributeMap.isEmpty()) { + toscaNodeType.setAttributes(toscaAttributeMap); + } + Map convertedProperties = new HashMap(); if (CollectionUtils.isNotEmpty(component.getProperties())) { List properties = component.getProperties(); - Map convertedProperties = properties.stream() - .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs())) - .collect(Collectors.toMap(PropertyDataDefinition::getName, - property -> propertyConvertor.convertProperty(dataTypes, property, - PropertyConvertor.PropertyType.PROPERTY))); - // merge component properties and inputs properties - mergedProperties.putAll(convertedProperties); + convertedProperties = properties.stream() + .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, component.getInputs())).collect(Collectors + .toMap(PropertyDataDefinition::getName, + property -> propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY))); } - if (MapUtils.isNotEmpty(mergedProperties)) { - toscaNodeType.setProperties(mergedProperties); + if (MapUtils.isNotEmpty(convertedProperties)) { + toscaNodeType.setProperties(convertedProperties); } - /* convert private data_types */ List privateDataTypes = component.getDataTypes(); if (CollectionUtils.isNotEmpty(privateDataTypes)) { Map toscaDataTypeMap = new HashMap<>(); for (DataTypeDefinition dataType : privateDataTypes) { log.debug("Emitting private data type: component.name={} dataType.name={}", - component.getNormalizedName(), dataType.getName()); + component.getNormalizedName(), dataType.getName()); ToscaDataType toscaDataType = new ToscaDataType(); toscaDataType.setDerived_from(dataType.getDerivedFromName()); toscaDataType.setDescription(dataType.getDescription()); toscaDataType.setVersion(dataType.getVersion()); if (CollectionUtils.isNotEmpty(dataType.getProperties())) { toscaDataType.setProperties(dataType.getProperties().stream() - .collect(Collectors.toMap( - s -> s.getName(), - s -> propertyConvertor - .convertProperty(dataTypes, s, PropertyConvertor.PropertyType.PROPERTY) - ))); + .collect(Collectors.toMap( + PropertyDataDefinition::getName, + s -> propertyConvertor.convertProperty(dataTypes, s, PropertyType.PROPERTY), + (toscaPropertyTobeValidated, toscaProperty) -> validateToscaProperty(privateDataTypes, toscaPropertyTobeValidated, + toscaProperty) + ))); } toscaDataTypeMap.put(dataType.getName(), toscaDataType); } @@ -783,13 +900,33 @@ public class ToscaExportHandler { return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes); } + private ToscaProperty validateToscaProperty(final List privateDataTypes, final ToscaProperty toscaPropertyTobeValidated, + final ToscaProperty toscaProperty) { + final Optional match = privateDataTypes.stream() + .filter(dataType -> dataType.getName().equals(toscaPropertyTobeValidated.getType())).findFirst(); + return match.isPresent() ? toscaPropertyTobeValidated : toscaProperty; + } + + private Map convertToToscaAttributes(final List attributeList, + final Map dataTypes) { + if (CollectionUtils.isEmpty(attributeList)) { + return Collections.emptyMap(); + } + final AttributeConverter converter = new AttributeConverter(dataTypes); + final Map toscaAttributeMap = new HashMap<>(); + for (final AttributeDefinition attributeDefinition : attributeList) { + toscaAttributeMap.put(attributeDefinition.getName(), converter.convert(attributeDefinition)); + } + return toscaAttributeMap; + } + private Either convertReqCapAndTypeName(Map componentsCache, Component component, ToscaTemplate toscaNode, Map nodeTypes, ToscaNodeType toscaNodeType, Map dataTypes) { Either capabilities = convertCapabilities(componentsCache, component, toscaNodeType, - dataTypes); + dataTypes); if (capabilities.isRight()) { return Either.right(capabilities.right().value()); } @@ -797,8 +934,7 @@ public class ToscaExportHandler { log.debug("Capabilities converted for {}", component.getUniqueId()); Either requirements = capabilityRequirementConverter - .convertRequirements(componentsCache, component, - toscaNodeType); + .convertRequirements(componentsCache, component, toscaNodeType); if (requirements.isRight()) { return Either.right(requirements.right().value()); } @@ -809,11 +945,11 @@ public class ToscaExportHandler { switch (component.getComponentType()) { case RESOURCE: toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition() - .getMetadataDataDefinition()).getToscaResourceName(); + .getMetadataDataDefinition()).getToscaResourceName(); break; case SERVICE: toscaResourceName = SERVICE_NODE_TYPE_PREFIX - + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName(); + + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName(); break; default: log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType()); @@ -826,59 +962,75 @@ public class ToscaExportHandler { return Either.left(toscaNode); } - protected Either, ToscaError> convertNodeTemplates( - Component component, - List componentInstances, - Map> componentInstancesProperties, - Map> componentInstanceInterfaces, - Map componentCache, Map dataTypes, - ToscaTopolgyTemplate topologyTemplate) { + private Either, ToscaError> convertNodeTemplates(final Component component, + final Map componentCache, + final Map dataTypes, + final ToscaTopolgyTemplate topologyTemplate) { + + final Map> componentInstancesProperties = component.getComponentInstancesProperties(); + final Map> componentInstancesAttributes = component.getComponentInstancesAttributes(); + final Map> componentInstancesInputs = component.getComponentInstancesInputs(); + final Map> componentInstanceInterfaces = component.getComponentInstancesInterfaces(); + final List componentInstancesRelations = component.getComponentInstancesRelations(); Either, ToscaError> convertNodeTemplatesRes = null; - log.debug("start convert topology template for {} for type {}", component.getUniqueId(), - component.getComponentType()); - Map nodeTemplates = new HashMap<>(); - Map> componentInstancesInputs = component.getComponentInstancesInputs(); + log.debug("start convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType()); + final Map nodeTemplates = new HashMap<>(); Map groupsMap = null; - for (ComponentInstance componentInstance : componentInstances) { + for (final ComponentInstance componentInstance : component.getComponentInstances()) { ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate(); if (MapUtils.isNotEmpty(componentInstance.getToscaArtifacts())) { nodeTemplate.setArtifacts(convertToNodeTemplateArtifacts(componentInstance.getToscaArtifacts())); } + if (componentInstance.getMinOccurrences() != null && componentInstance.getMaxOccurrences() != null) { + List occur = new ArrayList<>(); + occur.add(parseToIntIfPossible(componentInstance.getMinOccurrences())); + occur.add(parseToIntIfPossible(componentInstance.getMaxOccurrences())); + nodeTemplate.setOccurrences(occur); + } + if (componentInstance.getInstanceCount() != null) { + ObjectMapper objectMapper = new ObjectMapper(); + Object obj = convertToToscaObject(componentInstance.getInstanceCount()); + if (obj != null) { + Map map = objectMapper.convertValue(obj, Map.class); + nodeTemplate.setInstance_count(map); + } + } nodeTemplate.setType(componentInstance.getToscaComponentName()); nodeTemplate.setDirectives(componentInstance.getDirectives()); - nodeTemplate.setNode_filter(convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter())); - - Either originComponentRes = capabilityRequirementConverter - .getOriginComponent(componentCache, componentInstance); + NodeFilter nodeFilter = convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter()); + if (nodeFilter != null && nodeFilter.hasData()) { + nodeTemplate.setNode_filter(nodeFilter); + } + final Either originComponentRes = capabilityRequirementConverter + .getOriginComponent(componentCache, componentInstance); if (originComponentRes.isRight()) { convertNodeTemplatesRes = Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR); break; } - Either requirements = convertComponentInstanceRequirements(component, - componentInstance, component.getComponentInstancesRelations(), nodeTemplate, - originComponentRes.left().value(), componentCache); + final Either requirements = convertComponentInstanceRequirements(component, componentInstance, + componentInstancesRelations, nodeTemplate, originComponentRes.left().value(), componentCache); if (requirements.isRight()) { convertNodeTemplatesRes = Either.right(requirements.right().value()); break; } - String instanceUniqueId = componentInstance.getUniqueId(); + final String instanceUniqueId = componentInstance.getUniqueId(); log.debug("Component instance Requirements converted for instance {}", instanceUniqueId); nodeTemplate = requirements.left().value(); - Component originalComponent = componentCache.get(componentInstance.getActualComponentUid()); + final Component originalComponent = componentCache.get(componentInstance.getActualComponentUid()); if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) { - Component componentOfProxy = componentCache.get(componentInstance.getComponentUid()); + final Component componentOfProxy = componentCache.get(componentInstance.getComponentUid()); nodeTemplate.setMetadata(convertMetadata(componentOfProxy, true, componentInstance)); } else { nodeTemplate.setMetadata(convertMetadata(originalComponent, true, componentInstance)); } - Either capabilities = capabilityRequirementConverter - .convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate); + final Either capabilities = + capabilityRequirementConverter.convertComponentInstanceCapabilities(componentInstance, dataTypes, nodeTemplate); if (capabilities.isRight()) { convertNodeTemplatesRes = Either.right(capabilities.right().value()); break; @@ -886,50 +1038,47 @@ public class ToscaExportHandler { log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId); nodeTemplate = capabilities.left().value(); - Map props = new HashMap<>(); + final Map props = new HashMap<>(); + final Map attribs = new HashMap<>(); if (originalComponent.getComponentType() == ComponentTypeEnum.RESOURCE) { // Adds the properties of parent component to map addPropertiesOfParentComponent(dataTypes, originalComponent, props); + addAttributesOfParentComponent(originalComponent, attribs); } if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) { - addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId, - props); + addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes, instanceUniqueId, props); + } + if (null != componentInstancesAttributes && componentInstancesAttributes.containsKey(instanceUniqueId)) { + addAttributesOfComponentInstance(componentInstancesAttributes, instanceUniqueId, attribs); } - if (componentInstancesInputs != null && componentInstancesInputs.containsKey(instanceUniqueId) - && !isComponentOfTypeServiceProxy(componentInstance)) { + if (componentInstancesInputs != null + && componentInstancesInputs.containsKey(instanceUniqueId) + && !isComponentOfTypeServiceProxy(componentInstance)) { //For service proxy the inputs are already handled under instance properties above - addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, - props); + addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props); } //M3[00001] - NODE TEMPLATE INTERFACES - START - handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate, - instanceUniqueId, component); + handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate, instanceUniqueId, component); //M3[00001] - NODE TEMPLATE INTERFACES - END - if (props != null && !props.isEmpty()) { + if (MapUtils.isNotEmpty(props)) { nodeTemplate.setProperties(props); } + if (MapUtils.isNotEmpty(attribs)) { + nodeTemplate.setAttributes(attribs); + } - List groupInstances = componentInstance.getGroupInstances(); - if (groupInstances != null) { + final List groupInstances = componentInstance.getGroupInstances(); + if (CollectionUtils.isNotEmpty(groupInstances)) { if (groupsMap == null) { groupsMap = new HashMap<>(); } - for (GroupInstance groupInst : groupInstances) { - boolean addToTosca = true; - - List artifacts = groupInst.getArtifacts(); - if (artifacts == null || artifacts.isEmpty()) { - addToTosca = false; - } - - if (addToTosca) { - ToscaGroupTemplate toscaGroup = groupExportParser - .getToscaGroupTemplate(groupInst, componentInstance.getInvariantName()); - groupsMap.put(groupInst.getName(), toscaGroup); + for (final GroupInstance groupInst : groupInstances) { + if (CollectionUtils.isNotEmpty(groupInst.getArtifacts())) { + groupsMap.put(groupInst.getName(), groupExportParser.getToscaGroupTemplate(groupInst, componentInstance.getInvariantName())); } } } @@ -941,44 +1090,60 @@ public class ToscaExportHandler { topologyTemplate.addGroups(groupsMap); } if (component.getComponentType() == ComponentTypeEnum.SERVICE && isNotEmpty( - ((Service) component).getForwardingPaths())) { - log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(), - component.getName()); + ((Service) component).getForwardingPaths())) { + log.debug("Starting converting paths for component {}, name {}", component.getUniqueId(), component.getName()); ForwardingPathToscaUtil - .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache, - toscaOperationFacade); - log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(), - component.getName()); + .addForwardingPaths((Service) component, nodeTemplates, capabilityRequirementConverter, componentCache, toscaOperationFacade); + log.debug("Finished converting paths for component {}, name {}", component.getUniqueId(), component.getName()); } if (convertNodeTemplatesRes == null) { convertNodeTemplatesRes = Either.left(nodeTemplates); } - log.debug("finish convert topology template for {} for type {}", component.getUniqueId(), - component.getComponentType()); + log.debug("finish convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType()); return convertNodeTemplatesRes; } - private void handleInstanceInterfaces( - Map> componentInstanceInterfaces, - ComponentInstance componentInstance, Map dataTypes, ToscaNodeTemplate nodeTemplate, - String instanceUniqueId, - Component parentComponent) { + private Object convertToToscaObject(String value) { + try { + ToscaMapValueConverter mapConverterInst = ToscaMapValueConverter.getInstance(); + StringReader reader = new StringReader(value); + JsonReader jsonReader = new JsonReader(reader); + jsonReader.setLenient(true); + JsonElement jsonElement = JsonParser.parseReader(jsonReader); + if (jsonElement.isJsonObject()) { + JsonObject jsonObj = jsonElement.getAsJsonObject(); + if (jsonObj.entrySet().size() == 1 && jsonObj.has(ToscaFunctions.GET_INPUT.getFunctionName())) { + return mapConverterInst.handleComplexJsonValue(jsonElement); + } + } + return null; + } catch (Exception e) { + log.debug("convertToToscaValue failed to parse json value :", e); + return null; + } + } + + private Object parseToIntIfPossible(final String value) { + final Integer intValue = Ints.tryParse(value); + return intValue == null ? value : intValue; + } + + private void handleInstanceInterfaces(Map> componentInstanceInterfaces, + ComponentInstance componentInstance, Map dataTypes, + ToscaNodeTemplate nodeTemplate, String instanceUniqueId, Component parentComponent) { - if (MapUtils.isEmpty(componentInstanceInterfaces) - || !componentInstanceInterfaces.containsKey(instanceUniqueId)) { + if (MapUtils.isEmpty(componentInstanceInterfaces) || !componentInstanceInterfaces.containsKey(instanceUniqueId)) { nodeTemplate.setInterfaces(null); return; } - final List currServiceInterfaces = - componentInstanceInterfaces.get(instanceUniqueId); + final List currServiceInterfaces = componentInstanceInterfaces.get(instanceUniqueId); final Map tmpInterfaces = new HashMap<>(); - currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface - .getUniqueId(), instInterface)); + currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface.getUniqueId(), instInterface)); final Map interfaceMap = interfacesOperationsConverter - .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance), isComponentOfTypeServiceProxy(componentInstance)); + .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance)); interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap); nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap); @@ -986,34 +1151,7 @@ public class ToscaExportHandler { private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) { return Objects.nonNull(componentInstance.getOriginType()) - && componentInstance.getOriginType().getValue().equals("Service Proxy"); - } - - //M3[00001] - NODE TEMPLATE INTERFACES - START - private Map getComponentInstanceInterfaceInstances( - Map> componentInstancesInterfaces, - ComponentInstance componentInstance, - String instanceUniqueId) { - if (MapUtils.isEmpty(componentInstancesInterfaces)) { - return null; - } - - List componentInstanceInterfaces = - componentInstancesInterfaces.get(instanceUniqueId); - - if (CollectionUtils.isEmpty(componentInstanceInterfaces)) { - return null; - } - - Map interfaces = new HashMap<>(); - for (ComponentInstanceInterface componentInstanceInterface : componentInstanceInterfaces) { - interfaces.put(componentInstanceInterface.getInterfaceId(), - removeOperationsKeyFromInterface(componentInstanceInterface.getInterfaceInstanceDataDefinition())); - } - - componentInstance.setInterfaces(interfaces); - - return interfaces; + && componentInstance.getOriginType().getValue().equals("Service Proxy"); } private void addComponentInstanceInputs(Map dataTypes, @@ -1023,24 +1161,32 @@ public class ToscaExportHandler { List instanceInputsList = componentInstancesInputs.get(instanceUniqueId); if (instanceInputsList != null) { instanceInputsList.forEach(input -> { - - Supplier supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue()) - ? input.getValue() : input.getDefaultValue(); + Supplier supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue()) ? input.getValue() + : input.getDefaultValue(); propertyConvertor.convertAndAddValue(dataTypes, props, input, supplier); }); } } - private void addPropertiesOfComponentInstance( - Map> componentInstancesProperties, - Map dataTypes, String instanceUniqueId, - Map props) { + private void addPropertiesOfComponentInstance(final Map> componentInstancesProperties, + final Map dataTypes, + final String instanceUniqueId, + final Map props) { if (isNotEmpty(componentInstancesProperties)) { componentInstancesProperties.get(instanceUniqueId) - // Converts and adds each value to property map - .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, - prop::getValue)); + // Converts and adds each value to property map + .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getValue)); + } + } + + private void addAttributesOfComponentInstance(final Map> componentInstancesAttributes, + final String instanceUniqueId, + final Map attribs) { + + if (isNotEmpty(componentInstancesAttributes) && componentInstancesAttributes.containsKey(instanceUniqueId)) { + componentInstancesAttributes.get(instanceUniqueId) + .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition)); } } @@ -1050,11 +1196,22 @@ public class ToscaExportHandler { List componentProperties = componentOfInstance.getProperties(); if (isNotEmpty(componentProperties)) { componentProperties.stream() - // Filters out properties with empty default values - .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue())) - // Converts and adds each value to property map - .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, - prop::getDefaultValue)); + // Filters out properties with empty default values + .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue())) + // Converts and adds each value to property map + .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop, prop::getDefaultValue)); + } + } + + private void addAttributesOfParentComponent(final Component componentOfInstance, final Map attribs) { + + final List componentAttributes = componentOfInstance.getAttributes(); + if (isNotEmpty(componentAttributes)) { + componentAttributes.stream() + // Filters out Attributes with empty default values + .filter(attrib -> StringUtils.isNotEmpty(attrib.getDefaultValue())) + // Converts and adds each value to attribute map + .forEach(attributeDefinition -> attributeConverter.convertAndAddValue(attribs, attributeDefinition)); } } @@ -1067,34 +1224,12 @@ public class ToscaExportHandler { toscaNodeType.setDescription(component.getDescription()); } else { String derivedFrom = null != component.getDerivedFromGenericType() ? component.getDerivedFromGenericType() - : NATIVE_ROOT; + : NATIVE_ROOT; toscaNodeType.setDerived_from(derivedFrom); } - if (component instanceof Resource) { - final List attributes = ((Resource) component).getAttributes(); - if (CollectionUtils.isNotEmpty(attributes)) { - final Map attributeDataDefinitionMap = new HashMap<>(); - attributes.forEach(attributeDataDefinition -> - buildAttributeData(attributeDataDefinition, attributeDataDefinitionMap)); - - toscaNodeType.setAttributes(attributeDataDefinitionMap); - } - } return toscaNodeType; } - private void buildAttributeData(final AttributeDataDefinition originalAttributeDataDefinition, - final Map attributeDataDefinitionMap) { - - attributeDataDefinitionMap.put(originalAttributeDataDefinition.getName(), - new ObjectMapper().convertValue(new AttributeDefinition( - originalAttributeDataDefinition.getType(), - originalAttributeDataDefinition.getDescription(), - originalAttributeDataDefinition.get_default(), - originalAttributeDataDefinition.getStatus(), - originalAttributeDataDefinition.getEntry_schema()), Object.class)); - } - private Either, ToscaError> createProxyInterfaceTypes(Component container) { Map proxyInterfaceTypes = new HashMap<>(); @@ -1105,8 +1240,8 @@ public class ToscaExportHandler { } Map serviceProxyInstanceList = new HashMap<>(); componentInstances.stream() - .filter(this::isComponentOfTypeServiceProxy) - .forEach(inst -> serviceProxyInstanceList.put(inst.getToscaComponentName(), inst)); + .filter(this::isComponentOfTypeServiceProxy) + .forEach(inst -> serviceProxyInstanceList.put(inst.getToscaComponentName(), inst)); if (MapUtils.isEmpty(serviceProxyInstanceList)) { return res; } @@ -1116,28 +1251,28 @@ public class ToscaExportHandler { componentParametersView.disableAll(); componentParametersView.setIgnoreInterfaces(false); Either service = toscaOperationFacade - .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView); + .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView); if (service.isRight()) { log.debug("Failed to fetch original service component with id {} for instance {}", - entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName()); + entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName()); return Either.right(ToscaError.GENERAL_ERROR); } else { serviceComponent = service.left().value(); } Either, StorageOperationStatus> lifecycleTypeEither = - interfaceLifecycleOperation.getAllInterfaceLifecycleTypes(); + interfaceLifecycleOperation.getAllInterfaceLifecycleTypes(serviceComponent.getModel()); if (lifecycleTypeEither.isRight()) { log.debug("Failed to retrieve global interface types :", lifecycleTypeEither.right().value()); return Either.right(ToscaError.GENERAL_ERROR); } List allGlobalInterfaceTypes = lifecycleTypeEither.left().value().values().stream() - .map(InterfaceDataDefinition::getType) - .collect(Collectors.toList()); + .map(InterfaceDataDefinition::getType) + .collect(Collectors.toList()); //Add interface types for local interfaces in the original service component for proxy - Map localInterfaceTypes = addInterfaceTypeElement(serviceComponent, - allGlobalInterfaceTypes); + Map localInterfaceTypes = interfacesOperationsConverter.addInterfaceTypeElement(serviceComponent, + allGlobalInterfaceTypes); if (MapUtils.isNotEmpty(localInterfaceTypes)) { proxyInterfaceTypes.putAll(localInterfaceTypes); } @@ -1159,8 +1294,8 @@ public class ToscaExportHandler { } Map serviceProxyInstanceList = new HashMap<>(); List proxyInst = componentInstances.stream() - .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name())) - .collect(Collectors.toList()); + .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceProxy.name())) + .collect(Collectors.toList()); if (proxyInst != null && !proxyInst.isEmpty()) { for (ComponentInstance inst : proxyInst) { serviceProxyInstanceList.put(inst.getToscaComponentName(), inst); @@ -1171,10 +1306,10 @@ public class ToscaExportHandler { return res; } Either serviceProxyOrigin = toscaOperationFacade - .getLatestByName("serviceProxy"); + .getLatestByName("serviceProxy", null); if (serviceProxyOrigin.isRight()) { log.debug("Failed to fetch normative service proxy resource by tosca name, error {}", - serviceProxyOrigin.right().value()); + serviceProxyOrigin.right().value()); return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE); } Component origComponent = serviceProxyOrigin.left().value(); @@ -1189,16 +1324,16 @@ public class ToscaExportHandler { componentParametersView.setIgnoreInterfaces(false); componentParametersView.setIgnoreRequirements(false); Either service = toscaOperationFacade - .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView); + .getToscaElement(entryProxy.getValue().getSourceModelUid(), componentParametersView); if (service.isRight()) { log.debug("Failed to fetch resource with id {} for instance {}", - entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName()); + entryProxy.getValue().getSourceModelUid(), entryProxy.getValue().getName()); } else { serviceComponent = service.left().value(); } ToscaNodeType toscaNodeType = createProxyNodeType(componentCache, origComponent, serviceComponent, - entryProxy.getValue()); + entryProxy.getValue()); nodeTypesMap.put(entryProxy.getKey(), toscaNodeType); } @@ -1206,19 +1341,21 @@ public class ToscaExportHandler { } private void createServiceSubstitutionNodeTypes(final Map componentCache, - final Component container, final ToscaTemplate toscaNode) { + final Component container, final ToscaTemplate toscaNode) { final List componentInstances = container.getComponentInstances(); if (CollectionUtils.isEmpty(componentInstances)) { return; } final List serviceSubstitutionInstanceList = componentInstances.stream() - .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceSubstitution.name())) - .collect(Collectors.toList()); + .filter(p -> p.getOriginType().name().equals(OriginTypeEnum.ServiceSubstitution.name())) + .collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(serviceSubstitutionInstanceList)) { for (ComponentInstance inst : serviceSubstitutionInstanceList) { - final Map nodeTypes = toscaNode.getNode_types() == null ? new HashMap<>() : toscaNode.getNode_types(); - convertInterfaceNodeType(new HashMap<>(), componentCache.get(inst.getSourceModelUid()), toscaNode, nodeTypes, true); + final Map nodeTypes = + toscaNode.getNode_types() == null ? new HashMap<>() : toscaNode.getNode_types(); + convertInterfaceNodeType(new HashMap<>(), componentCache.get(inst.getSourceModelUid()), toscaNode, + nodeTypes, true); } } } @@ -1229,19 +1366,20 @@ public class ToscaExportHandler { String derivedFrom = ((Resource) origComponent).getToscaResourceName(); toscaNodeType.setDerived_from(derivedFrom); - Either, JanusGraphOperationStatus> dataTypesEither = dataTypeCache.getAll(); + Either, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll( + origComponent.getModel()); if (dataTypesEither.isRight()) { log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value()); } Map dataTypes = dataTypesEither.left().value(); Map capabilities = this.capabilityRequirementConverter - .convertProxyCapabilities(componentCache, componentInstance, dataTypes); + .convertProxyCapabilities(componentCache, componentInstance, dataTypes); if (MapUtils.isNotEmpty(capabilities)) { toscaNodeType.setCapabilities(capabilities); } List> proxyNodeTypeRequirements = this.capabilityRequirementConverter - .convertProxyRequirements(componentCache, componentInstance); + .convertProxyRequirements(componentCache, componentInstance); if (CollectionUtils.isNotEmpty(proxyNodeTypeRequirements)) { toscaNodeType.setRequirements(proxyNodeTypeRequirements); } @@ -1255,8 +1393,7 @@ public class ToscaExportHandler { interfaceMap = proxyInterfaces.get(); } } else { - interfaceMap = interfacesOperationsConverter - .getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, false, false); + interfaceMap = interfacesOperationsConverter.getInterfacesMapFromComponentInstance(proxyComponent, componentInstance, dataTypes, false); } interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap); @@ -1272,19 +1409,18 @@ public class ToscaExportHandler { Component originComponent, Map componentCache) { - final List> toscaRequirements; final List requirementDefinitionList = filterRequirements(componentInstance, - relations); + relations); if (isNotEmpty(requirementDefinitionList)) { try { - toscaRequirements = buildRequirements(component, componentInstance, - requirementDefinitionList, originComponent, componentCache); - if (!toscaRequirements.isEmpty()) { + final List> toscaRequirements = buildRequirements(component, componentInstance, + requirementDefinitionList, originComponent, componentCache); + if (CollectionUtils.isNotEmpty(toscaRequirements)) { nodeTypeTemplate.setRequirements(toscaRequirements); } } catch (final Exception e) { log.debug("Failed to convert component instance requirements for the component instance {}. ", - componentInstance.getName(), e); + componentInstance.getName(), e); return Either.right(ToscaError.NODE_TYPE_REQUIREMENT_ERROR); } } @@ -1297,14 +1433,15 @@ public class ToscaExportHandler { final List filteredRelations, final Component originComponent, final Map componentCache) - throws ToscaExportException { + throws ToscaExportException { final List> toscaRequirements = new ArrayList<>(); for (RequirementCapabilityRelDef relationshipDefinition : filteredRelations) { final Map toscaTemplateRequirementMap = - buildRequirement(componentInstance, originComponent, component.getComponentInstances(), - relationshipDefinition, componentCache); - toscaRequirements.add(toscaTemplateRequirementMap); + buildRequirement(componentInstance, originComponent, component.getComponentInstances(), relationshipDefinition, componentCache); + if (MapUtils.isNotEmpty(toscaTemplateRequirementMap)) { + toscaRequirements.add(toscaTemplateRequirementMap); + } } return toscaRequirements; @@ -1313,7 +1450,7 @@ public class ToscaExportHandler { private List filterRequirements(ComponentInstance componentInstance, List relations) { return relations.stream() - .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList()); + .filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).collect(Collectors.toList()); } private Map buildRequirement(final ComponentInstance fromInstance, @@ -1321,28 +1458,27 @@ public class ToscaExportHandler { final List instancesList, final RequirementCapabilityRelDef relationshipDefinition, final Map componentCache) - throws ToscaExportException { + throws ToscaExportException { final Map> reqMap = fromOriginComponent.getRequirements(); - final CapabilityRequirementRelationship capabilityRequirementRelationship = relationshipDefinition - .getRelationships().get(0); + if (MapUtils.isEmpty(reqMap)) { + return new HashMap<>(); + } + final CapabilityRequirementRelationship capabilityRequirementRelationship = relationshipDefinition.getRelationships().get(0); final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation(); - final ComponentInstance toInstance = instancesList.stream() - .filter(i -> relationshipDefinition.getToNode().equals(i.getUniqueId())) - .findFirst().orElse(null); + final ComponentInstance toInstance = instancesList.stream().filter(i -> relationshipDefinition.getToNode().equals(i.getUniqueId())) + .findFirst().orElse(null); if (toInstance == null) { final String errorMsg = String - .format("Failed to find a relation from the node %s to the node %s", fromInstance.getName(), - relationshipDefinition.getToNode()); + .format("Failed to find a relation from the node %s to the node %s", fromInstance.getName(), + relationshipDefinition.getToNode()); log.debug(errorMsg); throw new ToscaExportException(errorMsg); } - final Optional reqOpt = - findRequirement(fromOriginComponent, reqMap, relationshipInfo, fromInstance.getUniqueId()); + final Optional reqOpt = findRequirement(fromOriginComponent, reqMap, relationshipInfo, fromInstance.getUniqueId()); if (reqOpt.isEmpty()) { - final String errorMsg = String - .format("Failed to find a requirement with uniqueId %s on a component with uniqueId %s", + final String errorMsg = String.format("Failed to find a requirement with uniqueId %s on a component with uniqueId %s", relationshipInfo.getRequirementUid(), fromOriginComponent.getUniqueId()); log.debug(errorMsg); throw new ToscaExportException(errorMsg); @@ -1352,46 +1488,44 @@ public class ToscaExportHandler { filter.setIgnoreCapabilities(false); filter.setIgnoreGroups(false); final Either getOriginRes = - toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter); + toscaOperationFacade.getToscaElement(toInstance.getActualComponentUid(), filter); if (getOriginRes.isRight()) { final String errorMsg = String.format( - "Failed to build substituted name for the requirement %s. " - + "Failed to get an origin component with uniqueId %s", - reqOpt.get().getName(), toInstance.getActualComponentUid()); + "Failed to build substituted name for the requirement %s. Failed to get an origin component with uniqueId %s", + reqOpt.get().getName(), toInstance.getActualComponentUid()); log.debug(errorMsg); throw new ToscaExportException(errorMsg); } final Component toOriginComponent = getOriginRes.left().value(); Optional capOpt = toOriginComponent.getCapabilities().get(reqOpt.get().getCapability()).stream() - .filter(c -> isCapabilityBelongToRelation(relationshipInfo, c)).findFirst(); + .filter(c -> isCapabilityBelongToRelation(relationshipInfo, c)).findFirst(); if (capOpt.isEmpty()) { capOpt = findCapability(relationshipInfo, toOriginComponent, fromOriginComponent, reqOpt.get()); if (capOpt.isEmpty()) { - final String errorMsg = String - .format("Failed to find a capability with name %s on a component with uniqueId %s", + final String errorMsg = String.format("Failed to find a capability with name %s on a component with uniqueId %s", relationshipInfo.getCapability(), fromOriginComponent.getUniqueId()); log.debug(errorMsg); throw new ToscaExportException(errorMsg); } } return buildRequirement(fromOriginComponent, toOriginComponent, capOpt.get(), reqOpt.get(), - capabilityRequirementRelationship, toInstance, componentCache); + capabilityRequirementRelationship, toInstance, componentCache); } private boolean isCapabilityBelongToRelation(RelationshipInfo reqAndRelationshipPair, CapabilityDefinition capability) { return capability.getName().equals(reqAndRelationshipPair.getCapability()) && (capability.getOwnerId() != null - && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId())); + && capability.getOwnerId().equals(reqAndRelationshipPair.getCapabilityOwnerId())); } private Optional findCapability(RelationshipInfo reqAndRelationshipPair, Component toOriginComponent, Component fromOriginComponent, RequirementDefinition requirement) { Optional cap = toOriginComponent.getCapabilities().get(requirement.getCapability()) - .stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst(); - if (!cap.isPresent()) { + .stream().filter(c -> c.getType().equals(requirement.getCapability())).findFirst(); + if (cap.isEmpty()) { log.debug("Failed to find a capability with name {} on a component with uniqueId {}", - reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId()); + reqAndRelationshipPair.getCapability(), fromOriginComponent.getUniqueId()); } return cap; } @@ -1403,31 +1537,31 @@ public class ToscaExportHandler { final CapabilityRequirementRelationship capabilityRequirementRelationship, final ComponentInstance toInstance, final Map componentCache) - throws ToscaExportException { + throws ToscaExportException { List reducedPath = capability.getPath(); if (capability.getOwnerId() != null) { reducedPath = capabilityRequirementConverter - .getReducedPathByOwner(capability.getPath(), capability.getOwnerId()); + .getReducedPathByOwner(capability.getPath(), capability.getOwnerId()); } final RelationshipInfo relationshipInfo = capabilityRequirementRelationship.getRelation(); final Either capabilityNameEither = capabilityRequirementConverter.buildSubstitutedName(componentCache, - toOriginComponent, reducedPath, relationshipInfo.getCapability(), capability.getPreviousName()); + toOriginComponent, reducedPath, relationshipInfo.getCapability(), capability.getPreviousName(), capability.getExternalName()); if (capabilityNameEither.isRight()) { final String errorMsg = String.format( - "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s", - capabilityRequirementRelationship.getCapability(), toOriginComponent.getUniqueId()); + "Failed to build a substituted capability name for the capability with name %s on a component with uniqueId %s", + capabilityRequirementRelationship.getCapability(), toOriginComponent.getUniqueId()); log.debug( - errorMsg); + errorMsg); throw new ToscaExportException(errorMsg); } final Either requirementNameEither = capabilityRequirementConverter - .buildSubstitutedName(componentCache, fromOriginComponent, - requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName()); + .buildSubstitutedName(componentCache, fromOriginComponent, + requirement.getPath(), relationshipInfo.getRequirement(), requirement.getPreviousName(), requirement.getExternalName()); if (requirementNameEither.isRight()) { final String errorMsg = String.format("Failed to build a substituted requirement name for the requirement " - + "with name %s on a component with uniqueId %s", - capabilityRequirementRelationship.getRequirement(), fromOriginComponent.getUniqueId()); + + "with name %s on a component with uniqueId %s", + capabilityRequirementRelationship.getRequirement(), fromOriginComponent.getUniqueId()); log.debug(errorMsg); throw new ToscaExportException(errorMsg); } @@ -1446,10 +1580,9 @@ public class ToscaExportHandler { Map> reqMap, RelationshipInfo reqAndRelationshipPair, String fromInstanceId) { - for (List reqList : reqMap.values()) { - Optional reqOpt = reqList.stream().filter( - r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId)) - .findFirst(); + for (final List reqList : reqMap.values()) { + final Optional reqOpt = reqList.stream() + .filter(r -> isRequirementBelongToRelation(fromOriginComponent, reqAndRelationshipPair, r, fromInstanceId)).findFirst(); if (reqOpt.isPresent()) { return reqOpt; } @@ -1458,70 +1591,63 @@ public class ToscaExportHandler { } /** - * Allows detecting the requirement belonging to the received relationship The detection logic is: A requirement - * belongs to a relationship IF 1.The name of the requirement equals to the "requirement" field of the relation; AND - * 2. In case of a non-atomic resource, OwnerId of the requirement equals to requirementOwnerId of the relation OR - * uniqueId of toInstance equals to capabilityOwnerId of the relation + * Allows detecting the requirement belonging to the received relationship The detection logic is: A requirement belongs to a relationship IF + * 1.The name of the requirement equals to the "requirement" field of the relation; AND 2. In case of a non-atomic resource, OwnerId of the + * requirement equals to requirementOwnerId of the relation OR uniqueId of toInstance equals to capabilityOwnerId of the relation */ private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair, RequirementDefinition requirement, String fromInstanceId) { + if (originComponent.isService() && requirement.getUniqueId().equals(reqAndRelationshipPair.getRequirementUid())) { + return true; + } if (!StringUtils.equals(requirement.getName(), reqAndRelationshipPair.getRequirement())) { - log.debug("Failed to find a requirement with name {} and reqAndRelationshipPair {}", - requirement.getName(), reqAndRelationshipPair.getRequirement()); + log.debug("Failed to find a requirement with name {} and reqAndRelationshipPair {}", requirement.getName(), + reqAndRelationshipPair.getRequirement()); return false; } - return ModelConverter.isAtomicComponent(originComponent) || - isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId, originComponent); + return ModelConverter.isAtomicComponent(originComponent) || isRequirementBelongToOwner(reqAndRelationshipPair, requirement, fromInstanceId, + originComponent); } - private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair, - RequirementDefinition requirement, String fromInstanceId, + private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair, RequirementDefinition requirement, String fromInstanceId, Component originComponent) { - return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId()) - || (isCvfc(originComponent) && StringUtils - .equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId()) - || StringUtils.equals(requirement.getOwnerId(), originComponent.getUniqueId())); + return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId()) || ( + isCvfc(originComponent) && StringUtils.equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId()) || StringUtils + .equals(requirement.getOwnerId(), originComponent.getUniqueId())); } private boolean isCvfc(Component component) { - return component.getComponentType() == ComponentTypeEnum.RESOURCE && - ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC; + return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC; } - private Either convertCapabilities(Component component, - SubstitutionMapping substitutionMappings, - Map componentCache) { - - Either result = Either.left(substitutionMappings); - Either, ToscaError> toscaCapabilitiesRes = capabilityRequirementConverter - .convertSubstitutionMappingCapabilities(componentCache, component); + private Either, ToscaError> convertSubstitutionMappingCapabilities(final Component component, + final Map componentCache) { + Either, ToscaError> toscaCapabilitiesRes = + capabilityRequirementConverter.convertSubstitutionMappingCapabilities(componentCache, component); if (toscaCapabilitiesRes.isRight()) { - result = Either.right(toscaCapabilitiesRes.right().value()); log.debug("Failed convert capabilities for the component {}. ", component.getName()); - } else if (isNotEmpty(toscaCapabilitiesRes.left().value())) { - substitutionMappings.setCapabilities(toscaCapabilitiesRes.left().value()); + return Either.right(toscaCapabilitiesRes.right().value()); + } + if (isNotEmpty(toscaCapabilitiesRes.left().value())) { log.debug("Finish convert capabilities for the component {}. ", component.getName()); + return Either.left(toscaCapabilitiesRes.left().value()); } log.debug("Finished to convert capabilities for the component {}. ", component.getName()); - return result; + + return Either.left(Collections.emptyMap()); } - private Either convertCapabilities(Map componentsCache, - Component component, ToscaNodeType nodeType, + private Either convertCapabilities(Map componentsCache, Component component, ToscaNodeType nodeType, Map dataTypes) { - Map toscaCapabilities = capabilityRequirementConverter - .convertCapabilities(componentsCache, component, - dataTypes); + Map toscaCapabilities = capabilityRequirementConverter.convertCapabilities(componentsCache, component, dataTypes); if (!toscaCapabilities.isEmpty()) { nodeType.setCapabilities(toscaCapabilities); } log.debug("Finish convert Capabilities for node type"); - return Either.left(nodeType); } - private Map convertToNodeTemplateArtifacts( - Map artifacts) { + private Map convertToNodeTemplateArtifacts(Map artifacts) { if (artifacts == null) { return null; } @@ -1530,68 +1656,48 @@ public class ToscaExportHandler { ToscaTemplateArtifact artifact = new ToscaTemplateArtifact(); artifact.setFile(entry.getValue().getFile()); artifact.setType(entry.getValue().getType()); + artifact.setProperties(entry.getValue().getProperties()); arts.put(entry.getKey(), artifact); } return arts; } - protected NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) { + private NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) { if (inNodeFilter == null) { return null; } NodeFilter nodeFilter = new NodeFilter(); - - ListDataDefinition origCapabilities = - inNodeFilter.getCapabilities(); - - ListDataDefinition origProperties = inNodeFilter.getProperties(); - + ListDataDefinition origCapabilities = inNodeFilter.getCapabilities(); + ListDataDefinition origProperties = inNodeFilter.getProperties(); List> capabilitiesCopy = new ArrayList<>(); - List>> propertiesCopy = new ArrayList<>(); - copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy); - copyNodeFilterProperties(origProperties, propertiesCopy); - if (CollectionUtils.isNotEmpty(capabilitiesCopy)) { nodeFilter.setCapabilities(capabilitiesCopy); } - + final List>> propertiesCopy = copyNodeFilterProperties(origProperties); if (CollectionUtils.isNotEmpty(propertiesCopy)) { nodeFilter.setProperties(propertiesCopy); } - nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id())); - nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class); - return nodeFilter; } - private NodeFilter convertToSubstitutionFilterComponent( - final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) { - + private NodeFilter convertToSubstitutionFilterComponent(final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) { if (substitutionFilterDataDefinition == null) { return null; } NodeFilter nodeFilter = new NodeFilter(); - - ListDataDefinition origProperties = - substitutionFilterDataDefinition.getProperties(); - List>> propertiesCopy = new ArrayList<>(); - - copySubstitutionFilterProperties(origProperties, propertiesCopy); - - if (CollectionUtils.isNotEmpty(propertiesCopy)) { + final List>> propertiesCopy = copySubstitutionPropertiesFilter(substitutionFilterDataDefinition.getProperties()); + if (!propertiesCopy.isEmpty()) { nodeFilter.setProperties(propertiesCopy); } nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id())); - return (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class); } private Object cloneToscaId(Object toscaId) { - return Objects.isNull(toscaId) ? null - : cloneObjectFromYml(toscaId, toscaId.getClass()); + return Objects.isNull(toscaId) ? null : cloneObjectFromYml(toscaId, toscaId.getClass()); } private Object cloneObjectFromYml(Object objToClone, Class classOfObj) { @@ -1599,159 +1705,192 @@ public class ToscaExportHandler { return yamlUtil.yamlToObject(objectAsYml, classOfObj); } - private void copyNodeFilterCapabilitiesTemplate( - ListDataDefinition origCapabilities, - List> capabilitiesCopy) { - if (origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null || - origCapabilities.getListToscaDataDefinition().isEmpty()) { + private void copyNodeFilterCapabilitiesTemplate(ListDataDefinition origCapabilities, + List> capabilitiesCopy) { + if (origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null || origCapabilities.getListToscaDataDefinition() + .isEmpty()) { return; } for (RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) { Map capabilityFilterCopyMap = new HashMap<>(); - CapabilityFilter capabilityFilter = new CapabilityFilter(); - List>> propertiesCopy = new ArrayList<>(); - copyNodeFilterProperties(capability.getProperties(), propertiesCopy); - capabilityFilter.setProperties(propertiesCopy); + final var capabilityFilter = new CapabilityFilter(); + capabilityFilter.setProperties(copyNodeFilterProperties(capability.getProperties())); capabilityFilterCopyMap.put(capability.getName(), capabilityFilter); capabilitiesCopy.add(capabilityFilterCopyMap); } } - private void copyNodeFilterProperties( - ListDataDefinition origProperties, - List>> propertiesCopy) { - if (origProperties == null || origProperties.getListToscaDataDefinition() == null || - origProperties.isEmpty()) { - return; + private List>> copyNodeFilterProperties(final ListDataDefinition origProperties) { + if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) { + return Collections.emptyList(); } - Map> propertyMapCopy = new HashMap<>(); - for (RequirementNodeFilterPropertyDataDefinition propertyDataDefinition : origProperties - .getListToscaDataDefinition()) { - for (String propertyInfoEntry : propertyDataDefinition.getConstraints()) { - Map propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class); - String propertyName = propertyDataDefinition.getName(); - if (propertyMapCopy.containsKey(propertyName)) { - addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName)); - } else { - if (propertyName != null) { - List propsList = new ArrayList(); - addPropertyConstraintValueToList(propertyName, propertyValObj, propsList); - propertyMapCopy.put(propertyName, propsList); - } else { - propertyMapCopy.putAll(propertyValObj); + List>> propertiesCopy = new ArrayList<>(); + Map> propertyFilterDefinitionMap = new HashMap<>(); + for (final PropertyFilterDataDefinition propertyFilter : origProperties.getListToscaDataDefinition()) { + final String propertyName = propertyFilter.getName(); + for (final PropertyFilterConstraintDataDefinition filterConstraint : propertyFilter.getConstraints()) { + propertyFilterDefinitionMap.compute(propertyName, (propertyName1, constraints) -> { + if (constraints == null) { + constraints = new ArrayList<>(); } - } + constraints.add(buildNodeFilterValue(filterConstraint)); + return constraints; + }); } } - propertyMapCopy.entrySet().stream().forEach(entry -> - addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry)); + propertyFilterDefinitionMap.entrySet().stream() + .map(entry -> Map.of(entry.getKey(), entry.getValue())) + .forEach(propertiesCopy::add); + return propertiesCopy; } - private void copySubstitutionFilterProperties( - final ListDataDefinition origProperties, - final List>> propertiesCopy) { - if (origProperties == null || origProperties.getListToscaDataDefinition() == null || - origProperties.isEmpty()) { - return; + private List>> copySubstitutionPropertiesFilter( + final ListDataDefinition origProperties) { + + if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) { + return Collections.emptyList(); } - final Map> propertyMapCopy = new HashMap<>(); - for (final RequirementSubstitutionFilterPropertyDataDefinition propertyDataDefinition : origProperties - .getListToscaDataDefinition()) { - for (final String propertyInfoEntry : propertyDataDefinition.getConstraints()) { - final Map> propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class); - final String propertyName = propertyDataDefinition.getName(); - if (propertyMapCopy.containsKey(propertyName)) { - addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName)); - } else { - if (propertyName != null) { - final List propsList = new ArrayList(); - addPropertyConstraintValueToList(propertyName, propertyValObj, propsList); - propertyMapCopy.put(propertyName, propsList); - } else { - propertyMapCopy.putAll(propertyValObj); + List>> propertiesCopy = new ArrayList<>(); + Map> propertyFilterDefinitionMap = new HashMap<>(); + for (final SubstitutionFilterPropertyDataDefinition propertyFilter : origProperties.getListToscaDataDefinition()) { + final String propertyName = propertyFilter.getName(); + for (final PropertyFilterConstraintDataDefinition filterConstraint : propertyFilter.getConstraints()) { + propertyFilterDefinitionMap.compute(propertyName, (propertyName1, constraints) -> { + if (constraints == null) { + constraints = new ArrayList<>(); } - } + constraints.add(buildNodeFilterValue(filterConstraint)); + return constraints; + }); } } - propertyMapCopy.entrySet().forEach(entry -> - addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry)); + propertyFilterDefinitionMap.entrySet().stream() + .map(entry -> Map.of(entry.getKey(), entry.getValue())) + .forEach(propertiesCopy::add); + return propertiesCopy; } - private void addPropertyConstraintValueToList(String propertyName, Map propertyValObj, List propsList) { - if (propertyValObj.containsKey(propertyName)) { - propsList.add(propertyValObj.get(propertyName)); - } else { - propsList.add(propertyValObj); + private static Object buildNodeFilterValue(final PropertyFilterConstraintDataDefinition filterConstraint) { + if (filterConstraint.getValue() instanceof ToscaFunction) { + return Map.of(filterConstraint.getOperator().getType(), ((ToscaFunction) filterConstraint.getValue()).getJsonObjectValue()); + } + if (filterConstraint.getValue() instanceof List) { + if (((List) filterConstraint.getValue()).get(0) instanceof ToscaFunction) { + List toscaFunctionList = new ArrayList<>(); + ((List) filterConstraint.getValue()).forEach(toscaFunctionValue -> toscaFunctionList.add( + ((ToscaFunction) toscaFunctionValue).getJsonObjectValue())); + return Map.of(filterConstraint.getOperator().getType(), toscaFunctionList); + } + } + if (doesTypeNeedConvertingToIntOrFloat(filterConstraint.getOriginalType(), filterConstraint.getValue())) { + ToscaType toscaType = ToscaType.getToscaType( + filterConstraint.getValue() instanceof List ? ToscaType.LIST.getType() : filterConstraint.getOriginalType()); + filterConstraint.setValue(toscaType.convert(String.valueOf(filterConstraint.getValue()))); + } else if (ConstraintType.LENGTH.getType().equals(filterConstraint.getOperator().getType()) || + ConstraintType.MIN_LENGTH.getType().equals(filterConstraint.getOperator().getType()) || + ConstraintType.MAX_LENGTH.getType().equals(filterConstraint.getOperator().getType())) { + filterConstraint.setValue(Integer.valueOf(String.valueOf(filterConstraint.getValue()))); } + if (doesTypeNeedConvertingToBoolean(filterConstraint.getOriginalType())) { + filterConstraint.setValue(ToscaType.getToscaType(filterConstraint.getOriginalType()).convert( + String.valueOf(filterConstraint.getValue()))); + } + return Map.of(filterConstraint.getOperator().getType(), filterConstraint.getValue()); } - private void addCalculatedConstraintsIntoPropertiesList(List>> propertiesCopy, - Entry> entry) { - Map> tempMap = new HashMap<>(); - tempMap.put(entry.getKey(), entry.getValue()); - propertiesCopy.add(tempMap); + private static boolean doesTypeNeedConvertingToIntOrFloat(String propertyType, Object value) { + if (value instanceof List && ((List) value).get(0) instanceof LinkedHashMap + && ((LinkedHashMap) ((List) value).get(0)).get("type") != null) { + return false; + } + return ToscaType.INTEGER.getType().equals(propertyType) || ToscaType.FLOAT.getType().equals(propertyType); } - private static class CustomRepresenter extends Representer { + private static boolean doesTypeNeedConvertingToBoolean(String propertyType) { + return ToscaType.BOOLEAN.getType().equals(propertyType); + } - CustomRepresenter() { - super(); - this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment()); - // null representer is exceptional and it is stored as an instance - // variable. - this.nullRepresenter = new RepresentNull(); + private Map buildSubstitutionMappingPropertyMapping(final Component component) { + if (component == null || CollectionUtils.isEmpty(component.getInputs())) { + return Collections.emptyMap(); + } + Map propertyMapping = new HashMap<>(); + List propertyMappedInputList = component.getInputs().stream().filter(InputDefinition::isMappedToComponentProperty).collect( + Collectors.toList()); + + if (CollectionUtils.isNotEmpty(propertyMappedInputList)) { + propertyMappedInputList.forEach(inputDefinition -> { + if (StringUtils.isNotEmpty(inputDefinition.getPropertyId())) { + Optional property = component.getProperties().stream() + .filter(propertyDefinition -> propertyDefinition.getUniqueId().equals(inputDefinition.getPropertyId())).findFirst(); + if (property.isPresent()) { + propertyMapping.put(property.get().getName(), new String[]{inputDefinition.getName()}); + } + } else { + propertyMapping.put(inputDefinition.getName(), new String[]{inputDefinition.getName()}); + } + }); + } + return propertyMapping; + } + private Map buildSubstitutionMappingAttributesMapping(final Component component) { + if (component == null || CollectionUtils.isEmpty(component.getOutputs())) { + return Collections.emptyMap(); } + return component.getOutputs().stream().map(AttributeDataDefinition::getName) + .collect(Collectors.toMap(outputName -> outputName, outputName -> new String[]{outputName}, (outputName1, outputName2) -> outputName1)); + } - private class RepresentToscaPropertyAssignment implements Represent { - public Node representData(Object data) { - final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data; - if (toscaOperationAssignment.getValue() instanceof String) { - final String stringValue = (String) toscaOperationAssignment.getValue(); - if (isPropertyOrAttributeFunction(stringValue)) { - return representGetAttribute(stringValue); - } + private Optional> getProxyNodeTypeProperties(Component proxyComponent, Map dataTypes) { + if (Objects.isNull(proxyComponent)) { + return Optional.empty(); + } + final var proxyProperties = convertInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyComponent.getUniqueId()); + if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) { + proxyProperties.putAll(proxyComponent.getProperties().stream() + .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, proxyComponent.getInputs())).collect(Collectors + .toMap(PropertyDataDefinition::getName, + property -> propertyConvertor.convertProperty(dataTypes, property, PropertyType.PROPERTY)))); + } + return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty(); + } - return representScalar(Tag.STR, stringValue); - } - return represent(null); - } + private Map convertInputsToProperties(Map dataTypes, List componentInputs, + String componentUniqueId) { + if (CollectionUtils.isEmpty(componentInputs)) { + return new HashMap<>(); + } + return componentInputs.stream().filter(input -> componentUniqueId.equals(input.getInstanceUniqueId())) + .collect(Collectors.toMap(InputDefinition::getName, i -> propertyConvertor.convertProperty(dataTypes, i, PropertyType.INPUT))); + } - public Node representGetAttribute(final String getAttributeFunction) { - return represent(new Yaml().load(getAttributeFunction)); - } + private Optional> getProxyNodeTypeInterfaces(Component proxyComponent, Map dataTypes) { + if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) { + return Optional.empty(); + } + Map proxyComponentInterfaces = proxyComponent.getInterfaces(); + //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is - public boolean isPropertyOrAttributeFunction(final String value) { - try { - final Yaml yaml = new Yaml(); - final Object yamlObj = yaml.load(value); - if (!(yamlObj instanceof Map)) { - return false; - } - final Map getAttributeMap = (Map) yamlObj; - if (getAttributeMap.size() != 1) { - return false; - } - final List functionList = Arrays - .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(), - GET_PROPERTY.getFunctionName()); - final Optional function = getAttributeMap.keySet().stream() - .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst(); + // always available in the proxy node template + removeOperationImplementationForProxyNodeType(proxyComponentInterfaces); + return Optional.ofNullable(interfacesOperationsConverter.getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes, false)); + } - if (function.isEmpty()) { - return false; - } - final String functionName = function.get(); - final Object getAttributeValueObj = getAttributeMap.get(functionName); - if (GET_INPUT.getFunctionName().equals(functionName)) { - return validateGetInputValue(getAttributeValueObj); - } else { - return validateGetPropertyOrAttributeValue(getAttributeValueObj); - } - } catch (final Exception ignored) { - return false; - } - } + private Configuration getConfiguration() { + return ConfigurationManager.getConfigurationManager().getConfiguration(); + } + + private static class CustomRepresenter extends Representer { + + CustomRepresenter() { + super(); + this.representers.put(ToscaPropertyAssignment.class, new RepresentToscaPropertyAssignment()); + this.representers.put(ToscaAttribute.class, new RepresentToscaAttribute()); + // null representer is exceptional and it is stored as an instance + + // variable. + this.nullRepresenter = new RepresentNull(); } public boolean validateGetInputValue(final Object valueObj) { @@ -1761,7 +1900,6 @@ public class ToscaExportHandler { if (valueObj instanceof List) { return ((List) valueObj).size() > 1; } - return true; } @@ -1769,13 +1907,11 @@ public class ToscaExportHandler { if (valueObj instanceof List) { return ((List) valueObj).size() > 1; } - return false; } @Override - protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, - Tag customTag) { + protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) { if (propertyValue == null) { return null; } @@ -1786,27 +1922,31 @@ public class ToscaExportHandler { if (javaBean instanceof ToscaRelationshipTemplate && "name".equals(property.getName())) { return null; } - + if (javaBean instanceof ToscaPropertyConstraint) { + return handleToscaPropertyConstraint((ToscaPropertyConstraint) javaBean, property, propertyValue, customTag); + } removeDefaultP(propertyValue); NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag); - if (javaBean instanceof ToscaTopolgyTemplate && "relationshipTemplates".equals(property.getName())) { return new NodeTuple(representData("relationship_templates"), defaultNode.getValueNode()); } + return "_defaultp_".equals(property.getName()) ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode; + } - return "_defaultp_".equals(property.getName()) - ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode; + private NodeTuple handleToscaPropertyConstraint(final ToscaPropertyConstraint javaBean, final Property property, final Object propertyValue, + final Tag customTag) { + final NodeTuple nodeTuple = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag); + final String entryToscaName = javaBean.getEntryToscaName(property.getName()); + return new NodeTuple(representData(entryToscaName), nodeTuple.getValueNode()); } private void removeDefaultP(final Object propertyValue) { if (propertyValue instanceof Map) { final Map mapPropertyValue = ((Map) propertyValue); - final Iterator iter = mapPropertyValue.entrySet().iterator(); Object defaultValue = null; while (iter.hasNext()) { final Map.Entry entry = iter.next(); - if ("_defaultp_".equals(entry.getKey())) { defaultValue = entry.getValue(); iter.remove(); @@ -1826,129 +1966,84 @@ public class ToscaExportHandler { if (!classTags.containsKey(javaBean.getClass())) { addClassTag(javaBean.getClass(), Tag.MAP); } - return super.representJavaBean(properties, javaBean); } - private class RepresentNull implements Represent { + private class RepresentToscaAttribute implements Represent { @Override public Node representData(Object data) { - // possible values are here http://yaml.org/type/null.html - return representScalar(Tag.NULL, ""); + final ToscaAttribute toscaAttribute = (ToscaAttribute) data; + return represent(toscaAttribute.asToscaMap()); } } - } - - private static class UnsortedPropertyUtils extends PropertyUtils { - - @Override - protected Set createPropertySet(Class type, BeanAccess bAccess) - throws IntrospectionException { - Collection fields = getPropertiesMap(type, BeanAccess.FIELD).values(); - return new LinkedHashSet<>(fields); - } - } - private Object removeOperationsKeyFromInterface(Object interfaceInstanceDataDefinition) { - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false); - - Map interfaceAsMap = ServiceUtils.getObjectAsMap(interfaceInstanceDataDefinition); - Map operations = (Map) interfaceAsMap.remove("operations"); - interfaceAsMap.remove("empty"); - - if (MapUtils.isNotEmpty(operations)) { - interfaceAsMap.putAll(operations); - } - - Object interfaceObject = objectMapper.convertValue(interfaceAsMap, Object.class); + private class RepresentToscaPropertyAssignment implements Represent { - return interfaceObject; + public Node representData(Object data) { + final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data; + if (toscaOperationAssignment.getValue() instanceof String) { + final String stringValue = (String) toscaOperationAssignment.getValue(); + if (isPropertyOrAttributeFunction(stringValue)) { + return representGetAttribute(stringValue); + } + return representScalar(Tag.STR, stringValue); + } + return represent(null); + } - } + public Node representGetAttribute(final String getAttributeFunction) { + return represent(new Yaml().load(getAttributeFunction)); + } - private Map buildSubstitutionMappingPropertyMapping(final Component component) { - if (component == null || CollectionUtils.isEmpty(component.getInputs())) { - return Collections.emptyMap(); + public boolean isPropertyOrAttributeFunction(final String value) { + try { + final Yaml yaml = new Yaml(); + final Object yamlObj = yaml.load(value); + if (!(yamlObj instanceof Map)) { + return false; + } + final Map getAttributeMap = (Map) yamlObj; + if (getAttributeMap.size() != 1) { + return false; + } + final List functionList = Arrays + .asList(GET_ATTRIBUTE.getFunctionName(), GET_INPUT.getFunctionName(), GET_PROPERTY.getFunctionName()); + final Optional function = getAttributeMap.keySet().stream() + .filter(key -> functionList.stream().anyMatch(function1 -> function1.equals(key))).findFirst(); + if (function.isEmpty()) { + return false; + } + final String functionName = function.get(); + final Object getAttributeValueObj = getAttributeMap.get(functionName); + if (GET_INPUT.getFunctionName().equals(functionName)) { + return validateGetInputValue(getAttributeValueObj); + } else { + return validateGetPropertyOrAttributeValue(getAttributeValueObj); + } + } catch (final Exception ignored) { + return false; + } + } } - return component.getInputs().stream() - .map(PropertyDataDefinition::getName) - .collect( - Collectors.toMap( - inputName -> inputName, - inputName -> new String[]{inputName}, - (inputName1, inputName2) -> inputName1) - ); - } - private Map buildSubstitutionMappingAttributesMapping(final Component component) { - if (component == null || CollectionUtils.isEmpty(component.getOutputs())) { - return Collections.emptyMap(); - } - return component.getOutputs().stream() - .map(PropertyDataDefinition::getName) - .collect( - Collectors.toMap( - outputName -> outputName, - outputName -> new String[]{outputName}, - (outputName1, outputName2) -> outputName1) - ); - } + private class RepresentNull implements Represent { - Optional> getProxyNodeTypeProperties(Component proxyComponent, - Map - dataTypes) { - if (Objects.isNull(proxyComponent)) { - return Optional.empty(); - } - Map proxyProperties = new HashMap<>(); - addInputsToProperties(dataTypes, proxyComponent.getInputs(), proxyProperties); - if (CollectionUtils.isNotEmpty(proxyComponent.getProperties())) { - proxyProperties.putAll(proxyComponent.getProperties().stream() - .map(propertyDefinition -> resolvePropertyValueFromInput(propertyDefinition, - proxyComponent.getInputs())) - .collect(Collectors.toMap(PropertyDataDefinition::getName, - property -> propertyConvertor.convertProperty(dataTypes, property, - PropertyConvertor.PropertyType.PROPERTY)))); + @Override + public Node representData(Object data) { + // possible values are here http://yaml.org/type/null.html + return representScalar(Tag.NULL, ""); + } } - return MapUtils.isNotEmpty(proxyProperties) ? Optional.of(proxyProperties) : Optional.empty(); } - void addInputsToProperties(Map dataTypes, - List componentInputs, - Map mergedProperties) { - if (CollectionUtils.isEmpty(componentInputs)) { - return; - } - for (InputDefinition input : componentInputs) { - ToscaProperty property = propertyConvertor.convertProperty(dataTypes, input, - PropertyConvertor.PropertyType.INPUT); - mergedProperties.put(input.getName(), property); - } - } + private static class UnsortedPropertyUtils extends PropertyUtils { - Optional> getProxyNodeTypeInterfaces(Component proxyComponent, - Map dataTypes) { - if (Objects.isNull(proxyComponent) || MapUtils.isEmpty(proxyComponent.getInterfaces())) { - return Optional.empty(); + @Override + protected Set createPropertySet(Class type, BeanAccess bAccess) { + Collection fields = getPropertiesMap(type, BeanAccess.FIELD).values(); + return new LinkedHashSet<>(fields); } - Map proxyComponentInterfaces = proxyComponent.getInterfaces(); - //Unset artifact path for operation implementation for proxy node types as for operations with artifacts it is - // always available in the proxy node template - removeOperationImplementationForProxyNodeType(proxyComponentInterfaces); - return Optional.ofNullable(interfacesOperationsConverter - .getInterfacesMap(proxyComponent, null, proxyComponentInterfaces, dataTypes, - false, false)); } - private static void removeOperationImplementationForProxyNodeType( - Map proxyComponentInterfaces) { - if (MapUtils.isEmpty(proxyComponentInterfaces)) { - return; - } - proxyComponentInterfaces.values().stream().map(InterfaceDataDefinition::getOperations) - .filter(MapUtils::isNotEmpty) - .forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null))); - } }