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.impl.services.ServiceTemplateReaderServiceImpl;
9 import org.openecomp.core.utilities.file.FileContentHandler;
10 import org.openecomp.core.utilities.json.JsonUtil;
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.*;
16 import org.openecomp.sdc.tosca.services.DataModelUtil;
17 import org.openecomp.sdc.tosca.services.ToscaUtil;
18 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
19 import org.yaml.snakeyaml.error.YAMLException;
21 import java.io.ByteArrayInputStream;
23 import java.io.IOException;
25 import java.util.jar.Manifest;
26 import java.util.regex.Pattern;
28 import static org.openecomp.core.converter.datatypes.Constants.*;
29 import static org.openecomp.core.impl.GlobalSubstitutionServiceTemplate.GLOBAL_SUBSTITUTION_SERVICE_FILE_NAME;
31 public class ToscaConverterImpl implements ToscaConverter {
33 public ToscaConverterImpl() {
38 public ToscaServiceModel convert(FileContentHandler fileContentHandler)
40 Map<String, byte[]> csarFiles = new HashMap<>(fileContentHandler.getFiles());
41 ToscaServiceModel toscaServiceModel = new ToscaServiceModel();
42 Map<String, ServiceTemplate> serviceTemplates = new HashMap<>();
43 FileContentHandler artifacts = new FileContentHandler();
44 GlobalSubstitutionServiceTemplate gsst = new GlobalSubstitutionServiceTemplate();
45 for (Map.Entry<String, byte[]> fileEntry : csarFiles.entrySet()) {
46 CsarFileTypes fileType = getFileType(fileEntry.getKey());
48 case mainServiceTemplate:
49 handleServiceTemplate(mainStName, fileEntry.getKey(), csarFiles, serviceTemplates);
52 case globalServiceTemplate:
53 handleServiceTemplate(globalStName, fileEntry.getKey(), csarFiles, serviceTemplates);
58 getConcreteArtifactFileName(fileEntry.getKey()), fileEntry.getValue());
62 handleDefintionTemplate(fileEntry.getKey(), csarFiles, gsst);
66 handleMetadataFile(csarFiles);
67 updateToscaServiceModel(toscaServiceModel, serviceTemplates, artifacts, gsst, csarFiles);
68 return toscaServiceModel;
71 private void handleMetadataFile(Map<String, byte[]> csarFiles) {
72 byte[] bytes = csarFiles.remove(metadataFile);
74 csarFiles.put(metadataFile + ".original", bytes);
78 private void handleDefintionTemplate(String key, Map<String, byte[]> csarFiles,
79 GlobalSubstitutionServiceTemplate gsst) {
81 ServiceTemplateReaderService readerService = new ServiceTemplateReaderServiceImpl(csarFiles.get(key));
82 if (readerService == null) {
85 Object nodeTypes = readerService.getNodeTypes();
86 if (nodeTypes instanceof Map) {
87 Map<String, NodeType> nodeTypeMap = (Map<String, NodeType>) nodeTypes;
88 gsst.appendNodes(nodeTypeMap);
90 } catch (YAMLException ye) {
91 throw new CoreException(new ErrorCode.ErrorCodeBuilder()
92 .withMessage("Invalid YAML content in file " + key + ". reason - "
94 .withCategory(ErrorCategory.APPLICATION).build());
98 private String getConcreteArtifactFileName(String fileName){
99 int artifactIndex = fileName.indexOf(CsarFileTypes.Artifacts.name());
100 if(artifactIndex < 0){
104 int artifactDirectoryIndex =
105 artifactIndex + CsarFileTypes.Artifacts.name().length() + 1;
106 return fileName.substring(artifactDirectoryIndex);
109 private void updateToscaServiceModel(ToscaServiceModel toscaServiceModel,
110 Map<String, ServiceTemplate> serviceTemplates,
111 FileContentHandler externalFilesHandler,
112 GlobalSubstitutionServiceTemplate globalSubstitutionServiceTemplate,
113 Map<String, byte[]> csarFiles) {
114 Collection<ServiceTemplate> globalServiceTemplates =
115 GlobalTypesGenerator.getGlobalTypesServiceTemplate().values();
116 addGlobalServiceTemplates(globalServiceTemplates, serviceTemplates);
117 toscaServiceModel.setEntryDefinitionServiceTemplate(mainStName);
118 toscaServiceModel.setServiceTemplates(serviceTemplates);
119 externalFilesHandler.addFile(metadataFile + ".original",
120 csarFiles.get(metadataFile + ".original"));
121 toscaServiceModel.setArtifactFiles(externalFilesHandler);
123 if(MapUtils.isNotEmpty(globalSubstitutionServiceTemplate.getNode_types())) {
125 .put(GLOBAL_SUBSTITUTION_SERVICE_FILE_NAME, globalSubstitutionServiceTemplate);
129 private void addGlobalServiceTemplates(Collection<ServiceTemplate> globalServiceTemplates,
130 Map<String, ServiceTemplate> serviceTemplates) {
131 for (ServiceTemplate serviceTemplate : globalServiceTemplates) {
132 serviceTemplates.put(ToscaUtil.getServiceTemplateFileName(serviceTemplate), serviceTemplate);
136 private void handleServiceTemplate(String serviceTemplateName,
137 String fileName, Map<String, byte[]> csarFiles,
138 Map<String, ServiceTemplate> serviceTemplates) {
139 Optional<ServiceTemplate> serviceTemplate =
140 getServiceTemplateFromCsar(fileName, csarFiles);
141 serviceTemplate.ifPresent(
142 serviceTemplateValue -> addServiceTemplate(serviceTemplateName, serviceTemplateValue,
146 private void addServiceTemplate(String serviceTemplateName,
147 ServiceTemplate serviceTemplate,
148 Map<String, ServiceTemplate> serviceTemplates) {
149 serviceTemplates.put(serviceTemplateName, serviceTemplate);
152 private Optional<byte[]> getManifestContent(Map<String, byte[]> csarFiles) {
153 for (Map.Entry<String, byte[]> csarFileEntry : csarFiles.entrySet()) {
154 if (csarFileEntry.getKey().contains(manifestFileName)) {
155 return Optional.of(csarFileEntry.getValue());
159 return Optional.empty();
162 private Optional<ServiceTemplate> getServiceTemplateFromCsar(String fileName,
163 Map<String, byte[]> csarFiles) {
164 byte[] fileContent = csarFiles.get(fileName);
165 ServiceTemplate serviceTemplate = convertServiceTemplate(fileName, fileContent);
167 return Optional.of(serviceTemplate);
170 private ServiceTemplate convertServiceTemplate(String serviceTemplateName,
171 byte[] fileContent) {
172 ServiceTemplate serviceTemplate = new ServiceTemplate();
174 ServiceTemplateReaderService readerService =
175 new ServiceTemplateReaderServiceImpl(fileContent);
176 convertMetadata(serviceTemplateName, serviceTemplate, readerService);
177 convertToscaVersion(serviceTemplate, readerService);
178 convertImports(serviceTemplate);
179 convertNodeTypes(serviceTemplate, readerService);
180 convertTopologyTemplate(serviceTemplate, readerService);
182 } catch (YAMLException ye) {
183 throw new CoreException(new ErrorCode.ErrorCodeBuilder()
184 .withMessage("Invalid YAML content in file" + serviceTemplateName + ". reason - "
186 .withCategory(ErrorCategory.APPLICATION).build());
190 return serviceTemplate;
193 private void convertToscaVersion(ServiceTemplate serviceTemplate,
194 ServiceTemplateReaderService readerService) {
195 Object toscaVersion = readerService.getToscaVersion();
196 serviceTemplate.setTosca_definitions_version((String) toscaVersion);
199 private void convertImports(ServiceTemplate serviceTemplate) {
200 serviceTemplate.setImports(new ArrayList<>());
201 serviceTemplate.getImports()
202 .add(createImportMap(openecompHeatIndex, "openecomp-heat/_index.yml"));
203 serviceTemplate.getImports().add(createImportMap(globalSubstitution, globalStName));
207 private Map<String, Import> createImportMap(String key, String fileName) {
208 Map<String, Import> importMap = new HashMap<>();
209 Import anImport = new Import();
210 anImport.setFile(fileName);
211 importMap.put(key, anImport);
216 private void convertMetadata(String serviceTemplateName,
217 ServiceTemplate serviceTemplate,
218 ServiceTemplateReaderService readerService) {
219 Map<String, Object> metadataToConvert = (Map<String, Object>) readerService.getMetadata();
220 Map<String, String> finalMetadata = new HashMap<>();
222 if (MapUtils.isNotEmpty(metadataToConvert)) {
223 for (Map.Entry<String, Object> metadataEntry : metadataToConvert.entrySet()) {
224 if (Objects.isNull(metadataEntry.getValue()) ||
225 !(metadataEntry.getValue() instanceof String)) {
228 finalMetadata.put(metadataEntry.getKey(), (String) metadataEntry.getValue());
232 finalMetadata.put("template_name", getTemplateNameFromStName(serviceTemplateName));
233 serviceTemplate.setMetadata(finalMetadata);
236 private void convertNodeTypes(ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) {
237 Map<String, Object> nodeTypes = (Map<String, Object>) readerService.getNodeTypes();
238 if (MapUtils.isEmpty(nodeTypes)) {
242 for (Map.Entry<String, Object> nodeTypeEntry : nodeTypes.entrySet()) {
243 Optional<NodeType> nodeType = ToscaConverterUtil
244 .createObjectFromClass(nodeTypeEntry.getKey(), nodeTypeEntry.getValue(),
247 nodeType.ifPresent(nodeTypeValue -> DataModelUtil
248 .addNodeType(serviceTemplate, nodeTypeEntry.getKey(), nodeTypeValue));
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 Optional<ParameterDefinition> parameterDefinition =
282 ToscaConverterUtil.createObjectFromClass(
283 entry.getKey(), entry.getValue(), ParameterDefinition.class);
285 parameterDefinition.ifPresent(parameterDefinitionValue -> {
286 handleDefaultValue(entry.getValue(), parameterDefinition.get());
287 addToServiceTemplateAccordingToSection(
288 serviceTemplate, inputsOrOutputs, entry.getKey(), parameterDefinition.get());
293 private void handleDefaultValue(Object entryValue,
294 ParameterDefinition parameterDefinition) {
295 if(!(entryValue instanceof Map)
296 || Objects.isNull(parameterDefinition)){
300 Object defaultValue = ((Map) entryValue).get("default");
301 if(Objects.nonNull(defaultValue)) {
302 parameterDefinition.set_default(defaultValue);
306 private void addToServiceTemplateAccordingToSection(ServiceTemplate serviceTemplate,
307 String inputsOrOutputs,
309 ParameterDefinition parameterDefinition) {
310 switch (inputsOrOutputs) {
313 .addInputParameterToTopologyTemplate(serviceTemplate, parameterId, parameterDefinition);
317 .addOutputParameterToTopologyTemplate(serviceTemplate, parameterId, parameterDefinition);
321 private void convertNodeTemplates(ServiceTemplate serviceTemplate,
322 ServiceTemplateReaderService readerService) {
323 Map<String, Object> nodeTemplates = readerService.getNodeTemplates();
324 if (MapUtils.isEmpty(nodeTemplates)) {
328 for (Map.Entry<String, Object> nodeTemplateEntry : nodeTemplates.entrySet()) {
329 NodeTemplate nodeTemplate = convertNodeTemplate(nodeTemplateEntry.getValue());
330 DataModelUtil.addNodeTemplate(serviceTemplate, nodeTemplateEntry.getKey(), nodeTemplate);
334 private void convertSubstitutionMappings(ServiceTemplate serviceTemplate,
335 ServiceTemplateReaderService readerService) {
336 Map<String, Object> substitutionMappings = readerService.getSubstitutionMappings();
337 if (MapUtils.isEmpty(substitutionMappings)) {
340 SubstitutionMapping substitutionMapping = convertSubstitutionMappings(substitutionMappings);
341 DataModelUtil.addSubstitutionMapping(serviceTemplate, substitutionMapping);
344 private SubstitutionMapping convertSubstitutionMappings(Map<String, Object> substitutionMappings) {
345 SubstitutionMapping substitutionMapping = new SubstitutionMapping();
347 substitutionMapping.setNode_type((String) substitutionMappings.get(nodeType));
348 substitutionMapping.setCapabilities(
349 convertSubstitutionMappingsSections((Map<String, Object>) substitutionMappings.get(capabilities)));
350 substitutionMapping.setRequirements(
351 convertSubstitutionMappingsSections((Map<String, Object>) substitutionMappings.get(requirements)));
353 return substitutionMapping;
356 private Map<String, List<String>> convertSubstitutionMappingsSections(
357 Map<String, Object> sectionToConvert) {
358 Map<String, List<String>> convertedSection = new HashMap<>();
359 if (MapUtils.isEmpty(sectionToConvert)) {
363 for (Map.Entry<String, Object> entry : sectionToConvert.entrySet()) {
364 if (entry.getValue() instanceof List) {
365 convertedSection.put(entry.getKey(), (List<String>) entry.getValue());
369 return convertedSection;
372 private CsarFileTypes getFileType(String fileName) {
373 if (isMainServiceTemplate(fileName)) {
374 return CsarFileTypes.mainServiceTemplate;
375 } else if (isGlobalServiceTemplate(fileName)) {
376 return CsarFileTypes.globalServiceTemplate;
377 } else if (isDefinitions(fileName)) {
378 return CsarFileTypes.definitionsFile;
379 } else if (isMetadataFile(fileName)) {
380 return CsarFileTypes.toscaMetadata;
382 return CsarFileTypes.externalFile;
385 private Optional<Manifest> getCsarManifest(Map<String, byte[]> csarFiles) throws IOException {
386 Optional<byte[]> manifestContent = getManifestContent(csarFiles);
388 if (manifestContent.isPresent()) {
389 ByteArrayInputStream byteInputStream = new ByteArrayInputStream(manifestContent.get());
391 return Optional.of(new Manifest(byteInputStream));
394 return Optional.empty();
397 private NodeTemplate convertNodeTemplate(Object candidateNodeTemplate) {
398 NodeTemplate nodeTemplate = new NodeTemplate();
400 Map<String, Object> nodeTemplateAsMap = (Map<String, Object>) candidateNodeTemplate;
401 nodeTemplate.setArtifacts((Map<String, ArtifactDefinition>) nodeTemplateAsMap.get("artifacts"));
402 nodeTemplate.setAttributes((Map<String, Object>) nodeTemplateAsMap.get("attributes"));
403 nodeTemplate.setCopy((String) nodeTemplateAsMap.get("copy"));
404 nodeTemplate.setDescription((String) nodeTemplateAsMap.get("description"));
405 nodeTemplate.setDirectives((List<String>) nodeTemplateAsMap.get("directives"));
406 nodeTemplate.setInterfaces(
407 (Map<String, InterfaceDefinition>) nodeTemplateAsMap.get("interfaces"));
408 nodeTemplate.setNode_filter((NodeFilter) nodeTemplateAsMap.get("node_filter"));
409 nodeTemplate.setProperties((Map<String, Object>) nodeTemplateAsMap.get("properties"));
410 nodeTemplate.setRequirements(
411 (List<Map<String, RequirementAssignment>>) nodeTemplateAsMap.get("requirements"));
412 nodeTemplate.setType((String) nodeTemplateAsMap.get("type"));
413 nodeTemplate.setCapabilities(
414 convertCapabilities((Map<String, Object>) nodeTemplateAsMap.get("capabilities")));
419 private List<Map<String, CapabilityAssignment>> convertCapabilities(Map<String, Object> capabilities) {
420 List<Map<String, CapabilityAssignment>> convertedCapabilities = new ArrayList<>();
421 if (MapUtils.isEmpty(capabilities)) {
424 for (Map.Entry<String, Object> capabilityAssignmentEntry : capabilities.entrySet()) {
425 Map<String, CapabilityAssignment> tempMap = new HashMap<>();
426 Optional<CapabilityAssignment> capabilityAssignment = ToscaConverterUtil.createObjectFromClass
427 (capabilityAssignmentEntry.getKey(), capabilityAssignmentEntry.getValue(),
428 CapabilityAssignment.class);
430 capabilityAssignment.ifPresent(capabilityAssignmentValue -> {
431 tempMap.put(capabilityAssignmentEntry.getKey(), capabilityAssignmentValue);
432 convertedCapabilities.add(tempMap);
437 return convertedCapabilities;
441 private boolean isMainServiceTemplate(String fileName) {
442 return fileName.endsWith(mainStName);
445 private boolean isMetadataFile(String fileName) {
446 return fileName.equals(metadataFile);
449 private boolean isGlobalServiceTemplate(String fileName) {
450 return fileName.endsWith(globalStName);
453 private boolean isDefinitions(String fileName) {
454 return fileName.startsWith(definitionsDir);
457 private String getTemplateNameFromStName(String serviceTemplateName) {
458 String fileNameWithoutDirectories;
459 fileNameWithoutDirectories = getFileNameWithoutDirectories(serviceTemplateName);
460 return fileNameWithoutDirectories.split("ServiceTemplate")[0];
463 private String getFileNameWithoutDirectories(String serviceTemplateName) {
464 String fileNameWithoutDirectories;
465 if (serviceTemplateName.contains("/")) {
466 String[] split = serviceTemplateName.split("/");
467 fileNameWithoutDirectories = split[split.length - 1];
468 } else if (serviceTemplateName.contains(File.separator)) {
469 String[] split = serviceTemplateName.split(Pattern.quote(File.separator));
470 fileNameWithoutDirectories = split[split.length - 1];
472 fileNameWithoutDirectories = serviceTemplateName;
474 return fileNameWithoutDirectories;