1 package org.openecomp.core.impl;
3 import org.apache.commons.collections.MapUtils;
4 import org.openecomp.core.converter.ServiceTemplateReaderService;
5 import org.openecomp.core.converter.ToscaConverter;
6 import org.openecomp.core.converter.datatypes.Constants;
7 import org.openecomp.core.converter.datatypes.CsarFileTypes;
8 import org.openecomp.core.converter.errors.SubstitutionMappingsConverterErrorBuilder;
9 import org.openecomp.core.impl.services.ServiceTemplateReaderServiceImpl;
10 import org.openecomp.core.utilities.file.FileContentHandler;
11 import org.openecomp.sdc.common.errors.CoreException;
12 import org.openecomp.sdc.common.errors.ErrorCategory;
13 import org.openecomp.sdc.common.errors.ErrorCode;
14 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
15 import org.openecomp.sdc.tosca.datatypes.model.ArtifactDefinition;
16 import org.openecomp.sdc.tosca.datatypes.model.CapabilityAssignment;
17 import org.openecomp.sdc.tosca.datatypes.model.Import;
18 import org.openecomp.sdc.tosca.datatypes.model.InterfaceDefinition;
19 import org.openecomp.sdc.tosca.datatypes.model.NodeFilter;
20 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
21 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
22 import org.openecomp.sdc.tosca.datatypes.model.ParameterDefinition;
23 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
24 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
25 import org.openecomp.sdc.tosca.datatypes.model.SubstitutionMapping;
26 import org.openecomp.sdc.tosca.services.DataModelUtil;
27 import org.openecomp.sdc.tosca.services.ToscaUtil;
28 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
29 import org.yaml.snakeyaml.error.YAMLException;
31 import java.io.ByteArrayInputStream;
33 import java.io.IOException;
34 import java.util.ArrayList;
35 import java.util.Collection;
36 import java.util.HashMap;
37 import java.util.List;
39 import java.util.Objects;
40 import java.util.Optional;
41 import java.util.jar.Manifest;
42 import java.util.regex.Pattern;
44 import static org.openecomp.core.converter.datatypes.Constants.capabilities;
45 import static org.openecomp.core.converter.datatypes.Constants.definitionsDir;
46 import static org.openecomp.core.converter.datatypes.Constants.globalStName;
47 import static org.openecomp.core.converter.datatypes.Constants.globalSubstitution;
48 import static org.openecomp.core.converter.datatypes.Constants.inputs;
49 import static org.openecomp.core.converter.datatypes.Constants.mainStName;
50 import static org.openecomp.core.converter.datatypes.Constants.manifestFileName;
51 import static org.openecomp.core.converter.datatypes.Constants.metadataFile;
52 import static org.openecomp.core.converter.datatypes.Constants.nodeType;
53 import static org.openecomp.core.converter.datatypes.Constants.openecompHeatIndex;
54 import static org.openecomp.core.converter.datatypes.Constants.outputs;
55 import static org.openecomp.core.converter.datatypes.Constants.requirements;
56 import static org.openecomp.core.impl.GlobalSubstitutionServiceTemplate.GLOBAL_SUBSTITUTION_SERVICE_FILE_NAME;
58 public class ToscaConverterImpl implements ToscaConverter {
60 public ToscaConverterImpl() {
65 public ToscaServiceModel convert(FileContentHandler fileContentHandler)
67 Map<String, byte[]> csarFiles = new HashMap<>(fileContentHandler.getFiles());
68 ToscaServiceModel toscaServiceModel = new ToscaServiceModel();
69 Map<String, ServiceTemplate> serviceTemplates = new HashMap<>();
70 FileContentHandler artifacts = new FileContentHandler();
71 GlobalSubstitutionServiceTemplate gsst = new GlobalSubstitutionServiceTemplate();
72 for (Map.Entry<String, byte[]> fileEntry : csarFiles.entrySet()) {
73 CsarFileTypes fileType = getFileType(fileEntry.getKey());
75 case mainServiceTemplate:
76 handleServiceTemplate(mainStName, fileEntry.getKey(), csarFiles, serviceTemplates);
79 case globalServiceTemplate:
80 handleServiceTemplate(globalStName, fileEntry.getKey(), csarFiles, serviceTemplates);
85 getConcreteArtifactFileName(fileEntry.getKey()), fileEntry.getValue());
89 handleDefintionTemplate(fileEntry.getKey(), csarFiles, gsst);
93 handleMetadataFile(csarFiles);
94 updateToscaServiceModel(toscaServiceModel, serviceTemplates, artifacts, gsst, csarFiles);
95 return toscaServiceModel;
98 private void handleMetadataFile(Map<String, byte[]> csarFiles) {
99 byte[] bytes = csarFiles.remove(metadataFile);
101 csarFiles.put(metadataFile + ".original", bytes);
105 private void handleDefintionTemplate(String key, Map<String, byte[]> csarFiles,
106 GlobalSubstitutionServiceTemplate gsst) {
108 ServiceTemplateReaderService readerService = new ServiceTemplateReaderServiceImpl(csarFiles.get(key));
109 if (readerService == null) {
112 Object nodeTypes = readerService.getNodeTypes();
113 if (nodeTypes instanceof Map) {
114 Map<String, NodeType> nodeTypeMap = (Map<String, NodeType>) nodeTypes;
115 gsst.appendNodes(nodeTypeMap);
117 } catch (YAMLException ye) {
118 throw new CoreException(new ErrorCode.ErrorCodeBuilder()
119 .withMessage("Invalid YAML content in file " + key)
120 .withCategory(ErrorCategory.APPLICATION).build(), ye);
124 private String getConcreteArtifactFileName(String fileName){
125 int artifactIndex = fileName.indexOf(CsarFileTypes.Artifacts.name());
126 if(artifactIndex < 0){
130 int artifactDirectoryIndex =
131 artifactIndex + CsarFileTypes.Artifacts.name().length() + 1;
132 return fileName.substring(artifactDirectoryIndex);
135 private void updateToscaServiceModel(ToscaServiceModel toscaServiceModel,
136 Map<String, ServiceTemplate> serviceTemplates,
137 FileContentHandler externalFilesHandler,
138 GlobalSubstitutionServiceTemplate globalSubstitutionServiceTemplate,
139 Map<String, byte[]> csarFiles) {
140 Collection<ServiceTemplate> globalServiceTemplates =
141 GlobalTypesGenerator.getGlobalTypesServiceTemplate().values();
142 addGlobalServiceTemplates(globalServiceTemplates, serviceTemplates);
143 toscaServiceModel.setEntryDefinitionServiceTemplate(mainStName);
144 toscaServiceModel.setServiceTemplates(serviceTemplates);
145 externalFilesHandler.addFile(metadataFile + ".original",
146 csarFiles.get(metadataFile + ".original"));
147 toscaServiceModel.setArtifactFiles(externalFilesHandler);
149 if(MapUtils.isNotEmpty(globalSubstitutionServiceTemplate.getNode_types())) {
151 .put(GLOBAL_SUBSTITUTION_SERVICE_FILE_NAME, globalSubstitutionServiceTemplate);
155 private void addGlobalServiceTemplates(Collection<ServiceTemplate> globalServiceTemplates,
156 Map<String, ServiceTemplate> serviceTemplates) {
157 for (ServiceTemplate serviceTemplate : globalServiceTemplates) {
158 serviceTemplates.put(ToscaUtil.getServiceTemplateFileName(serviceTemplate), serviceTemplate);
162 private void handleServiceTemplate(String serviceTemplateName,
163 String fileName, Map<String, byte[]> csarFiles,
164 Map<String, ServiceTemplate> serviceTemplates) {
165 Optional<ServiceTemplate> serviceTemplate =
166 getServiceTemplateFromCsar(fileName, csarFiles);
167 serviceTemplate.ifPresent(
168 serviceTemplateValue -> addServiceTemplate(serviceTemplateName, serviceTemplateValue,
172 private void addServiceTemplate(String serviceTemplateName,
173 ServiceTemplate serviceTemplate,
174 Map<String, ServiceTemplate> serviceTemplates) {
175 serviceTemplates.put(serviceTemplateName, serviceTemplate);
178 private Optional<byte[]> getManifestContent(Map<String, byte[]> csarFiles) {
179 for (Map.Entry<String, byte[]> csarFileEntry : csarFiles.entrySet()) {
180 if (csarFileEntry.getKey().contains(manifestFileName)) {
181 return Optional.of(csarFileEntry.getValue());
185 return Optional.empty();
188 private Optional<ServiceTemplate> getServiceTemplateFromCsar(String fileName,
189 Map<String, byte[]> csarFiles) {
190 byte[] fileContent = csarFiles.get(fileName);
191 ServiceTemplate serviceTemplate = convertServiceTemplate(fileName, fileContent);
193 return Optional.of(serviceTemplate);
196 private ServiceTemplate convertServiceTemplate(String serviceTemplateName,
197 byte[] fileContent) {
198 ServiceTemplate serviceTemplate = new ServiceTemplate();
200 ServiceTemplateReaderService readerService =
201 new ServiceTemplateReaderServiceImpl(fileContent);
202 convertMetadata(serviceTemplateName, serviceTemplate, readerService);
203 convertToscaVersion(serviceTemplate, readerService);
204 convertImports(serviceTemplate);
205 convertNodeTypes(serviceTemplate, readerService);
206 convertTopologyTemplate(serviceTemplate, readerService);
208 } catch (YAMLException ye) {
209 throw new CoreException(new ErrorCode.ErrorCodeBuilder()
210 .withMessage("Invalid YAML content in file" + serviceTemplateName)
211 .withCategory(ErrorCategory.APPLICATION).build(), ye);
215 return serviceTemplate;
218 private void convertToscaVersion(ServiceTemplate serviceTemplate,
219 ServiceTemplateReaderService readerService) {
220 Object toscaVersion = readerService.getToscaVersion();
221 serviceTemplate.setTosca_definitions_version((String) toscaVersion);
224 private void convertImports(ServiceTemplate serviceTemplate) {
225 serviceTemplate.setImports(new ArrayList<>());
226 serviceTemplate.getImports()
227 .add(createImportMap(openecompHeatIndex, "openecomp-heat/_index.yml"));
228 serviceTemplate.getImports().add(createImportMap(globalSubstitution, globalStName));
232 private Map<String, Import> createImportMap(String key, String fileName) {
233 Map<String, Import> importMap = new HashMap<>();
234 Import anImport = new Import();
235 anImport.setFile(fileName);
236 importMap.put(key, anImport);
241 private void convertMetadata(String serviceTemplateName,
242 ServiceTemplate serviceTemplate,
243 ServiceTemplateReaderService readerService) {
244 Map<String, Object> metadataToConvert = (Map<String, Object>) readerService.getMetadata();
245 Map<String, String> finalMetadata = new HashMap<>();
247 if (MapUtils.isNotEmpty(metadataToConvert)) {
248 for (Map.Entry<String, Object> metadataEntry : metadataToConvert.entrySet()) {
249 if (Objects.isNull(metadataEntry.getValue()) ||
250 !(metadataEntry.getValue() instanceof String)) {
253 finalMetadata.put(metadataEntry.getKey(), (String) metadataEntry.getValue());
257 finalMetadata.put("template_name", getTemplateNameFromStName(serviceTemplateName));
258 serviceTemplate.setMetadata(finalMetadata);
261 private void convertNodeTypes(ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) {
262 Map<String, Object> nodeTypes = (Map<String, Object>) readerService.getNodeTypes();
263 if (MapUtils.isEmpty(nodeTypes)) {
267 for (Map.Entry<String, Object> nodeTypeEntry : nodeTypes.entrySet()) {
268 Optional<NodeType> nodeType = ToscaConverterUtil
269 .createObjectFromClass(nodeTypeEntry.getKey(), nodeTypeEntry.getValue(),
272 nodeType.ifPresent(nodeTypeValue -> DataModelUtil
273 .addNodeType(serviceTemplate, nodeTypeEntry.getKey(), nodeTypeValue));
277 private void convertTopologyTemplate(ServiceTemplate serviceTemplate,
278 ServiceTemplateReaderService readerService) {
280 convertInputs(serviceTemplate, readerService);
281 convertNodeTemplates(serviceTemplate, readerService);
282 convertOutputs(serviceTemplate, readerService);
283 convertSubstitutionMappings(serviceTemplate, readerService);
286 private void convertInputs(ServiceTemplate serviceTemplate,
287 ServiceTemplateReaderService readerService) {
288 Map<String, Object> inputs = readerService.getInputs();
289 addInputsOrOutputsToServiceTemplate(serviceTemplate, inputs, Constants.inputs);
292 private void convertOutputs(ServiceTemplate serviceTemplate,
293 ServiceTemplateReaderService readerService) {
294 Map<String, Object> outputs = readerService.getOutputs();
295 addInputsOrOutputsToServiceTemplate(serviceTemplate, outputs, Constants.outputs);
298 private void addInputsOrOutputsToServiceTemplate(ServiceTemplate serviceTemplate,
299 Map<String, Object> mapToConvert,
300 String inputsOrOutputs) {
301 if (MapUtils.isEmpty(mapToConvert)) {
305 for (Map.Entry<String, Object> entry : mapToConvert.entrySet()) {
306 Optional<ParameterDefinition> parameterDefinition =
307 ToscaConverterUtil.createObjectFromClass(
308 entry.getKey(), entry.getValue(), ParameterDefinition.class);
310 parameterDefinition.ifPresent(parameterDefinitionValue -> {
311 Optional<Object> defaultValue =
312 ToscaConverterUtil.getDefaultValue(entry.getValue(), parameterDefinition.get());
313 defaultValue.ifPresent(parameterDefinitionValue::set_default);
314 addToServiceTemplateAccordingToSection(
315 serviceTemplate, inputsOrOutputs, entry.getKey(), parameterDefinition.get());
320 private void addToServiceTemplateAccordingToSection(ServiceTemplate serviceTemplate,
321 String inputsOrOutputs,
323 ParameterDefinition parameterDefinition) {
324 switch (inputsOrOutputs) {
327 .addInputParameterToTopologyTemplate(serviceTemplate, parameterId, parameterDefinition);
331 .addOutputParameterToTopologyTemplate(serviceTemplate, parameterId, parameterDefinition);
335 private void convertNodeTemplates(ServiceTemplate serviceTemplate,
336 ServiceTemplateReaderService readerService) {
337 Map<String, Object> nodeTemplates = readerService.getNodeTemplates();
338 if (MapUtils.isEmpty(nodeTemplates)) {
342 for (Map.Entry<String, Object> nodeTemplateEntry : nodeTemplates.entrySet()) {
343 NodeTemplate nodeTemplate = convertNodeTemplate(nodeTemplateEntry.getValue());
344 DataModelUtil.addNodeTemplate(serviceTemplate, nodeTemplateEntry.getKey(), nodeTemplate);
348 private void convertSubstitutionMappings(ServiceTemplate serviceTemplate,
349 ServiceTemplateReaderService readerService) {
350 Map<String, Object> substitutionMappings = readerService.getSubstitutionMappings();
351 if (MapUtils.isEmpty(substitutionMappings)) {
354 SubstitutionMapping substitutionMapping = convertSubstitutionMappings(substitutionMappings);
355 DataModelUtil.addSubstitutionMapping(serviceTemplate, substitutionMapping);
358 private SubstitutionMapping convertSubstitutionMappings(Map<String, Object> substitutionMappings) {
359 SubstitutionMapping substitutionMapping = new SubstitutionMapping();
361 substitutionMapping.setNode_type((String) substitutionMappings.get(nodeType));
362 substitutionMapping.setCapabilities(
363 convertSubstitutionMappingsSections(capabilities, substitutionMappings.get(capabilities)));
364 substitutionMapping.setRequirements(
365 convertSubstitutionMappingsSections(requirements, substitutionMappings.get(requirements)));
367 return substitutionMapping;
370 private Map<String, List<String>> convertSubstitutionMappingsSections(String sectionName,
371 Object sectionToConvert) {
373 if(Objects.isNull(sectionToConvert)){
377 if(!(sectionToConvert instanceof Map)) {
378 throw new CoreException(
379 new SubstitutionMappingsConverterErrorBuilder(
380 sectionName, sectionToConvert.getClass().getSimpleName()).build());
383 return convertSection(sectionToConvert);
386 private Map<String, List<String>> convertSection(Object sectionToConvert) {
388 Map<String, Object> sectionAsMap = (Map<String, Object>)sectionToConvert;
389 Map<String, List<String>> convertedSection = new HashMap<>();
391 if (MapUtils.isEmpty(sectionAsMap)) {
395 for (Map.Entry<String, Object> entry : sectionAsMap.entrySet()) {
396 if (entry.getValue() instanceof List) {
397 convertedSection.put(entry.getKey(), (List<String>) entry.getValue());
401 return convertedSection;
404 private CsarFileTypes getFileType(String fileName) {
405 if (isMainServiceTemplate(fileName)) {
406 return CsarFileTypes.mainServiceTemplate;
407 } else if (isGlobalServiceTemplate(fileName)) {
408 return CsarFileTypes.globalServiceTemplate;
409 } else if (isDefinitions(fileName)) {
410 return CsarFileTypes.definitionsFile;
411 } else if (isMetadataFile(fileName)) {
412 return CsarFileTypes.toscaMetadata;
414 return CsarFileTypes.externalFile;
417 private Optional<Manifest> getCsarManifest(Map<String, byte[]> csarFiles) throws IOException {
418 Optional<byte[]> manifestContent = getManifestContent(csarFiles);
420 if (manifestContent.isPresent()) {
421 ByteArrayInputStream byteInputStream = new ByteArrayInputStream(manifestContent.get());
423 return Optional.of(new Manifest(byteInputStream));
426 return Optional.empty();
429 private NodeTemplate convertNodeTemplate(Object candidateNodeTemplate) {
430 NodeTemplate nodeTemplate = new NodeTemplate();
432 Map<String, Object> nodeTemplateAsMap = (Map<String, Object>) candidateNodeTemplate;
433 nodeTemplate.setArtifacts((Map<String, ArtifactDefinition>) nodeTemplateAsMap.get("artifacts"));
434 nodeTemplate.setAttributes((Map<String, Object>) nodeTemplateAsMap.get("attributes"));
435 nodeTemplate.setCopy((String) nodeTemplateAsMap.get("copy"));
436 nodeTemplate.setDescription((String) nodeTemplateAsMap.get("description"));
437 nodeTemplate.setDirectives((List<String>) nodeTemplateAsMap.get("directives"));
438 nodeTemplate.setInterfaces(
439 (Map<String, InterfaceDefinition>) nodeTemplateAsMap.get("interfaces"));
440 nodeTemplate.setNode_filter((NodeFilter) nodeTemplateAsMap.get("node_filter"));
441 nodeTemplate.setProperties((Map<String, Object>) nodeTemplateAsMap.get("properties"));
442 nodeTemplate.setRequirements(
443 (List<Map<String, RequirementAssignment>>) nodeTemplateAsMap.get("requirements"));
444 nodeTemplate.setType((String) nodeTemplateAsMap.get("type"));
445 nodeTemplate.setCapabilities(
446 convertCapabilities((Map<String, Object>) nodeTemplateAsMap.get("capabilities")));
451 private List<Map<String, CapabilityAssignment>> convertCapabilities(Map<String, Object> capabilities) {
452 List<Map<String, CapabilityAssignment>> convertedCapabilities = new ArrayList<>();
453 if (MapUtils.isEmpty(capabilities)) {
456 for (Map.Entry<String, Object> capabilityAssignmentEntry : capabilities.entrySet()) {
457 Map<String, CapabilityAssignment> tempMap = new HashMap<>();
458 Optional<CapabilityAssignment> capabilityAssignment = ToscaConverterUtil.createObjectFromClass
459 (capabilityAssignmentEntry.getKey(), capabilityAssignmentEntry.getValue(),
460 CapabilityAssignment.class);
462 capabilityAssignment.ifPresent(capabilityAssignmentValue -> {
463 tempMap.put(capabilityAssignmentEntry.getKey(), capabilityAssignmentValue);
464 convertedCapabilities.add(tempMap);
469 return convertedCapabilities;
473 private boolean isMainServiceTemplate(String fileName) {
474 return fileName.endsWith(mainStName);
477 private boolean isMetadataFile(String fileName) {
478 return fileName.equals(metadataFile);
481 private boolean isGlobalServiceTemplate(String fileName) {
482 return fileName.endsWith(globalStName);
485 private boolean isDefinitions(String fileName) {
486 return fileName.startsWith(definitionsDir);
489 private String getTemplateNameFromStName(String serviceTemplateName) {
490 String fileNameWithoutDirectories;
491 fileNameWithoutDirectories = getFileNameWithoutDirectories(serviceTemplateName);
492 return fileNameWithoutDirectories.split("ServiceTemplate")[0];
495 private String getFileNameWithoutDirectories(String serviceTemplateName) {
496 String fileNameWithoutDirectories;
497 if (serviceTemplateName.contains("/")) {
498 String[] split = serviceTemplateName.split("/");
499 fileNameWithoutDirectories = split[split.length - 1];
500 } else if (serviceTemplateName.contains(File.separator)) {
501 String[] split = serviceTemplateName.split(Pattern.quote(File.separator));
502 fileNameWithoutDirectories = split[split.length - 1];
504 fileNameWithoutDirectories = serviceTemplateName;
506 return fileNameWithoutDirectories;