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.sdc.common.errors.CoreException;
13 import org.openecomp.sdc.common.errors.ErrorCategory;
14 import org.openecomp.sdc.common.errors.ErrorCode;
15 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
16 import org.openecomp.sdc.tosca.datatypes.model.*;
17 import org.openecomp.sdc.tosca.services.DataModelUtil;
18 import org.openecomp.sdc.tosca.services.ToscaUtil;
19 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
20 import org.yaml.snakeyaml.error.YAMLException;
22 import java.io.ByteArrayInputStream;
24 import java.io.IOException;
26 import java.util.jar.Manifest;
27 import java.util.regex.Pattern;
29 import static org.openecomp.core.converter.datatypes.Constants.*;
30 import static org.openecomp.core.impl.GlobalSubstitutionServiceTemplate.GLOBAL_SUBSTITUTION_SERVICE_FILE_NAME;
32 public class ToscaConverterImpl implements ToscaConverter {
34 public ToscaConverterImpl() {
39 public ToscaServiceModel convert(FileContentHandler fileContentHandler)
41 Map<String, byte[]> csarFiles = new HashMap<>(fileContentHandler.getFiles());
42 ToscaServiceModel toscaServiceModel = new ToscaServiceModel();
43 Map<String, ServiceTemplate> serviceTemplates = new HashMap<>();
44 FileContentHandler artifacts = new FileContentHandler();
45 GlobalSubstitutionServiceTemplate gsst = new GlobalSubstitutionServiceTemplate();
46 for (Map.Entry<String, byte[]> fileEntry : csarFiles.entrySet()) {
47 CsarFileTypes fileType = getFileType(fileEntry.getKey());
49 case mainServiceTemplate:
50 handleServiceTemplate(mainStName, fileEntry.getKey(), csarFiles, serviceTemplates);
53 case globalServiceTemplate:
54 handleServiceTemplate(globalStName, fileEntry.getKey(), csarFiles, serviceTemplates);
59 getConcreteArtifactFileName(fileEntry.getKey()), fileEntry.getValue());
63 handleDefintionTemplate(fileEntry.getKey(), csarFiles, gsst);
67 handleMetadataFile(csarFiles);
68 updateToscaServiceModel(toscaServiceModel, serviceTemplates, artifacts, gsst, csarFiles);
69 return toscaServiceModel;
72 private void handleMetadataFile(Map<String, byte[]> csarFiles) {
73 byte[] bytes = csarFiles.remove(metadataFile);
75 csarFiles.put(metadataFile + ".original", bytes);
79 private void handleDefintionTemplate(String key, Map<String, byte[]> csarFiles,
80 GlobalSubstitutionServiceTemplate gsst) {
82 ServiceTemplateReaderService readerService = new ServiceTemplateReaderServiceImpl(csarFiles.get(key));
83 if (readerService == null) {
86 Object nodeTypes = readerService.getNodeTypes();
87 if (nodeTypes instanceof Map) {
88 Map<String, NodeType> nodeTypeMap = (Map<String, NodeType>) nodeTypes;
89 gsst.appendNodes(nodeTypeMap);
91 } catch (YAMLException ye) {
92 throw new CoreException(new ErrorCode.ErrorCodeBuilder()
93 .withMessage("Invalid YAML content in file " + key + ". reason - "
95 .withCategory(ErrorCategory.APPLICATION).build());
99 private String getConcreteArtifactFileName(String fileName){
100 int artifactIndex = fileName.indexOf(CsarFileTypes.Artifacts.name());
101 if(artifactIndex < 0){
105 int artifactDirectoryIndex =
106 artifactIndex + CsarFileTypes.Artifacts.name().length() + 1;
107 return fileName.substring(artifactDirectoryIndex);
110 private void updateToscaServiceModel(ToscaServiceModel toscaServiceModel,
111 Map<String, ServiceTemplate> serviceTemplates,
112 FileContentHandler externalFilesHandler,
113 GlobalSubstitutionServiceTemplate globalSubstitutionServiceTemplate,
114 Map<String, byte[]> csarFiles) {
115 Collection<ServiceTemplate> globalServiceTemplates =
116 GlobalTypesGenerator.getGlobalTypesServiceTemplate().values();
117 addGlobalServiceTemplates(globalServiceTemplates, serviceTemplates);
118 toscaServiceModel.setEntryDefinitionServiceTemplate(mainStName);
119 toscaServiceModel.setServiceTemplates(serviceTemplates);
120 externalFilesHandler.addFile(metadataFile + ".original",
121 csarFiles.get(metadataFile + ".original"));
122 toscaServiceModel.setArtifactFiles(externalFilesHandler);
124 if(MapUtils.isNotEmpty(globalSubstitutionServiceTemplate.getNode_types())) {
126 .put(GLOBAL_SUBSTITUTION_SERVICE_FILE_NAME, globalSubstitutionServiceTemplate);
130 private void addGlobalServiceTemplates(Collection<ServiceTemplate> globalServiceTemplates,
131 Map<String, ServiceTemplate> serviceTemplates) {
132 for (ServiceTemplate serviceTemplate : globalServiceTemplates) {
133 serviceTemplates.put(ToscaUtil.getServiceTemplateFileName(serviceTemplate), serviceTemplate);
137 private void handleServiceTemplate(String serviceTemplateName,
138 String fileName, Map<String, byte[]> csarFiles,
139 Map<String, ServiceTemplate> serviceTemplates) {
140 Optional<ServiceTemplate> serviceTemplate =
141 getServiceTemplateFromCsar(fileName, csarFiles);
142 serviceTemplate.ifPresent(
143 serviceTemplateValue -> addServiceTemplate(serviceTemplateName, serviceTemplateValue,
147 private void addServiceTemplate(String serviceTemplateName,
148 ServiceTemplate serviceTemplate,
149 Map<String, ServiceTemplate> serviceTemplates) {
150 serviceTemplates.put(serviceTemplateName, serviceTemplate);
153 private Optional<byte[]> getManifestContent(Map<String, byte[]> csarFiles) {
154 for (Map.Entry<String, byte[]> csarFileEntry : csarFiles.entrySet()) {
155 if (csarFileEntry.getKey().contains(manifestFileName)) {
156 return Optional.of(csarFileEntry.getValue());
160 return Optional.empty();
163 private Optional<ServiceTemplate> getServiceTemplateFromCsar(String fileName,
164 Map<String, byte[]> csarFiles) {
165 byte[] fileContent = csarFiles.get(fileName);
166 ServiceTemplate serviceTemplate = convertServiceTemplate(fileName, fileContent);
168 return Optional.of(serviceTemplate);
171 private ServiceTemplate convertServiceTemplate(String serviceTemplateName,
172 byte[] fileContent) {
173 ServiceTemplate serviceTemplate = new ServiceTemplate();
175 ServiceTemplateReaderService readerService =
176 new ServiceTemplateReaderServiceImpl(fileContent);
177 convertMetadata(serviceTemplateName, serviceTemplate, readerService);
178 convertToscaVersion(serviceTemplate, readerService);
179 convertImports(serviceTemplate);
180 convertNodeTypes(serviceTemplate, readerService);
181 convertTopologyTemplate(serviceTemplate, readerService);
183 } catch (YAMLException ye) {
184 throw new CoreException(new ErrorCode.ErrorCodeBuilder()
185 .withMessage("Invalid YAML content in file" + serviceTemplateName + ". reason - "
187 .withCategory(ErrorCategory.APPLICATION).build());
191 return serviceTemplate;
194 private void convertToscaVersion(ServiceTemplate serviceTemplate,
195 ServiceTemplateReaderService readerService) {
196 Object toscaVersion = readerService.getToscaVersion();
197 serviceTemplate.setTosca_definitions_version((String) toscaVersion);
200 private void convertImports(ServiceTemplate serviceTemplate) {
201 serviceTemplate.setImports(new ArrayList<>());
202 serviceTemplate.getImports()
203 .add(createImportMap(openecompHeatIndex, "openecomp-heat/_index.yml"));
204 serviceTemplate.getImports().add(createImportMap(globalSubstitution, globalStName));
208 private Map<String, Import> createImportMap(String key, String fileName) {
209 Map<String, Import> importMap = new HashMap<>();
210 Import anImport = new Import();
211 anImport.setFile(fileName);
212 importMap.put(key, anImport);
217 private void convertMetadata(String serviceTemplateName,
218 ServiceTemplate serviceTemplate,
219 ServiceTemplateReaderService readerService) {
220 Map<String, Object> metadataToConvert = (Map<String, Object>) readerService.getMetadata();
221 Map<String, String> finalMetadata = new HashMap<>();
223 if (MapUtils.isNotEmpty(metadataToConvert)) {
224 for (Map.Entry<String, Object> metadataEntry : metadataToConvert.entrySet()) {
225 if (Objects.isNull(metadataEntry.getValue()) ||
226 !(metadataEntry.getValue() instanceof String)) {
229 finalMetadata.put(metadataEntry.getKey(), (String) metadataEntry.getValue());
233 finalMetadata.put("template_name", getTemplateNameFromStName(serviceTemplateName));
234 serviceTemplate.setMetadata(finalMetadata);
237 private void convertNodeTypes(ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) {
238 Map<String, Object> nodeTypes = (Map<String, Object>) readerService.getNodeTypes();
239 if (MapUtils.isEmpty(nodeTypes)) {
243 for (Map.Entry<String, Object> nodeTypeEntry : nodeTypes.entrySet()) {
244 Optional<NodeType> nodeType = ToscaConverterUtil
245 .createObjectFromClass(nodeTypeEntry.getKey(), nodeTypeEntry.getValue(),
248 nodeType.ifPresent(nodeTypeValue -> DataModelUtil
249 .addNodeType(serviceTemplate, nodeTypeEntry.getKey(), nodeTypeValue));
253 private void convertTopologyTemplate(ServiceTemplate serviceTemplate,
254 ServiceTemplateReaderService readerService) {
256 convertInputs(serviceTemplate, readerService);
257 convertNodeTemplates(serviceTemplate, readerService);
258 convertOutputs(serviceTemplate, readerService);
259 convertSubstitutionMappings(serviceTemplate, readerService);
262 private void convertInputs(ServiceTemplate serviceTemplate,
263 ServiceTemplateReaderService readerService) {
264 Map<String, Object> inputs = readerService.getInputs();
265 addInputsOrOutputsToServiceTemplate(serviceTemplate, inputs, Constants.inputs);
268 private void convertOutputs(ServiceTemplate serviceTemplate,
269 ServiceTemplateReaderService readerService) {
270 Map<String, Object> outputs = readerService.getOutputs();
271 addInputsOrOutputsToServiceTemplate(serviceTemplate, outputs, Constants.outputs);
274 private void addInputsOrOutputsToServiceTemplate(ServiceTemplate serviceTemplate,
275 Map<String, Object> mapToConvert,
276 String inputsOrOutputs) {
277 if (MapUtils.isEmpty(mapToConvert)) {
281 for (Map.Entry<String, Object> entry : mapToConvert.entrySet()) {
282 Optional<ParameterDefinition> parameterDefinition =
283 ToscaConverterUtil.createObjectFromClass(
284 entry.getKey(), entry.getValue(), ParameterDefinition.class);
286 parameterDefinition.ifPresent(parameterDefinitionValue -> {
287 handleDefaultValue(entry.getValue(), parameterDefinition.get());
288 addToServiceTemplateAccordingToSection(
289 serviceTemplate, inputsOrOutputs, entry.getKey(), parameterDefinition.get());
294 private void handleDefaultValue(Object entryValue,
295 ParameterDefinition parameterDefinition) {
296 if(!(entryValue instanceof Map)
297 || Objects.isNull(parameterDefinition)){
301 Object defaultValue = ((Map) entryValue).get("default");
302 if(Objects.nonNull(defaultValue)) {
303 parameterDefinition.set_default(defaultValue);
307 private void addToServiceTemplateAccordingToSection(ServiceTemplate serviceTemplate,
308 String inputsOrOutputs,
310 ParameterDefinition parameterDefinition) {
311 switch (inputsOrOutputs) {
314 .addInputParameterToTopologyTemplate(serviceTemplate, parameterId, parameterDefinition);
318 .addOutputParameterToTopologyTemplate(serviceTemplate, parameterId, parameterDefinition);
322 private void convertNodeTemplates(ServiceTemplate serviceTemplate,
323 ServiceTemplateReaderService readerService) {
324 Map<String, Object> nodeTemplates = readerService.getNodeTemplates();
325 if (MapUtils.isEmpty(nodeTemplates)) {
329 for (Map.Entry<String, Object> nodeTemplateEntry : nodeTemplates.entrySet()) {
330 NodeTemplate nodeTemplate = convertNodeTemplate(nodeTemplateEntry.getValue());
331 DataModelUtil.addNodeTemplate(serviceTemplate, nodeTemplateEntry.getKey(), nodeTemplate);
335 private void convertSubstitutionMappings(ServiceTemplate serviceTemplate,
336 ServiceTemplateReaderService readerService) {
337 Map<String, Object> substitutionMappings = readerService.getSubstitutionMappings();
338 if (MapUtils.isEmpty(substitutionMappings)) {
341 SubstitutionMapping substitutionMapping = convertSubstitutionMappings(substitutionMappings);
342 DataModelUtil.addSubstitutionMapping(serviceTemplate, substitutionMapping);
345 private SubstitutionMapping convertSubstitutionMappings(Map<String, Object> substitutionMappings) {
346 SubstitutionMapping substitutionMapping = new SubstitutionMapping();
348 substitutionMapping.setNode_type((String) substitutionMappings.get(nodeType));
349 substitutionMapping.setCapabilities(
350 convertSubstitutionMappingsSections(capabilities, substitutionMappings.get(capabilities)));
351 substitutionMapping.setRequirements(
352 convertSubstitutionMappingsSections(requirements, substitutionMappings.get(requirements)));
354 return substitutionMapping;
357 private Map<String, List<String>> convertSubstitutionMappingsSections(String sectionName,
358 Object sectionToConvert) {
360 if(Objects.isNull(sectionToConvert)){
364 if(!(sectionToConvert instanceof Map)) {
365 throw new CoreException(
366 new SubstitutionMappingsConverterErrorBuilder(
367 sectionName, sectionToConvert.getClass().getSimpleName()).build());
370 return convertSection(sectionToConvert);
373 private Map<String, List<String>> convertSection(Object sectionToConvert) {
375 Map<String, Object> sectionAsMap = (Map<String, Object>)sectionToConvert;
376 Map<String, List<String>> convertedSection = new HashMap<>();
378 if (MapUtils.isEmpty(sectionAsMap)) {
382 for (Map.Entry<String, Object> entry : sectionAsMap.entrySet()) {
383 if (entry.getValue() instanceof List) {
384 convertedSection.put(entry.getKey(), (List<String>) entry.getValue());
388 return convertedSection;
391 private CsarFileTypes getFileType(String fileName) {
392 if (isMainServiceTemplate(fileName)) {
393 return CsarFileTypes.mainServiceTemplate;
394 } else if (isGlobalServiceTemplate(fileName)) {
395 return CsarFileTypes.globalServiceTemplate;
396 } else if (isDefinitions(fileName)) {
397 return CsarFileTypes.definitionsFile;
398 } else if (isMetadataFile(fileName)) {
399 return CsarFileTypes.toscaMetadata;
401 return CsarFileTypes.externalFile;
404 private Optional<Manifest> getCsarManifest(Map<String, byte[]> csarFiles) throws IOException {
405 Optional<byte[]> manifestContent = getManifestContent(csarFiles);
407 if (manifestContent.isPresent()) {
408 ByteArrayInputStream byteInputStream = new ByteArrayInputStream(manifestContent.get());
410 return Optional.of(new Manifest(byteInputStream));
413 return Optional.empty();
416 private NodeTemplate convertNodeTemplate(Object candidateNodeTemplate) {
417 NodeTemplate nodeTemplate = new NodeTemplate();
419 Map<String, Object> nodeTemplateAsMap = (Map<String, Object>) candidateNodeTemplate;
420 nodeTemplate.setArtifacts((Map<String, ArtifactDefinition>) nodeTemplateAsMap.get("artifacts"));
421 nodeTemplate.setAttributes((Map<String, Object>) nodeTemplateAsMap.get("attributes"));
422 nodeTemplate.setCopy((String) nodeTemplateAsMap.get("copy"));
423 nodeTemplate.setDescription((String) nodeTemplateAsMap.get("description"));
424 nodeTemplate.setDirectives((List<String>) nodeTemplateAsMap.get("directives"));
425 nodeTemplate.setInterfaces(
426 (Map<String, InterfaceDefinition>) nodeTemplateAsMap.get("interfaces"));
427 nodeTemplate.setNode_filter((NodeFilter) nodeTemplateAsMap.get("node_filter"));
428 nodeTemplate.setProperties((Map<String, Object>) nodeTemplateAsMap.get("properties"));
429 nodeTemplate.setRequirements(
430 (List<Map<String, RequirementAssignment>>) nodeTemplateAsMap.get("requirements"));
431 nodeTemplate.setType((String) nodeTemplateAsMap.get("type"));
432 nodeTemplate.setCapabilities(
433 convertCapabilities((Map<String, Object>) nodeTemplateAsMap.get("capabilities")));
438 private List<Map<String, CapabilityAssignment>> convertCapabilities(Map<String, Object> capabilities) {
439 List<Map<String, CapabilityAssignment>> convertedCapabilities = new ArrayList<>();
440 if (MapUtils.isEmpty(capabilities)) {
443 for (Map.Entry<String, Object> capabilityAssignmentEntry : capabilities.entrySet()) {
444 Map<String, CapabilityAssignment> tempMap = new HashMap<>();
445 Optional<CapabilityAssignment> capabilityAssignment = ToscaConverterUtil.createObjectFromClass
446 (capabilityAssignmentEntry.getKey(), capabilityAssignmentEntry.getValue(),
447 CapabilityAssignment.class);
449 capabilityAssignment.ifPresent(capabilityAssignmentValue -> {
450 tempMap.put(capabilityAssignmentEntry.getKey(), capabilityAssignmentValue);
451 convertedCapabilities.add(tempMap);
456 return convertedCapabilities;
460 private boolean isMainServiceTemplate(String fileName) {
461 return fileName.endsWith(mainStName);
464 private boolean isMetadataFile(String fileName) {
465 return fileName.equals(metadataFile);
468 private boolean isGlobalServiceTemplate(String fileName) {
469 return fileName.endsWith(globalStName);
472 private boolean isDefinitions(String fileName) {
473 return fileName.startsWith(definitionsDir);
476 private String getTemplateNameFromStName(String serviceTemplateName) {
477 String fileNameWithoutDirectories;
478 fileNameWithoutDirectories = getFileNameWithoutDirectories(serviceTemplateName);
479 return fileNameWithoutDirectories.split("ServiceTemplate")[0];
482 private String getFileNameWithoutDirectories(String serviceTemplateName) {
483 String fileNameWithoutDirectories;
484 if (serviceTemplateName.contains("/")) {
485 String[] split = serviceTemplateName.split("/");
486 fileNameWithoutDirectories = split[split.length - 1];
487 } else if (serviceTemplateName.contains(File.separator)) {
488 String[] split = serviceTemplateName.split(Pattern.quote(File.separator));
489 fileNameWithoutDirectories = split[split.length - 1];
491 fileNameWithoutDirectories = serviceTemplateName;
493 return fileNameWithoutDirectories;