2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2019 Nordix Foundation
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * 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.
16 * SPDX-License-Identifier: Apache-2.0
17 * ============LICENSE_END=========================================================
20 package org.openecomp.core.converter.pnfd.parser;
22 import java.util.HashMap;
23 import java.util.List;
25 import java.util.Optional;
27 import org.apache.commons.collections.MapUtils;
28 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
29 import org.openecomp.core.converter.ServiceTemplateReaderService;
30 import org.openecomp.core.converter.pnfd.model.ConversionDefinition;
31 import org.openecomp.core.converter.pnfd.model.PnfTransformationToken;
32 import org.openecomp.core.converter.pnfd.model.Transformation;
34 public abstract class AbstractPnfdBlockParser implements PnfdBlockParser {
36 protected final Transformation transformation;
37 protected ServiceTemplateReaderService templateFrom;
38 protected ServiceTemplate templateTo;
40 public AbstractPnfdBlockParser(final Transformation transformation) {
41 this.transformation = transformation;
45 * Parses a PNFD block based on the {@link Transformation} provided during the {@link PnfdBlockParser}
48 * @param templateFrom the original PNFD template
49 * @param templateTo the resulting PNFD template
51 public void parse(final ServiceTemplateReaderService templateFrom, final ServiceTemplate templateTo) {
52 this.templateFrom = templateFrom;
53 this.templateTo = templateTo;
54 final Set<Map<String, Object>> blockToParseSet = findBlocksToParse();
55 if (!blockToParseSet.isEmpty()) {
56 blockToParseSet.forEach(this::parse);
61 * Applies all specified conversions in {@link Transformation#getConversionDefinitionList()} for the given
64 * @param blockYamlObject the block content as a YAML object
66 protected void parse(final Map<String, Object> blockYamlObject) {
67 if (MapUtils.isEmpty(blockYamlObject)) {
70 final List<ConversionDefinition> conversionDefinitionList = transformation.getConversionDefinitionList();
71 final Map<String, Object> parsedBlockYamlObject = new HashMap<>();
72 final String blockName = blockYamlObject.keySet().iterator().next();
73 conversionDefinitionList.stream()
74 .filter(conversionDefinition -> conversionDefinition.getConversionQuery().isValidAttributeQuery())
75 .forEach(conversionDefinition -> {
76 final Map<String, Object> query =
77 (Map<String, Object>) conversionDefinition.getConversionQuery().getQuery();
78 final Map<String, Object> blockAttributeMap = (Map<String, Object>) blockYamlObject.get(blockName);
79 final Optional<Map<String, Object>> parsedBlockAttributeMap = buildParsedBlock(query, blockAttributeMap
80 , conversionDefinition);
81 parsedBlockAttributeMap.ifPresent(convertedNodeTemplateAttributeMap1 ->
82 mergeYamlObjects(parsedBlockYamlObject, convertedNodeTemplateAttributeMap1)
86 write(blockName, parsedBlockYamlObject);
90 * Writes the block in the resulting {@link ServiceTemplate} {@link #templateTo}.
92 * @param blockName the name of the block
93 * @param parsedBlockYamlObject the block content as a YAML object
95 protected abstract void write(final String blockName, final Map<String, Object> parsedBlockYamlObject);
98 * Uses the provided attribute query to find a attribute in the original YAML object and apply the provided
101 * @param attributeQuery the attribute query
102 * @param fromNodeTemplateAttributeMap the original YAML object
103 * @param conversionDefinition the conversion
104 * @return the rebuilt original YAML object with the converted attribute
106 protected abstract Optional<Map<String, Object>> buildParsedBlock(final Map<String, Object> attributeQuery,
107 final Map<String, Object> fromNodeTemplateAttributeMap,
108 final ConversionDefinition conversionDefinition);
111 * Merges two YAML objects.
113 * @param originalMap original YAML object
114 * @param toBeMergedMap YAML object to be merged
115 * @return the new YAML object representing the merge result.
117 protected Map<String, Object> mergeYamlObjects(final Map<String, Object> originalMap,
118 final Map<String, Object> toBeMergedMap) {
119 toBeMergedMap.forEach(
120 (key, value) -> originalMap.merge(key, value,
121 (toBeMergedValue, originalValue) -> {
122 if (originalValue instanceof Map) {
123 return mergeYamlObjects((Map) originalValue, (Map) toBeMergedValue);
125 return originalValue;
133 * Executes the provided {@link #transformation getConversionQuery} YAML query to find the blocks to be parsed in
134 * {@link #templateFrom}.
136 * @return The YAML blocks found
138 protected abstract Set<Map<String, Object>> findBlocksToParse();
141 * Checks if the YAML object is a TOSCA get_input call
143 * @param yamlObject the YAML object
144 * @return {@code true} if the YAML object is a TOSCA get_input call, {@code false} otherwise
146 protected boolean isGetInputFunction(final Object yamlObject) {
147 if (yamlObject instanceof Map) {
148 final Map<String, Object> yamlMap = (Map<String, Object>) yamlObject;
149 return yamlMap.containsKey(PnfTransformationToken.GET_INPUT.getName());
156 * Gets the value (input name) of a YAML object representing a TOSCA get_input call: "get_input: <i>value</i>".
158 * @param yamlObject the YAML object
159 * @return The get_input function value, that represents the input name
161 protected String extractGetInputFunctionValue(final Object yamlObject) {
162 if (yamlObject instanceof Map) {
163 final Map<String, Object> yamlMap = (Map<String, Object>) yamlObject;
164 return (String) yamlMap.values().stream().findFirst().orElse(null);
171 * Gets the stored input names called with TOSCA get_input function and its transformation configured in {@link
172 * ConversionDefinition#getToGetInput()}
174 public Optional<Map<String, String>> getInputAndTransformationNameMap() {
175 return Optional.empty();