1 package org.openecomp.core.impl;
3 import org.apache.commons.collections.MapUtils;
4 import org.apache.commons.lang3.StringUtils;
5 import org.openecomp.core.converter.ServiceTemplateReaderService;
6 import org.openecomp.core.converter.ToscaConverter;
7 import org.openecomp.core.converter.datatypes.Constants;
8 import org.openecomp.core.converter.datatypes.CsarFileTypes;
9 import org.openecomp.core.converter.errors.SubstitutionMappingsConverterErrorBuilder;
10 import org.openecomp.core.impl.services.ServiceTemplateReaderServiceImpl;
11 import org.openecomp.core.utilities.file.FileContentHandler;
12 import org.openecomp.core.utilities.json.JsonUtil;
13 import org.openecomp.sdc.common.errors.CoreException;
14 import org.openecomp.sdc.common.errors.ErrorCategory;
15 import org.openecomp.sdc.common.errors.ErrorCode;
16 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
17 import org.openecomp.sdc.tosca.datatypes.model.*;
18 import org.openecomp.sdc.tosca.services.DataModelUtil;
19 import org.openecomp.sdc.tosca.services.ToscaUtil;
20 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
21 import org.yaml.snakeyaml.error.YAMLException;
23 import java.io.ByteArrayInputStream;
25 import java.io.IOException;
27 import java.util.jar.Manifest;
28 import java.util.regex.Pattern;
30 import static org.openecomp.core.converter.datatypes.Constants.*;
31 import static org.openecomp.core.impl.GlobalSubstitutionServiceTemplate.GLOBAL_SUBSTITUTION_SERVICE_FILE_NAME;
33 public class ToscaConverterImpl implements ToscaConverter {
35 public ToscaConverterImpl() {
40 public ToscaServiceModel convert(FileContentHandler fileContentHandler)
42 Map<String, byte[]> csarFiles = new HashMap<>(fileContentHandler.getFiles());
43 ToscaServiceModel toscaServiceModel = new ToscaServiceModel();
44 Map<String, ServiceTemplate> serviceTemplates = new HashMap<>();
45 FileContentHandler artifacts = new FileContentHandler();
46 GlobalSubstitutionServiceTemplate gsst = new GlobalSubstitutionServiceTemplate();
47 for (Map.Entry<String, byte[]> fileEntry : csarFiles.entrySet()) {
48 CsarFileTypes fileType = getFileType(fileEntry.getKey());
50 case mainServiceTemplate:
51 handleServiceTemplate(mainStName, fileEntry.getKey(), csarFiles, serviceTemplates);
54 case globalServiceTemplate:
55 handleServiceTemplate(globalStName, fileEntry.getKey(), csarFiles, serviceTemplates);
60 getConcreteArtifactFileName(fileEntry.getKey()), fileEntry.getValue());
64 handleDefintionTemplate(fileEntry.getKey(), csarFiles, gsst);
68 handleMetadataFile(csarFiles);
69 updateToscaServiceModel(toscaServiceModel, serviceTemplates, artifacts, gsst, csarFiles);
70 return toscaServiceModel;
73 private void handleMetadataFile(Map<String, byte[]> csarFiles) {
74 byte[] bytes = csarFiles.remove(metadataFile);
76 csarFiles.put(metadataFile + ".original", bytes);
80 private void handleDefintionTemplate(String key, Map<String, byte[]> csarFiles,
81 GlobalSubstitutionServiceTemplate gsst) {
83 ServiceTemplateReaderService readerService = new ServiceTemplateReaderServiceImpl(csarFiles.get(key));
84 if (readerService == null) {
87 Object nodeTypes = readerService.getNodeTypes();
88 if (nodeTypes instanceof Map) {
89 Map<String, NodeType> nodeTypeMap = (Map<String, NodeType>) nodeTypes;
90 gsst.appendNodes(nodeTypeMap);
92 } catch (YAMLException ye) {
93 throw new CoreException(new ErrorCode.ErrorCodeBuilder()
94 .withMessage("Invalid YAML content in file " + key + ". reason - "
96 .withCategory(ErrorCategory.APPLICATION).build());
100 private String getConcreteArtifactFileName(String fileName){
101 int artifactIndex = fileName.indexOf(CsarFileTypes.Artifacts.name());
102 if(artifactIndex < 0){
106 int artifactDirectoryIndex =
107 artifactIndex + CsarFileTypes.Artifacts.name().length() + 1;
108 return fileName.substring(artifactDirectoryIndex);
111 private void updateToscaServiceModel(ToscaServiceModel toscaServiceModel,
112 Map<String, ServiceTemplate> serviceTemplates,
113 FileContentHandler externalFilesHandler,
114 GlobalSubstitutionServiceTemplate globalSubstitutionServiceTemplate,
115 Map<String, byte[]> csarFiles) {
116 Collection<ServiceTemplate> globalServiceTemplates =
117 GlobalTypesGenerator.getGlobalTypesServiceTemplate().values();
118 addGlobalServiceTemplates(globalServiceTemplates, serviceTemplates);
119 toscaServiceModel.setEntryDefinitionServiceTemplate(mainStName);
120 toscaServiceModel.setServiceTemplates(serviceTemplates);
121 externalFilesHandler.addFile(metadataFile + ".original",
122 csarFiles.get(metadataFile + ".original"));
123 toscaServiceModel.setArtifactFiles(externalFilesHandler);
125 if(MapUtils.isNotEmpty(globalSubstitutionServiceTemplate.getNode_types())) {
127 .put(GLOBAL_SUBSTITUTION_SERVICE_FILE_NAME, globalSubstitutionServiceTemplate);
131 private void addGlobalServiceTemplates(Collection<ServiceTemplate> globalServiceTemplates,
132 Map<String, ServiceTemplate> serviceTemplates) {
133 for (ServiceTemplate serviceTemplate : globalServiceTemplates) {
134 serviceTemplates.put(ToscaUtil.getServiceTemplateFileName(serviceTemplate), serviceTemplate);
138 private void handleServiceTemplate(String serviceTemplateName,
139 String fileName, Map<String, byte[]> csarFiles,
140 Map<String, ServiceTemplate> serviceTemplates) {
141 Optional<ServiceTemplate> serviceTemplate =
142 getServiceTemplateFromCsar(fileName, csarFiles);
143 serviceTemplate.ifPresent(
144 serviceTemplate1 -> addServiceTemplate(serviceTemplateName, serviceTemplate1,
148 private void addServiceTemplate(String serviceTemplateName,
149 ServiceTemplate serviceTemplate,
150 Map<String, ServiceTemplate> serviceTemplates) {
151 serviceTemplates.put(serviceTemplateName, serviceTemplate);
154 private Optional<byte[]> getManifestContent(Map<String, byte[]> csarFiles) {
155 for (Map.Entry<String, byte[]> csarFileEntry : csarFiles.entrySet()) {
156 if (csarFileEntry.getKey().contains(manifestFileName)) {
157 return Optional.of(csarFileEntry.getValue());
161 return Optional.empty();
164 private Optional<ServiceTemplate> getServiceTemplateFromCsar(String fileName,
165 Map<String, byte[]> csarFiles) {
166 byte[] fileContent = csarFiles.get(fileName);
167 ServiceTemplate serviceTemplate = convertServiceTemplate(fileName, fileContent);
169 return Optional.of(serviceTemplate);
172 private ServiceTemplate convertServiceTemplate(String serviceTemplateName,
173 byte[] fileContent) {
174 ServiceTemplate serviceTemplate = new ServiceTemplate();
176 ServiceTemplateReaderService readerService =
177 new ServiceTemplateReaderServiceImpl(fileContent);
178 convertMetadata(serviceTemplateName, serviceTemplate, readerService);
179 convertToscaVersion(serviceTemplate, readerService);
180 convertImports(serviceTemplate);
181 convertNodeTypes(serviceTemplate, readerService);
182 convertTopologyTemplate(serviceTemplate, readerService);
184 } catch (YAMLException ye) {
185 throw new CoreException(new ErrorCode.ErrorCodeBuilder()
186 .withMessage("Invalid YAML content in file" + serviceTemplateName + ". reason - "
188 .withCategory(ErrorCategory.APPLICATION).build());
192 return serviceTemplate;
195 private void convertToscaVersion(ServiceTemplate serviceTemplate,
196 ServiceTemplateReaderService readerService) {
197 Object toscaVersion = readerService.getToscaVersion();
198 serviceTemplate.setTosca_definitions_version((String) toscaVersion);
201 private void convertImports(ServiceTemplate serviceTemplate) {
202 serviceTemplate.setImports(new ArrayList<>());
203 serviceTemplate.getImports()
204 .add(createImportMap(openecompHeatIndex, "openecomp-heat/_index.yml"));
205 serviceTemplate.getImports().add(createImportMap(globalSubstitution, globalStName));
209 private Map<String, Import> createImportMap(String key, String fileName) {
210 Map<String, Import> importMap = new HashMap<>();
211 Import anImport = new Import();
212 anImport.setFile(fileName);
213 importMap.put(key, anImport);
218 private void convertMetadata(String serviceTemplateName,
219 ServiceTemplate serviceTemplate,
220 ServiceTemplateReaderService readerService) {
221 Map<String, Object> metadataToConvert = (Map<String, Object>) readerService.getMetadata();
222 Map<String, String> finalMetadata = new HashMap<>();
224 if (MapUtils.isNotEmpty(metadataToConvert)) {
225 for (Map.Entry<String, Object> metadataEntry : metadataToConvert.entrySet()) {
226 if (Objects.isNull(metadataEntry.getValue()) ||
227 !(metadataEntry.getValue() instanceof String)) {
230 finalMetadata.put(metadataEntry.getKey(), (String) metadataEntry.getValue());
234 finalMetadata.put("template_name", getTemplateNameFromStName(serviceTemplateName));
235 serviceTemplate.setMetadata(finalMetadata);
238 private void convertNodeTypes(ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) {
239 Map<String, Object> nodeTypes = (Map<String, Object>) readerService.getNodeTypes();
240 if (MapUtils.isEmpty(nodeTypes)) {
244 for (Map.Entry<String, Object> nodeTypeEntry : nodeTypes.entrySet()) {
246 .addNodeType(serviceTemplate, nodeTypeEntry.getKey(),
247 (NodeType) createObjectFromClass(nodeTypeEntry.getKey(), nodeTypeEntry.getValue(),
252 private void convertTopologyTemplate(ServiceTemplate serviceTemplate,
253 ServiceTemplateReaderService readerService) {
255 convertInputs(serviceTemplate, readerService);
256 convertNodeTemplates(serviceTemplate, readerService);
257 convertOutputs(serviceTemplate, readerService);
258 convertSubstitutionMappings(serviceTemplate, readerService);
261 private void convertInputs(ServiceTemplate serviceTemplate,
262 ServiceTemplateReaderService readerService) {
263 Map<String, Object> inputs = readerService.getInputs();
264 addInputsOrOutputsToServiceTemplate(serviceTemplate, inputs, Constants.inputs);
267 private void convertOutputs(ServiceTemplate serviceTemplate,
268 ServiceTemplateReaderService readerService) {
269 Map<String, Object> outputs = readerService.getOutputs();
270 addInputsOrOutputsToServiceTemplate(serviceTemplate, outputs, Constants.outputs);
273 private void addInputsOrOutputsToServiceTemplate(ServiceTemplate serviceTemplate,
274 Map<String, Object> mapToConvert,
275 String inputsOrOutputs) {
276 if (MapUtils.isEmpty(mapToConvert)) {
280 for (Map.Entry<String, Object> entry : mapToConvert.entrySet()) {
281 ParameterDefinition parameterDefinition =
282 (ParameterDefinition) createObjectFromClass(
283 entry.getKey(), entry.getValue(), ParameterDefinition.class);
284 addToServiceTemplateAccordingToSection(
285 serviceTemplate, inputsOrOutputs, entry.getKey(), parameterDefinition);
289 private void addToServiceTemplateAccordingToSection(ServiceTemplate serviceTemplate,
290 String inputsOrOutputs,
292 ParameterDefinition parameterDefinition) {
293 switch (inputsOrOutputs) {
296 .addInputParameterToTopologyTemplate(serviceTemplate, parameterId, parameterDefinition);
300 .addOutputParameterToTopologyTemplate(serviceTemplate, parameterId, parameterDefinition);
304 private void convertNodeTemplates(ServiceTemplate serviceTemplate,
305 ServiceTemplateReaderService readerService) {
306 Map<String, Object> nodeTemplates = readerService.getNodeTemplates();
307 if (MapUtils.isEmpty(nodeTemplates)) {
311 for (Map.Entry<String, Object> nodeTemplateEntry : nodeTemplates.entrySet()) {
312 NodeTemplate nodeTemplate = convertNodeTemplate(nodeTemplateEntry.getValue());
313 DataModelUtil.addNodeTemplate(serviceTemplate, nodeTemplateEntry.getKey(), nodeTemplate);
317 private void convertSubstitutionMappings(ServiceTemplate serviceTemplate,
318 ServiceTemplateReaderService readerService) {
319 Map<String, Object> substitutionMappings = readerService.getSubstitutionMappings();
320 if (MapUtils.isEmpty(substitutionMappings)) {
323 SubstitutionMapping substitutionMapping = convertSubstitutionMappings(substitutionMappings);
324 DataModelUtil.addSubstitutionMapping(serviceTemplate, substitutionMapping);
327 private SubstitutionMapping convertSubstitutionMappings(Map<String, Object> substitutionMappings) {
328 SubstitutionMapping substitutionMapping = new SubstitutionMapping();
330 substitutionMapping.setNode_type((String) substitutionMappings.get(nodeType));
331 setSubstitutionMappingsSection(
332 capabilities, substitutionMapping,
333 convertSubstitutionMappingsSections(capabilities, substitutionMappings.get(capabilities)));
334 setSubstitutionMappingsSection(
335 requirements, substitutionMapping,
336 convertSubstitutionMappingsSections(requirements, substitutionMappings.get(requirements)));
338 return substitutionMapping;
341 private void setSubstitutionMappingsSection(String sectionName,
342 SubstitutionMapping substitutionMapping,
343 Map<String, List<String>> convertedSection) {
344 if(MapUtils.isEmpty(convertedSection)
345 || StringUtils.isEmpty(sectionName)
346 || Objects.isNull(substitutionMapping)){
350 switch (sectionName){
352 substitutionMapping.setRequirements(convertedSection);
355 substitutionMapping.setCapabilities(convertedSection);
360 private Map<String, List<String>> convertSubstitutionMappingsSections(String sectionName,
361 Object sectionToConvert) {
362 if(Objects.isNull(sectionToConvert)){
366 if(!(sectionToConvert instanceof Map)){
367 throw new CoreException(
368 new SubstitutionMappingsConverterErrorBuilder(
369 sectionName, "Map").build());
372 return convertSubstitutionMappongsSection((Map<String, Object>) sectionToConvert);
375 private Map<String, List<String>> convertSubstitutionMappongsSection(Map<String, Object> sectionToConvert) {
376 Map<String, List<String>> convertedSection = new HashMap<>();
377 if (MapUtils.isEmpty(sectionToConvert)) {
381 for (Map.Entry<String, Object> entry : sectionToConvert.entrySet()) {
382 if (entry.getValue() instanceof List) {
383 convertedSection.put(entry.getKey(), (List<String>) entry.getValue());
387 return convertedSection;
390 private CsarFileTypes getFileType(String fileName) {
391 if (isMainServiceTemplate(fileName)) {
392 return CsarFileTypes.mainServiceTemplate;
393 } else if (isGlobalServiceTemplate(fileName)) {
394 return CsarFileTypes.globalServiceTemplate;
395 } else if (isDefinitions(fileName)) {
396 return CsarFileTypes.definitionsFile;
397 } else if (isMetadataFile(fileName)) {
398 return CsarFileTypes.toscaMetadata;
400 return CsarFileTypes.externalFile;
403 private Optional<Manifest> getCsarManifest(Map<String, byte[]> csarFiles) throws IOException {
404 Optional<byte[]> manifestContent = getManifestContent(csarFiles);
406 if (manifestContent.isPresent()) {
407 ByteArrayInputStream byteInputStream = new ByteArrayInputStream(manifestContent.get());
409 return Optional.of(new Manifest(byteInputStream));
412 return Optional.empty();
415 private NodeTemplate convertNodeTemplate(Object candidateNodeTemplate) {
416 NodeTemplate nodeTemplate = new NodeTemplate();
418 Map<String, Object> nodeTemplateAsMap = (Map<String, Object>) candidateNodeTemplate;
419 nodeTemplate.setArtifacts((Map<String, ArtifactDefinition>) nodeTemplateAsMap.get("artifacts"));
420 nodeTemplate.setAttributes((Map<String, Object>) nodeTemplateAsMap.get("attributes"));
421 nodeTemplate.setCopy((String) nodeTemplateAsMap.get("copy"));
422 nodeTemplate.setDescription((String) nodeTemplateAsMap.get("description"));
423 nodeTemplate.setDirectives((List<String>) nodeTemplateAsMap.get("directives"));
424 nodeTemplate.setInterfaces(
425 (Map<String, InterfaceDefinition>) nodeTemplateAsMap.get("interfaces"));
426 nodeTemplate.setNode_filter((NodeFilter) nodeTemplateAsMap.get("node_filter"));
427 nodeTemplate.setProperties((Map<String, Object>) nodeTemplateAsMap.get("properties"));
428 nodeTemplate.setRequirements(
429 (List<Map<String, RequirementAssignment>>) nodeTemplateAsMap.get("requirements"));
430 nodeTemplate.setType((String) nodeTemplateAsMap.get("type"));
431 nodeTemplate.setCapabilities(
432 convertCapabilities((Map<String, Object>) nodeTemplateAsMap.get("capabilities")));
437 private List<Map<String, CapabilityAssignment>> convertCapabilities(Map<String, Object> capabilities) {
438 List<Map<String, CapabilityAssignment>> convertedCapabilities = new ArrayList<>();
439 if (MapUtils.isEmpty(capabilities)) {
442 for (Map.Entry<String, Object> capabilityAssignmentEntry : capabilities.entrySet()) {
443 Map<String, CapabilityAssignment> tempMap = new HashMap<>();
444 tempMap.put(capabilityAssignmentEntry.getKey(),
445 (CapabilityAssignment) createObjectFromClass
446 (capabilityAssignmentEntry.getKey(), capabilityAssignmentEntry.getValue(), CapabilityAssignment.class));
447 convertedCapabilities.add(tempMap);
449 return convertedCapabilities;
452 private Object createObjectFromClass(String nodeTypeId,
453 Object objectCandidate,
454 Class classToCreate) {
456 return JsonUtil.json2Object(objectCandidate.toString(), classToCreate);
457 } catch (Exception e) {
458 //todo - return error to user?
459 throw new CoreException(new ErrorCode.ErrorCodeBuilder()
460 .withCategory(ErrorCategory.APPLICATION)
461 .withMessage("Can't create " + classToCreate.getSimpleName() + " from " +
462 nodeTypeId).build());
466 private boolean isMainServiceTemplate(String fileName) {
467 return fileName.endsWith(mainStName);
470 private boolean isMetadataFile(String fileName) {
471 return fileName.equals(metadataFile);
474 private boolean isGlobalServiceTemplate(String fileName) {
475 return fileName.endsWith(globalStName);
478 private boolean isDefinitions(String fileName) {
479 return fileName.startsWith(definitionsDir);
482 private String getTemplateNameFromStName(String serviceTemplateName) {
483 String fileNameWithoutDirectories;
484 fileNameWithoutDirectories = getFileNameWithoutDirectories(serviceTemplateName);
485 return fileNameWithoutDirectories.split("ServiceTemplate")[0];
488 private String getFileNameWithoutDirectories(String serviceTemplateName) {
489 String fileNameWithoutDirectories;
490 if (serviceTemplateName.contains("/")) {
491 String[] split = serviceTemplateName.split("/");
492 fileNameWithoutDirectories = split[split.length - 1];
493 } else if (serviceTemplateName.contains(File.separator)) {
494 String[] split = serviceTemplateName.split(Pattern.quote(File.separator));
495 fileNameWithoutDirectories = split[split.length - 1];
497 fileNameWithoutDirectories = serviceTemplateName;
499 return fileNameWithoutDirectories;