2 * Copyright © 2016-2017 European Support Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.openecomp.core.impl;
19 import org.apache.commons.collections.MapUtils;
20 import org.onap.sdc.tosca.datatypes.model.*;
21 import org.openecomp.core.converter.ServiceTemplateReaderService;
22 import org.openecomp.core.converter.ToscaConverter;
23 import org.openecomp.core.converter.datatypes.Constants;
24 import org.openecomp.core.converter.datatypes.CsarFileTypes;
25 import org.openecomp.core.converter.errors.SubstitutionMappingsConverterErrorBuilder;
26 import org.openecomp.core.impl.services.ServiceTemplateReaderServiceImpl;
27 import org.openecomp.core.utilities.file.FileContentHandler;
28 import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
29 import org.openecomp.sdc.common.errors.CoreException;
30 import org.openecomp.sdc.common.errors.ErrorCategory;
31 import org.openecomp.sdc.common.errors.ErrorCode;
32 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
33 import org.openecomp.sdc.tosca.services.DataModelUtil;
34 import org.openecomp.sdc.tosca.services.ToscaUtil;
35 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
36 import org.yaml.snakeyaml.error.YAMLException;
40 import java.util.regex.Pattern;
42 import static org.openecomp.core.converter.datatypes.Constants.*;
43 import static org.openecomp.core.impl.GlobalSubstitutionServiceTemplate.*;
45 public class ToscaConverterImpl implements ToscaConverter {
47 private static final String ORIGINAL = ".original";
48 public ToscaConverterImpl() {
53 public ToscaServiceModel convert(FileContentHandler fileContentHandler) {
54 Map<String, byte[]> csarFiles = new HashMap<>(fileContentHandler.getFiles());
55 ToscaServiceModel toscaServiceModel = new ToscaServiceModel();
56 Map<String, ServiceTemplate> serviceTemplates = new HashMap<>();
57 FileContentHandler artifacts = new FileContentHandler();
58 GlobalSubstitutionServiceTemplate gsst = new GlobalSubstitutionServiceTemplate();
59 for (Map.Entry<String, byte[]> fileEntry : csarFiles.entrySet()) {
60 CsarFileTypes fileType = getFileType(fileEntry.getKey());
62 case mainServiceTemplate:
63 handleServiceTemplate(mainStName, fileEntry.getKey(), csarFiles, serviceTemplates);
66 case globalServiceTemplate:
67 handleServiceTemplate(globalStName, fileEntry.getKey(), csarFiles, serviceTemplates);
72 getConcreteArtifactFileName(fileEntry.getKey()), fileEntry.getValue());
76 handleDefintionTemplate(fileEntry.getKey(), csarFiles, gsst);
83 handleMetadataFile(csarFiles);
84 updateToscaServiceModel(toscaServiceModel, serviceTemplates, artifacts, gsst, csarFiles);
85 return toscaServiceModel;
88 private void handleMetadataFile(Map<String, byte[]> csarFiles) {
89 byte[] bytes = csarFiles.remove(metadataFile);
91 csarFiles.put(metadataFile + ORIGINAL, bytes);
95 private void handleDefintionTemplate(String key, Map<String, byte[]> csarFiles,
96 GlobalSubstitutionServiceTemplate gsst) {
98 ServiceTemplateReaderService readerService = new ServiceTemplateReaderServiceImpl(csarFiles.get(key));
99 Object nodeTypes = readerService.getNodeTypes();
100 if (nodeTypes instanceof Map) {
101 Map<String, NodeType> nodeTypeMap = (Map<String, NodeType>) nodeTypes;
102 gsst.appendNodes(nodeTypeMap);
104 } catch (YAMLException ye) {
105 throw new CoreException(new ErrorCode.ErrorCodeBuilder()
106 .withMessage("Invalid YAML content in file " + key)
107 .withCategory(ErrorCategory.APPLICATION).build(), ye);
111 private String getConcreteArtifactFileName(String fileName){
112 int artifactIndex = fileName.indexOf(CsarFileTypes.Artifacts.name());
113 if(artifactIndex < 0){
117 int artifactDirectoryIndex =
118 artifactIndex + CsarFileTypes.Artifacts.name().length() + 1;
119 return fileName.substring(artifactDirectoryIndex);
122 private void updateToscaServiceModel(ToscaServiceModel toscaServiceModel,
123 Map<String, ServiceTemplate> serviceTemplates,
124 FileContentHandler externalFilesHandler,
125 GlobalSubstitutionServiceTemplate globalSubstitutionServiceTemplate,
126 Map<String, byte[]> csarFiles) {
127 Collection<ServiceTemplate> globalServiceTemplates =
128 GlobalTypesGenerator.getGlobalTypesServiceTemplate(OnboardingTypesEnum.CSAR).values();
129 addGlobalServiceTemplates(globalServiceTemplates, serviceTemplates);
130 toscaServiceModel.setEntryDefinitionServiceTemplate(mainStName);
131 toscaServiceModel.setServiceTemplates(serviceTemplates);
132 externalFilesHandler.addFile(metadataFile + ORIGINAL,
133 csarFiles.get(metadataFile + ORIGINAL));
134 toscaServiceModel.setArtifactFiles(externalFilesHandler);
136 if(MapUtils.isNotEmpty(globalSubstitutionServiceTemplate.getNode_types())) {
138 .put(GLOBAL_SUBSTITUTION_SERVICE_FILE_NAME, globalSubstitutionServiceTemplate);
142 private void addGlobalServiceTemplates(Collection<ServiceTemplate> globalServiceTemplates,
143 Map<String, ServiceTemplate> serviceTemplates) {
144 for (ServiceTemplate serviceTemplate : globalServiceTemplates) {
145 serviceTemplates.put(ToscaUtil.getServiceTemplateFileName(serviceTemplate), serviceTemplate);
149 private void handleServiceTemplate(String serviceTemplateName,
150 String fileName, Map<String, byte[]> csarFiles,
151 Map<String, ServiceTemplate> serviceTemplates) {
152 Optional<ServiceTemplate> serviceTemplate =
153 getServiceTemplateFromCsar(fileName, csarFiles);
154 serviceTemplate.ifPresent(
155 serviceTemplateValue -> addServiceTemplate(serviceTemplateName, serviceTemplateValue,
159 private void addServiceTemplate(String serviceTemplateName,
160 ServiceTemplate serviceTemplate,
161 Map<String, ServiceTemplate> serviceTemplates) {
162 serviceTemplates.put(serviceTemplateName, serviceTemplate);
165 private Optional<ServiceTemplate> getServiceTemplateFromCsar(String fileName,
166 Map<String, byte[]> csarFiles) {
167 byte[] fileContent = csarFiles.get(fileName);
168 ServiceTemplate serviceTemplate = convertServiceTemplate(fileName, fileContent);
170 return Optional.of(serviceTemplate);
173 private ServiceTemplate convertServiceTemplate(String serviceTemplateName,
174 byte[] fileContent) {
175 ServiceTemplate serviceTemplate = new ServiceTemplate();
177 ServiceTemplateReaderService readerService =
178 new ServiceTemplateReaderServiceImpl(fileContent);
179 convertMetadata(serviceTemplateName, serviceTemplate, readerService);
180 convertToscaVersion(serviceTemplate, readerService);
181 convertImports(serviceTemplate);
182 convertNodeTypes(serviceTemplate, readerService);
183 convertTopologyTemplate(serviceTemplate, readerService);
185 } catch (YAMLException ye) {
186 throw new CoreException(new ErrorCode.ErrorCodeBuilder()
187 .withMessage("Invalid YAML content in file" + serviceTemplateName)
188 .withCategory(ErrorCategory.APPLICATION).build(), ye);
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, HEAT_INDEX_IMPORT_FILE));
205 serviceTemplate.getImports().add(createImportMap(ONAP_INDEX, ONAP_INDEX_IMPORT_FILE));
206 serviceTemplate.getImports().add(createImportMap(globalSubstitution, globalStName));
210 private Map<String, Import> createImportMap(String key, String fileName) {
211 Map<String, Import> importMap = new HashMap<>();
212 Import anImport = new Import();
213 anImport.setFile(fileName);
214 importMap.put(key, anImport);
219 private void convertMetadata(String serviceTemplateName,
220 ServiceTemplate serviceTemplate,
221 ServiceTemplateReaderService readerService) {
222 Map<String, Object> metadataToConvert = (Map<String, Object>) readerService.getMetadata();
223 Map<String, String> finalMetadata = new HashMap<>();
225 if (MapUtils.isNotEmpty(metadataToConvert)) {
226 for (Map.Entry<String, Object> metadataEntry : metadataToConvert.entrySet()) {
227 if (Objects.isNull(metadataEntry.getValue()) ||
228 !(metadataEntry.getValue() instanceof String)) {
231 finalMetadata.put(metadataEntry.getKey(), (String) metadataEntry.getValue());
235 finalMetadata.put("template_name", getTemplateNameFromStName(serviceTemplateName));
236 serviceTemplate.setMetadata(finalMetadata);
239 private void convertNodeTypes(ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) {
240 Map<String, Object> nodeTypes = readerService.getNodeTypes();
241 if (MapUtils.isEmpty(nodeTypes)) {
245 for (Map.Entry<String, Object> nodeTypeEntry : nodeTypes.entrySet()) {
246 Optional<NodeType> nodeType = ToscaConverterUtil
247 .createObjectFromClass(nodeTypeEntry.getKey(), nodeTypeEntry.getValue(),
250 nodeType.ifPresent(nodeTypeValue -> DataModelUtil
251 .addNodeType(serviceTemplate, nodeTypeEntry.getKey(), nodeTypeValue));
255 private void convertTopologyTemplate(ServiceTemplate serviceTemplate,
256 ServiceTemplateReaderService readerService) {
258 convertInputs(serviceTemplate, readerService);
259 convertNodeTemplates(serviceTemplate, readerService);
260 convertOutputs(serviceTemplate, readerService);
261 convertSubstitutionMappings(serviceTemplate, readerService);
264 private void convertInputs(ServiceTemplate serviceTemplate,
265 ServiceTemplateReaderService readerService) {
266 Map<String, Object> inputs = readerService.getInputs();
267 addInputsOrOutputsToServiceTemplate(serviceTemplate, inputs, Constants.inputs);
270 private void convertOutputs(ServiceTemplate serviceTemplate,
271 ServiceTemplateReaderService readerService) {
272 Map<String, Object> outputs = readerService.getOutputs();
273 addInputsOrOutputsToServiceTemplate(serviceTemplate, outputs, Constants.outputs);
276 private void addInputsOrOutputsToServiceTemplate(ServiceTemplate serviceTemplate,
277 Map<String, Object> mapToConvert,
278 String inputsOrOutputs) {
279 if (MapUtils.isEmpty(mapToConvert)) {
283 for (Map.Entry<String, Object> entry : mapToConvert.entrySet()) {
284 Optional<ParameterDefinition> parameterDefinition =
285 ToscaConverterUtil.createObjectFromClass(
286 entry.getKey(), entry.getValue(), ParameterDefinition.class);
288 parameterDefinition.ifPresent(parameterDefinitionValue -> {
289 Optional<Object> defaultValue =
290 ToscaConverterUtil.getDefaultValue(entry.getValue(), parameterDefinition.get());
291 defaultValue.ifPresent(parameterDefinitionValue::set_default);
292 addToServiceTemplateAccordingToSection(
293 serviceTemplate, inputsOrOutputs, entry.getKey(), parameterDefinition.get());
298 private void addToServiceTemplateAccordingToSection(ServiceTemplate serviceTemplate,
299 String inputsOrOutputs,
301 ParameterDefinition parameterDefinition) {
302 if (inputsOrOutputs.equals(inputs)) {
304 .addInputParameterToTopologyTemplate(serviceTemplate, parameterId, parameterDefinition);
305 } else if (inputsOrOutputs.equals(outputs)) {
307 .addOutputParameterToTopologyTemplate(serviceTemplate, parameterId, parameterDefinition);
311 private void convertNodeTemplates(ServiceTemplate serviceTemplate,
312 ServiceTemplateReaderService readerService) {
313 Map<String, Object> nodeTemplates = readerService.getNodeTemplates();
314 if (MapUtils.isEmpty(nodeTemplates)) {
318 for (Map.Entry<String, Object> nodeTemplateEntry : nodeTemplates.entrySet()) {
319 NodeTemplate nodeTemplate = convertNodeTemplate(nodeTemplateEntry.getValue());
320 DataModelUtil.addNodeTemplate(serviceTemplate, nodeTemplateEntry.getKey(), nodeTemplate);
324 private void convertSubstitutionMappings(ServiceTemplate serviceTemplate,
325 ServiceTemplateReaderService readerService) {
326 Map<String, Object> substitutionMappings = readerService.getSubstitutionMappings();
327 if (MapUtils.isEmpty(substitutionMappings)) {
330 SubstitutionMapping substitutionMapping = convertSubstitutionMappings(substitutionMappings);
331 DataModelUtil.addSubstitutionMapping(serviceTemplate, substitutionMapping);
334 private SubstitutionMapping convertSubstitutionMappings(
335 Map<String, Object> substitutionMappings) {
336 SubstitutionMapping substitutionMapping = new SubstitutionMapping();
338 substitutionMapping.setNode_type((String) substitutionMappings.get(nodeType));
339 substitutionMapping.setCapabilities(
340 convertSubstitutionMappingsSections(capabilities, substitutionMappings.get(capabilities)));
341 substitutionMapping.setRequirements(
342 convertSubstitutionMappingsSections(requirements, substitutionMappings.get(requirements)));
344 return substitutionMapping;
347 private Map<String, List<String>> convertSubstitutionMappingsSections(String sectionName,
348 Object sectionToConvert) {
350 if (Objects.isNull(sectionToConvert)) {
354 if (!(sectionToConvert instanceof Map)) {
355 throw new CoreException(
356 new SubstitutionMappingsConverterErrorBuilder(
357 sectionName, sectionToConvert.getClass().getSimpleName()).build());
360 return convertSection(sectionToConvert);
363 private Map<String, List<String>> convertSection(Object sectionToConvert) {
365 Map<String, Object> sectionAsMap = (Map<String, Object>) sectionToConvert;
366 Map<String, List<String>> convertedSection = new HashMap<>();
368 if (MapUtils.isEmpty(sectionAsMap)) {
372 for (Map.Entry<String, Object> entry : sectionAsMap.entrySet()) {
373 if (entry.getValue() instanceof List) {
374 convertedSection.put(entry.getKey(), (List<String>) entry.getValue());
378 return convertedSection;
381 private CsarFileTypes getFileType(String fileName) {
382 if (isMainServiceTemplate(fileName)) {
383 return CsarFileTypes.mainServiceTemplate;
384 } else if (isGlobalServiceTemplate(fileName)) {
385 return CsarFileTypes.globalServiceTemplate;
386 } else if (isDefinitions(fileName)) {
387 return CsarFileTypes.definitionsFile;
388 } else if (isMetadataFile(fileName)) {
389 return CsarFileTypes.toscaMetadata;
391 return CsarFileTypes.externalFile;
394 private NodeTemplate convertNodeTemplate(Object candidateNodeTemplate) {
395 NodeTemplate nodeTemplate = new NodeTemplate();
397 Map<String, Object> nodeTemplateAsMap = (Map<String, Object>) candidateNodeTemplate;
398 nodeTemplate.setArtifacts((Map<String, ArtifactDefinition>) nodeTemplateAsMap.get("artifacts"));
399 nodeTemplate.setAttributes((Map<String, Object>) nodeTemplateAsMap.get("attributes"));
400 nodeTemplate.setCopy((String) nodeTemplateAsMap.get("copy"));
401 nodeTemplate.setDescription((String) nodeTemplateAsMap.get("description"));
402 nodeTemplate.setDirectives((List<String>) nodeTemplateAsMap.get("directives"));
403 nodeTemplate.setInterfaces(
404 (Map<String, Object>) nodeTemplateAsMap.get("interfaces"));
405 nodeTemplate.setNode_filter((NodeFilter) nodeTemplateAsMap.get("node_filter"));
406 nodeTemplate.setProperties((Map<String, Object>) nodeTemplateAsMap.get("properties"));
407 nodeTemplate.setRequirements(
408 (List<Map<String, RequirementAssignment>>) nodeTemplateAsMap.get("requirements"));
409 nodeTemplate.setType((String) nodeTemplateAsMap.get("type"));
410 nodeTemplate.setCapabilities(
411 convertCapabilities((Map<String, Object>) nodeTemplateAsMap.get("capabilities")));
416 private Map<String, CapabilityAssignment> convertCapabilities(Map<String, Object> capabilities) {
417 if (MapUtils.isEmpty(capabilities)) {
421 Map<String, CapabilityAssignment> convertedCapabilities = new HashMap<>();
422 for (Map.Entry<String, Object> capabilityAssignmentEntry : capabilities.entrySet()) {
423 Optional<CapabilityAssignment> capabilityAssignment = ToscaConverterUtil.createObjectFromClass
424 (capabilityAssignmentEntry.getKey(), capabilityAssignmentEntry.getValue(),
425 CapabilityAssignment.class);
427 capabilityAssignment.ifPresent(capabilityAssignmentValue ->
428 convertedCapabilities.put(capabilityAssignmentEntry.getKey(), capabilityAssignmentValue));
431 return convertedCapabilities;
435 private boolean isMainServiceTemplate(String fileName) {
436 return fileName.endsWith(mainStName);
439 private boolean isMetadataFile(String fileName) {
440 return fileName.equals(metadataFile);
443 private boolean isGlobalServiceTemplate(String fileName) {
444 return fileName.endsWith(globalStName);
447 private boolean isDefinitions(String fileName) {
448 return fileName.startsWith(definitionsDir);
451 private String getTemplateNameFromStName(String serviceTemplateName) {
452 String fileNameWithoutDirectories;
453 fileNameWithoutDirectories = getFileNameWithoutDirectories(serviceTemplateName);
454 return fileNameWithoutDirectories.split("ServiceTemplate")[0];
457 private String getFileNameWithoutDirectories(String serviceTemplateName) {
458 String fileNameWithoutDirectories;
459 if (serviceTemplateName.contains("/")) {
460 String[] split = serviceTemplateName.split("/");
461 fileNameWithoutDirectories = split[split.length - 1];
462 } else if (serviceTemplateName.contains(File.separator)) {
463 String[] split = serviceTemplateName.split(Pattern.quote(File.separator));
464 fileNameWithoutDirectories = split[split.length - 1];
466 fileNameWithoutDirectories = serviceTemplateName;
468 return fileNameWithoutDirectories;