package org.openecomp.core.impl; import org.apache.commons.collections.MapUtils; import org.openecomp.core.converter.ServiceTemplateReaderService; import org.openecomp.core.converter.ToscaConverter; import org.openecomp.core.converter.datatypes.Constants; import org.openecomp.core.converter.datatypes.CsarFileTypes; import org.openecomp.core.impl.services.ServiceTemplateReaderServiceImpl; import org.openecomp.core.utilities.file.FileContentHandler; import org.openecomp.core.utilities.json.JsonUtil; import org.openecomp.sdc.common.errors.CoreException; import org.openecomp.sdc.common.errors.ErrorCategory; import org.openecomp.sdc.common.errors.ErrorCode; import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel; import org.openecomp.sdc.tosca.datatypes.model.*; import org.openecomp.sdc.tosca.services.DataModelUtil; import org.openecomp.sdc.tosca.services.ToscaUtil; import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator; import org.yaml.snakeyaml.error.YAMLException; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.util.*; import java.util.jar.Manifest; import java.util.regex.Pattern; import static org.openecomp.core.converter.datatypes.Constants.*; import static org.openecomp.core.impl.GlobalSubstitutionServiceTemplate.GLOBAL_SUBSTITUTION_SERVICE_FILE_NAME; public class ToscaConverterImpl implements ToscaConverter { public ToscaConverterImpl() { } @Override public ToscaServiceModel convert(FileContentHandler fileContentHandler) throws IOException { Map csarFiles = new HashMap<>(fileContentHandler.getFiles()); ToscaServiceModel toscaServiceModel = new ToscaServiceModel(); Map serviceTemplates = new HashMap<>(); FileContentHandler artifacts = new FileContentHandler(); GlobalSubstitutionServiceTemplate gsst = new GlobalSubstitutionServiceTemplate(); for (Map.Entry fileEntry : csarFiles.entrySet()) { CsarFileTypes fileType = getFileType(fileEntry.getKey()); switch (fileType) { case mainServiceTemplate: handleServiceTemplate(mainStName, fileEntry.getKey(), csarFiles, serviceTemplates); break; case globalServiceTemplate: handleServiceTemplate(globalStName, fileEntry.getKey(), csarFiles, serviceTemplates); break; case externalFile: artifacts.addFile(fileEntry.getKey(), fileEntry.getValue()); break; case definitionsFile: handleDefintionTemplate(fileEntry.getKey(), csarFiles, gsst); break; } } handleMetadataFile(csarFiles); updateToscaServiceModel(toscaServiceModel, serviceTemplates, artifacts, gsst, csarFiles); return toscaServiceModel; } private void handleMetadataFile(Map csarFiles) { byte[] bytes = csarFiles.remove(metadataFile); if (bytes != null) { csarFiles.put(metadataFile + ".old", bytes); } } private void handleDefintionTemplate(String key, Map csarFiles, GlobalSubstitutionServiceTemplate gsst) { try { ServiceTemplateReaderService readerService = new ServiceTemplateReaderServiceImpl(csarFiles.get(key)); if (readerService == null) { return; } Object nodeTypes = readerService.getNodeTypes(); if (nodeTypes instanceof Map) { Map nodeTypeMap = (Map) nodeTypes; gsst.appendNodes(nodeTypeMap); } } catch (YAMLException ye) { throw new CoreException(new ErrorCode.ErrorCodeBuilder() .withMessage("Invalid YAML content in file " + key + ". reason - " + ye.getMessage()) .withCategory(ErrorCategory.APPLICATION).build()); } } private void updateToscaServiceModel(ToscaServiceModel toscaServiceModel, Map serviceTemplates, FileContentHandler externalFilesHandler, GlobalSubstitutionServiceTemplate globalSubstitutionServiceTemplate, Map csarFiles) { Collection globalServiceTemplates = GlobalTypesGenerator.getGlobalTypesServiceTemplate().values(); addGlobalServiceTemplates(globalServiceTemplates, serviceTemplates); serviceTemplates.put(GLOBAL_SUBSTITUTION_SERVICE_FILE_NAME, globalSubstitutionServiceTemplate); toscaServiceModel.setEntryDefinitionServiceTemplate(mainStName); toscaServiceModel.setServiceTemplates(serviceTemplates); externalFilesHandler.addFile(metadataFile + ".old", csarFiles.get(metadataFile + ".old")); toscaServiceModel.setArtifactFiles(externalFilesHandler); } private void addGlobalServiceTemplates(Collection globalServiceTemplates, Map serviceTemplates) { for (ServiceTemplate serviceTemplate : globalServiceTemplates) { serviceTemplates.put(ToscaUtil.getServiceTemplateFileName(serviceTemplate), serviceTemplate); } } private void handleServiceTemplate(String serviceTemplateName, String fileName, Map csarFiles, Map serviceTemplates) { Optional serviceTemplate = getServiceTemplateFromCsar(fileName, csarFiles); serviceTemplate.ifPresent( serviceTemplate1 -> addServiceTemplate(serviceTemplateName, serviceTemplate1, serviceTemplates)); } private void addServiceTemplate(String serviceTemplateName, ServiceTemplate serviceTemplate, Map serviceTemplates) { serviceTemplates.put(serviceTemplateName, serviceTemplate); } private Optional getManifestContent(Map csarFiles) { for (Map.Entry csarFileEntry : csarFiles.entrySet()) { if (csarFileEntry.getKey().contains(manifestFileName)) { return Optional.of(csarFileEntry.getValue()); } } return Optional.empty(); } private Optional getServiceTemplateFromCsar(String fileName, Map csarFiles) { byte[] fileContent = csarFiles.get(fileName); ServiceTemplate serviceTemplate = convertServiceTemplate(fileName, fileContent); return Optional.of(serviceTemplate); } private ServiceTemplate convertServiceTemplate(String serviceTemplateName, byte[] fileContent) { ServiceTemplate serviceTemplate = new ServiceTemplate(); try { ServiceTemplateReaderService readerService = new ServiceTemplateReaderServiceImpl(fileContent); convertMetadata(serviceTemplateName, serviceTemplate, readerService); convertToscaVersion(serviceTemplate, readerService); convertImports(serviceTemplate); convertNodeTypes(serviceTemplate, readerService); convertTopologyTemplate(serviceTemplate, readerService); } catch (YAMLException ye) { throw new CoreException(new ErrorCode.ErrorCodeBuilder() .withMessage("Invalid YAML content in file" + serviceTemplateName + ". reason - " + ye.getMessage()) .withCategory(ErrorCategory.APPLICATION).build()); } return serviceTemplate; } private void convertToscaVersion(ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) { Object toscaVersion = readerService.getToscaVersion(); serviceTemplate.setTosca_definitions_version((String) toscaVersion); } private void convertImports(ServiceTemplate serviceTemplate) { serviceTemplate.setImports(new ArrayList<>()); serviceTemplate.getImports() .add(createImportMap(openecompHeatIndex, "openecomp-heat/_index.yml")); serviceTemplate.getImports().add(createImportMap(globalSubstitution, globalStName)); } private Map createImportMap(String key, String fileName) { Map importMap = new HashMap<>(); Import anImport = new Import(); anImport.setFile(fileName); importMap.put(key, anImport); return importMap; } private void convertMetadata(String serviceTemplateName, ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) { Map metadataToConvert = (Map) readerService.getMetadata(); Map finalMetadata = new HashMap<>(); if (MapUtils.isNotEmpty(metadataToConvert)) { for (Map.Entry metadataEntry : metadataToConvert.entrySet()) { if (Objects.isNull(metadataEntry.getValue()) || !(metadataEntry.getValue() instanceof String)) { continue; } finalMetadata.put(metadataEntry.getKey(), (String) metadataEntry.getValue()); } } finalMetadata.put("template_name", getTemplateNameFromStName(serviceTemplateName)); serviceTemplate.setMetadata(finalMetadata); } private void convertNodeTypes(ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) { Map nodeTypes = (Map) readerService.getNodeTypes(); if (MapUtils.isEmpty(nodeTypes)) { return; } for (Map.Entry nodeTypeEntry : nodeTypes.entrySet()) { DataModelUtil .addNodeType(serviceTemplate, nodeTypeEntry.getKey(), (NodeType) createObjectFromClass(nodeTypeEntry.getKey(), nodeTypeEntry.getValue(), NodeType.class)); } } private void convertTopologyTemplate(ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) { convertInputs(serviceTemplate, readerService); convertNodeTemplates(serviceTemplate, readerService); convertOutputs(serviceTemplate, readerService); convertSubstitutionMappings(serviceTemplate, readerService); } private void convertInputs(ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) { Map inputs = readerService.getInputs(); addInputsOrOutputsToServiceTemplate(serviceTemplate, inputs, Constants.inputs); } private void convertOutputs(ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) { Map outputs = readerService.getOutputs(); addInputsOrOutputsToServiceTemplate(serviceTemplate, outputs, Constants.outputs); } private void addInputsOrOutputsToServiceTemplate(ServiceTemplate serviceTemplate, Map mapToConvert, String inputsOrOutputs) { if (MapUtils.isEmpty(mapToConvert)) { return; } for (Map.Entry entry : mapToConvert.entrySet()) { ParameterDefinition parameterDefinition = (ParameterDefinition) createObjectFromClass( entry.getKey(), entry.getValue(), ParameterDefinition.class); addToServiceTemplateAccordingToSection( serviceTemplate, inputsOrOutputs, entry.getKey(), parameterDefinition); } } private void addToServiceTemplateAccordingToSection(ServiceTemplate serviceTemplate, String inputsOrOutputs, String parameterId, ParameterDefinition parameterDefinition) { switch (inputsOrOutputs) { case inputs: DataModelUtil .addInputParameterToTopologyTemplate(serviceTemplate, parameterId, parameterDefinition); break; case outputs: DataModelUtil .addOutputParameterToTopologyTemplate(serviceTemplate, parameterId, parameterDefinition); } } private void convertNodeTemplates(ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) { Map nodeTemplates = readerService.getNodeTemplates(); if (MapUtils.isEmpty(nodeTemplates)) { return; } for (Map.Entry nodeTemplateEntry : nodeTemplates.entrySet()) { NodeTemplate nodeTemplate = convertNodeTemplate(nodeTemplateEntry.getValue()); DataModelUtil.addNodeTemplate(serviceTemplate, nodeTemplateEntry.getKey(), nodeTemplate); } } private void convertSubstitutionMappings(ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) { Map substitutionMappings = readerService.getSubstitutionMappings(); if (MapUtils.isEmpty(substitutionMappings)) { return; } SubstitutionMapping substitutionMapping = convertSubstitutionMappings(substitutionMappings); DataModelUtil.addSubstitutionMapping(serviceTemplate, substitutionMapping); } private SubstitutionMapping convertSubstitutionMappings(Map substitutionMappings) { SubstitutionMapping substitutionMapping = new SubstitutionMapping(); substitutionMapping.setNode_type((String) substitutionMappings.get(nodeType)); substitutionMapping.setCapabilities( convertSubstitutionMappingsSections((Map) substitutionMappings.get(capabilities))); substitutionMapping.setRequirements( convertSubstitutionMappingsSections((Map) substitutionMappings.get(requirements))); return substitutionMapping; } private Map> convertSubstitutionMappingsSections( Map sectionToConvert) { Map> convertedSection = new HashMap<>(); if (MapUtils.isEmpty(sectionToConvert)) { return null; } for (Map.Entry entry : sectionToConvert.entrySet()) { if (entry.getValue() instanceof List) { convertedSection.put(entry.getKey(), (List) entry.getValue()); } } return convertedSection; } private CsarFileTypes getFileType(String fileName) { if (isMainServiceTemplate(fileName)) { return CsarFileTypes.mainServiceTemplate; } else if (isGlobalServiceTemplate(fileName)) { return CsarFileTypes.globalServiceTemplate; } else if (isDefinitions(fileName)) { return CsarFileTypes.definitionsFile; } else if (isMetadataFile(metadataFile)) { return CsarFileTypes.toscaMetadata; } return CsarFileTypes.externalFile; } private Optional getCsarManifest(Map csarFiles) throws IOException { Optional manifestContent = getManifestContent(csarFiles); if (manifestContent.isPresent()) { ByteArrayInputStream byteInputStream = new ByteArrayInputStream(manifestContent.get()); return Optional.of(new Manifest(byteInputStream)); } return Optional.empty(); } private NodeTemplate convertNodeTemplate(Object candidateNodeTemplate) { NodeTemplate nodeTemplate = new NodeTemplate(); Map nodeTemplateAsMap = (Map) candidateNodeTemplate; nodeTemplate.setArtifacts((Map) nodeTemplateAsMap.get("artifacts")); nodeTemplate.setAttributes((Map) nodeTemplateAsMap.get("attributes")); nodeTemplate.setCopy((String) nodeTemplateAsMap.get("copy")); nodeTemplate.setDescription((String) nodeTemplateAsMap.get("description")); nodeTemplate.setDirectives((List) nodeTemplateAsMap.get("directives")); nodeTemplate.setInterfaces( (Map) nodeTemplateAsMap.get("interfaces")); nodeTemplate.setNode_filter((NodeFilter) nodeTemplateAsMap.get("node_filter")); nodeTemplate.setProperties((Map) nodeTemplateAsMap.get("properties")); nodeTemplate.setRequirements( (List>) nodeTemplateAsMap.get("requirements")); nodeTemplate.setType((String) nodeTemplateAsMap.get("type")); nodeTemplate.setCapabilities( convertCapabilities((Map) nodeTemplateAsMap.get("capabilities"))); return nodeTemplate; } private List> convertCapabilities(Map capabilities) { List> convertedCapabilities = new ArrayList<>(); if (MapUtils.isEmpty(capabilities)) { return null; } for (Map.Entry capabilityAssignmentEntry : capabilities.entrySet()) { Map tempMap = new HashMap<>(); tempMap.put(capabilityAssignmentEntry.getKey(), (CapabilityAssignment) createObjectFromClass (capabilityAssignmentEntry.getKey(), capabilityAssignmentEntry.getValue(), CapabilityAssignment.class)); convertedCapabilities.add(tempMap); } return convertedCapabilities; } private Object createObjectFromClass(String nodeTypeId, Object objectCandidate, Class classToCreate) { try { return JsonUtil.json2Object(objectCandidate.toString(), classToCreate); } catch (Exception e) { //todo - return error to user? throw new CoreException(new ErrorCode.ErrorCodeBuilder() .withCategory(ErrorCategory.APPLICATION) .withMessage("Can't create Node Type from " + nodeTypeId).build()); } } private boolean isMainServiceTemplate(String fileName) { return fileName.endsWith(mainStName); } private boolean isMetadataFile(String fileName) { return fileName.equals(metadataFile); } private boolean isGlobalServiceTemplate(String fileName) { return fileName.endsWith(globalStName); } private boolean isDefinitions(String fileName) { return fileName.startsWith(definitionsDir); } private String getTemplateNameFromStName(String serviceTemplateName) { String fileNameWithoutDirectories; fileNameWithoutDirectories = getFileNameWithoutDirectories(serviceTemplateName); return fileNameWithoutDirectories.split("ServiceTemplate")[0]; } private String getFileNameWithoutDirectories(String serviceTemplateName) { String fileNameWithoutDirectories; if (serviceTemplateName.contains("/")) { String[] split = serviceTemplateName.split("/"); fileNameWithoutDirectories = split[split.length - 1]; } else if (serviceTemplateName.contains(File.separator)) { String[] split = serviceTemplateName.split(Pattern.quote(File.separator)); fileNameWithoutDirectories = split[split.length - 1]; } else { fileNameWithoutDirectories = serviceTemplateName; } return fileNameWithoutDirectories; } }