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);
57 artifacts.addFile(fileEntry.getKey(), fileEntry.getValue());
61 handleDefintionTemplate(fileEntry.getKey(), csarFiles, gsst);
65 handleMetadataFile(csarFiles);
66 updateToscaServiceModel(toscaServiceModel, serviceTemplates, artifacts, gsst, csarFiles);
67 return toscaServiceModel;
70 private void handleMetadataFile(Map<String, byte[]> csarFiles) {
71 byte[] bytes = csarFiles.remove(metadataFile);
73 csarFiles.put(metadataFile + ".original", bytes);
77 private void handleDefintionTemplate(String key, Map<String, byte[]> csarFiles,
78 GlobalSubstitutionServiceTemplate gsst) {
80 ServiceTemplateReaderService readerService = new ServiceTemplateReaderServiceImpl(csarFiles.get(key));
81 if (readerService == null) {
84 Object nodeTypes = readerService.getNodeTypes();
85 if (nodeTypes instanceof Map) {
86 Map<String, NodeType> nodeTypeMap = (Map<String, NodeType>) nodeTypes;
87 gsst.appendNodes(nodeTypeMap);
89 } catch (YAMLException ye) {
90 throw new CoreException(new ErrorCode.ErrorCodeBuilder()
91 .withMessage("Invalid YAML content in file " + key + ". reason - "
93 .withCategory(ErrorCategory.APPLICATION).build());
97 private void updateToscaServiceModel(ToscaServiceModel toscaServiceModel,
98 Map<String, ServiceTemplate> serviceTemplates,
99 FileContentHandler externalFilesHandler,
100 GlobalSubstitutionServiceTemplate globalSubstitutionServiceTemplate,
101 Map<String, byte[]> csarFiles) {
102 Collection<ServiceTemplate> globalServiceTemplates =
103 GlobalTypesGenerator.getGlobalTypesServiceTemplate().values();
104 addGlobalServiceTemplates(globalServiceTemplates, serviceTemplates);
105 toscaServiceModel.setEntryDefinitionServiceTemplate(mainStName);
106 toscaServiceModel.setServiceTemplates(serviceTemplates);
107 externalFilesHandler.addFile(metadataFile + ".original",
108 csarFiles.get(metadataFile + ".original"));
109 toscaServiceModel.setArtifactFiles(externalFilesHandler);
111 if(MapUtils.isNotEmpty(globalSubstitutionServiceTemplate.getNode_types())) {
113 .put(GLOBAL_SUBSTITUTION_SERVICE_FILE_NAME, globalSubstitutionServiceTemplate);
117 private void addGlobalServiceTemplates(Collection<ServiceTemplate> globalServiceTemplates,
118 Map<String, ServiceTemplate> serviceTemplates) {
119 for (ServiceTemplate serviceTemplate : globalServiceTemplates) {
120 serviceTemplates.put(ToscaUtil.getServiceTemplateFileName(serviceTemplate), serviceTemplate);
124 private void handleServiceTemplate(String serviceTemplateName,
125 String fileName, Map<String, byte[]> csarFiles,
126 Map<String, ServiceTemplate> serviceTemplates) {
127 Optional<ServiceTemplate> serviceTemplate =
128 getServiceTemplateFromCsar(fileName, csarFiles);
129 serviceTemplate.ifPresent(
130 serviceTemplate1 -> addServiceTemplate(serviceTemplateName, serviceTemplate1,
134 private void addServiceTemplate(String serviceTemplateName,
135 ServiceTemplate serviceTemplate,
136 Map<String, ServiceTemplate> serviceTemplates) {
137 serviceTemplates.put(serviceTemplateName, serviceTemplate);
140 private Optional<byte[]> getManifestContent(Map<String, byte[]> csarFiles) {
141 for (Map.Entry<String, byte[]> csarFileEntry : csarFiles.entrySet()) {
142 if (csarFileEntry.getKey().contains(manifestFileName)) {
143 return Optional.of(csarFileEntry.getValue());
147 return Optional.empty();
150 private Optional<ServiceTemplate> getServiceTemplateFromCsar(String fileName,
151 Map<String, byte[]> csarFiles) {
152 byte[] fileContent = csarFiles.get(fileName);
153 ServiceTemplate serviceTemplate = convertServiceTemplate(fileName, fileContent);
155 return Optional.of(serviceTemplate);
158 private ServiceTemplate convertServiceTemplate(String serviceTemplateName,
159 byte[] fileContent) {
160 ServiceTemplate serviceTemplate = new ServiceTemplate();
162 ServiceTemplateReaderService readerService =
163 new ServiceTemplateReaderServiceImpl(fileContent);
164 convertMetadata(serviceTemplateName, serviceTemplate, readerService);
165 convertToscaVersion(serviceTemplate, readerService);
166 convertImports(serviceTemplate);
167 convertNodeTypes(serviceTemplate, readerService);
168 convertTopologyTemplate(serviceTemplate, readerService);
170 } catch (YAMLException ye) {
171 throw new CoreException(new ErrorCode.ErrorCodeBuilder()
172 .withMessage("Invalid YAML content in file" + serviceTemplateName + ". reason - "
174 .withCategory(ErrorCategory.APPLICATION).build());
178 return serviceTemplate;
181 private void convertToscaVersion(ServiceTemplate serviceTemplate,
182 ServiceTemplateReaderService readerService) {
183 Object toscaVersion = readerService.getToscaVersion();
184 serviceTemplate.setTosca_definitions_version((String) toscaVersion);
187 private void convertImports(ServiceTemplate serviceTemplate) {
188 serviceTemplate.setImports(new ArrayList<>());
189 serviceTemplate.getImports()
190 .add(createImportMap(openecompHeatIndex, "openecomp-heat/_index.yml"));
191 serviceTemplate.getImports().add(createImportMap(globalSubstitution, globalStName));
195 private Map<String, Import> createImportMap(String key, String fileName) {
196 Map<String, Import> importMap = new HashMap<>();
197 Import anImport = new Import();
198 anImport.setFile(fileName);
199 importMap.put(key, anImport);
204 private void convertMetadata(String serviceTemplateName,
205 ServiceTemplate serviceTemplate,
206 ServiceTemplateReaderService readerService) {
207 Map<String, Object> metadataToConvert = (Map<String, Object>) readerService.getMetadata();
208 Map<String, String> finalMetadata = new HashMap<>();
210 if (MapUtils.isNotEmpty(metadataToConvert)) {
211 for (Map.Entry<String, Object> metadataEntry : metadataToConvert.entrySet()) {
212 if (Objects.isNull(metadataEntry.getValue()) ||
213 !(metadataEntry.getValue() instanceof String)) {
216 finalMetadata.put(metadataEntry.getKey(), (String) metadataEntry.getValue());
220 finalMetadata.put("template_name", getTemplateNameFromStName(serviceTemplateName));
221 serviceTemplate.setMetadata(finalMetadata);
224 private void convertNodeTypes(ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) {
225 Map<String, Object> nodeTypes = (Map<String, Object>) readerService.getNodeTypes();
226 if (MapUtils.isEmpty(nodeTypes)) {
230 for (Map.Entry<String, Object> nodeTypeEntry : nodeTypes.entrySet()) {
232 .addNodeType(serviceTemplate, nodeTypeEntry.getKey(),
233 (NodeType) createObjectFromClass(nodeTypeEntry.getKey(), nodeTypeEntry.getValue(),
238 private void convertTopologyTemplate(ServiceTemplate serviceTemplate,
239 ServiceTemplateReaderService readerService) {
241 convertInputs(serviceTemplate, readerService);
242 convertNodeTemplates(serviceTemplate, readerService);
243 convertOutputs(serviceTemplate, readerService);
244 convertSubstitutionMappings(serviceTemplate, readerService);
247 private void convertInputs(ServiceTemplate serviceTemplate,
248 ServiceTemplateReaderService readerService) {
249 Map<String, Object> inputs = readerService.getInputs();
250 addInputsOrOutputsToServiceTemplate(serviceTemplate, inputs, Constants.inputs);
253 private void convertOutputs(ServiceTemplate serviceTemplate,
254 ServiceTemplateReaderService readerService) {
255 Map<String, Object> outputs = readerService.getOutputs();
256 addInputsOrOutputsToServiceTemplate(serviceTemplate, outputs, Constants.outputs);
259 private void addInputsOrOutputsToServiceTemplate(ServiceTemplate serviceTemplate,
260 Map<String, Object> mapToConvert,
261 String inputsOrOutputs) {
262 if (MapUtils.isEmpty(mapToConvert)) {
266 for (Map.Entry<String, Object> entry : mapToConvert.entrySet()) {
267 ParameterDefinition parameterDefinition =
268 (ParameterDefinition) createObjectFromClass(
269 entry.getKey(), entry.getValue(), ParameterDefinition.class);
270 addToServiceTemplateAccordingToSection(
271 serviceTemplate, inputsOrOutputs, entry.getKey(), parameterDefinition);
275 private void addToServiceTemplateAccordingToSection(ServiceTemplate serviceTemplate,
276 String inputsOrOutputs,
278 ParameterDefinition parameterDefinition) {
279 switch (inputsOrOutputs) {
282 .addInputParameterToTopologyTemplate(serviceTemplate, parameterId, parameterDefinition);
286 .addOutputParameterToTopologyTemplate(serviceTemplate, parameterId, parameterDefinition);
290 private void convertNodeTemplates(ServiceTemplate serviceTemplate,
291 ServiceTemplateReaderService readerService) {
292 Map<String, Object> nodeTemplates = readerService.getNodeTemplates();
293 if (MapUtils.isEmpty(nodeTemplates)) {
297 for (Map.Entry<String, Object> nodeTemplateEntry : nodeTemplates.entrySet()) {
298 NodeTemplate nodeTemplate = convertNodeTemplate(nodeTemplateEntry.getValue());
299 DataModelUtil.addNodeTemplate(serviceTemplate, nodeTemplateEntry.getKey(), nodeTemplate);
303 private void convertSubstitutionMappings(ServiceTemplate serviceTemplate,
304 ServiceTemplateReaderService readerService) {
305 Map<String, Object> substitutionMappings = readerService.getSubstitutionMappings();
306 if (MapUtils.isEmpty(substitutionMappings)) {
309 SubstitutionMapping substitutionMapping = convertSubstitutionMappings(substitutionMappings);
310 DataModelUtil.addSubstitutionMapping(serviceTemplate, substitutionMapping);
313 private SubstitutionMapping convertSubstitutionMappings(Map<String, Object> substitutionMappings) {
314 SubstitutionMapping substitutionMapping = new SubstitutionMapping();
316 substitutionMapping.setNode_type((String) substitutionMappings.get(nodeType));
317 substitutionMapping.setCapabilities(
318 convertSubstitutionMappingsSections((Map<String, Object>) substitutionMappings.get(capabilities)));
319 substitutionMapping.setRequirements(
320 convertSubstitutionMappingsSections((Map<String, Object>) substitutionMappings.get(requirements)));
322 return substitutionMapping;
325 private Map<String, List<String>> convertSubstitutionMappingsSections(
326 Map<String, Object> sectionToConvert) {
327 Map<String, List<String>> convertedSection = new HashMap<>();
328 if (MapUtils.isEmpty(sectionToConvert)) {
332 for (Map.Entry<String, Object> entry : sectionToConvert.entrySet()) {
333 if (entry.getValue() instanceof List) {
334 convertedSection.put(entry.getKey(), (List<String>) entry.getValue());
338 return convertedSection;
341 private CsarFileTypes getFileType(String fileName) {
342 if (isMainServiceTemplate(fileName)) {
343 return CsarFileTypes.mainServiceTemplate;
344 } else if (isGlobalServiceTemplate(fileName)) {
345 return CsarFileTypes.globalServiceTemplate;
346 } else if (isDefinitions(fileName)) {
347 return CsarFileTypes.definitionsFile;
348 } else if (isMetadataFile(fileName)) {
349 return CsarFileTypes.toscaMetadata;
351 return CsarFileTypes.externalFile;
354 private Optional<Manifest> getCsarManifest(Map<String, byte[]> csarFiles) throws IOException {
355 Optional<byte[]> manifestContent = getManifestContent(csarFiles);
357 if (manifestContent.isPresent()) {
358 ByteArrayInputStream byteInputStream = new ByteArrayInputStream(manifestContent.get());
360 return Optional.of(new Manifest(byteInputStream));
363 return Optional.empty();
366 private NodeTemplate convertNodeTemplate(Object candidateNodeTemplate) {
367 NodeTemplate nodeTemplate = new NodeTemplate();
369 Map<String, Object> nodeTemplateAsMap = (Map<String, Object>) candidateNodeTemplate;
370 nodeTemplate.setArtifacts((Map<String, ArtifactDefinition>) nodeTemplateAsMap.get("artifacts"));
371 nodeTemplate.setAttributes((Map<String, Object>) nodeTemplateAsMap.get("attributes"));
372 nodeTemplate.setCopy((String) nodeTemplateAsMap.get("copy"));
373 nodeTemplate.setDescription((String) nodeTemplateAsMap.get("description"));
374 nodeTemplate.setDirectives((List<String>) nodeTemplateAsMap.get("directives"));
375 nodeTemplate.setInterfaces(
376 (Map<String, InterfaceDefinition>) nodeTemplateAsMap.get("interfaces"));
377 nodeTemplate.setNode_filter((NodeFilter) nodeTemplateAsMap.get("node_filter"));
378 nodeTemplate.setProperties((Map<String, Object>) nodeTemplateAsMap.get("properties"));
379 nodeTemplate.setRequirements(
380 (List<Map<String, RequirementAssignment>>) nodeTemplateAsMap.get("requirements"));
381 nodeTemplate.setType((String) nodeTemplateAsMap.get("type"));
382 nodeTemplate.setCapabilities(
383 convertCapabilities((Map<String, Object>) nodeTemplateAsMap.get("capabilities")));
388 private List<Map<String, CapabilityAssignment>> convertCapabilities(Map<String, Object> capabilities) {
389 List<Map<String, CapabilityAssignment>> convertedCapabilities = new ArrayList<>();
390 if (MapUtils.isEmpty(capabilities)) {
393 for (Map.Entry<String, Object> capabilityAssignmentEntry : capabilities.entrySet()) {
394 Map<String, CapabilityAssignment> tempMap = new HashMap<>();
395 tempMap.put(capabilityAssignmentEntry.getKey(),
396 (CapabilityAssignment) createObjectFromClass
397 (capabilityAssignmentEntry.getKey(), capabilityAssignmentEntry.getValue(), CapabilityAssignment.class));
398 convertedCapabilities.add(tempMap);
400 return convertedCapabilities;
403 private Object createObjectFromClass(String nodeTypeId,
404 Object objectCandidate,
405 Class classToCreate) {
407 return JsonUtil.json2Object(objectCandidate.toString(), classToCreate);
408 } catch (Exception e) {
409 //todo - return error to user?
410 throw new CoreException(new ErrorCode.ErrorCodeBuilder()
411 .withCategory(ErrorCategory.APPLICATION)
412 .withMessage("Can't create " + classToCreate.getSimpleName() + " from " +
413 nodeTypeId).build());
417 private boolean isMainServiceTemplate(String fileName) {
418 return fileName.endsWith(mainStName);
421 private boolean isMetadataFile(String fileName) {
422 return fileName.equals(metadataFile);
425 private boolean isGlobalServiceTemplate(String fileName) {
426 return fileName.endsWith(globalStName);
429 private boolean isDefinitions(String fileName) {
430 return fileName.startsWith(definitionsDir);
433 private String getTemplateNameFromStName(String serviceTemplateName) {
434 String fileNameWithoutDirectories;
435 fileNameWithoutDirectories = getFileNameWithoutDirectories(serviceTemplateName);
436 return fileNameWithoutDirectories.split("ServiceTemplate")[0];
439 private String getFileNameWithoutDirectories(String serviceTemplateName) {
440 String fileNameWithoutDirectories;
441 if (serviceTemplateName.contains("/")) {
442 String[] split = serviceTemplateName.split("/");
443 fileNameWithoutDirectories = split[split.length - 1];
444 } else if (serviceTemplateName.contains(File.separator)) {
445 String[] split = serviceTemplateName.split(Pattern.quote(File.separator));
446 fileNameWithoutDirectories = split[split.length - 1];
448 fileNameWithoutDirectories = serviceTemplateName;
450 return fileNameWithoutDirectories;