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.impl.pnfd.parser;
22 import static org.openecomp.core.converter.pnfd.model.PnfTransformationToken.CONVERSIONS;
23 import static org.openecomp.core.converter.pnfd.model.PnfTransformationToken.DESCRIPTION;
24 import static org.openecomp.core.converter.pnfd.model.PnfTransformationToken.FROM;
25 import static org.openecomp.core.converter.pnfd.model.PnfTransformationToken.NAME;
26 import static org.openecomp.core.converter.pnfd.model.PnfTransformationToken.PROPERTIES;
27 import static org.openecomp.core.converter.pnfd.model.PnfTransformationToken.QUERY;
28 import static org.openecomp.core.converter.pnfd.model.PnfTransformationToken.TO;
29 import static org.openecomp.core.converter.pnfd.model.PnfTransformationToken.TRANSFORMATION_FOR;
31 import java.util.ArrayList;
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.HashSet;
35 import java.util.List;
37 import java.util.Objects;
38 import java.util.Optional;
40 import java.util.stream.Collectors;
41 import org.apache.commons.collections.CollectionUtils;
42 import org.apache.commons.collections.MapUtils;
43 import org.openecomp.core.converter.impl.pnfd.strategy.ReplaceConversionStrategy;
44 import org.openecomp.core.converter.pnfd.model.ConversionDefinition;
45 import org.openecomp.core.converter.pnfd.model.ConversionQuery;
46 import org.openecomp.core.converter.pnfd.model.Transformation;
47 import org.openecomp.core.converter.pnfd.model.TransformationBlock;
48 import org.openecomp.core.converter.pnfd.model.TransformationProperty;
49 import org.openecomp.core.converter.pnfd.model.TransformationPropertyType;
50 import org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum;
51 import org.openecomp.sdc.logging.api.Logger;
52 import org.openecomp.sdc.logging.api.LoggerFactory;
55 * Handles YAML from/to {@link Transformation} conversions
57 public class TransformationYamlParser {
59 private static final Logger LOGGER = LoggerFactory.getLogger(TransformationYamlParser.class);
61 private TransformationYamlParser() {
66 * Parses the given YAML object to a {@link Transformation} instance.
67 * @param transformationYaml the YAML object representing a transformation
69 * A new instance of {@link Transformation}.
71 public static Optional<Transformation> parse(final Map<String, Object> transformationYaml) {
72 final Transformation transformation = new Transformation();
73 final Optional<String> name = parseStringAttribute(NAME.getName(), transformationYaml);
74 if (!name.isPresent()) {
75 LOGGER.warn("Invalid '{}' value in transformation '{}'", NAME.getName(), transformationYaml.toString());
77 transformation.setName(name.orElse(null));
78 transformation.setDescription(parseStringAttribute(DESCRIPTION.getName(), transformationYaml).orElse(null));
79 transformation.setPropertySet(readProperties(transformationYaml));
81 final String block = parseStringAttribute(TRANSFORMATION_FOR.getName(), transformationYaml).orElse(null);
82 final Optional<TransformationBlock> transformationBlockOptional = TransformationBlock.parse(block);
83 if (transformationBlockOptional.isPresent()) {
84 final TransformationBlock transformationBlock = transformationBlockOptional.get();
85 transformation.setBlock(transformationBlock);
86 parseTransformationBlock(transformationBlock, transformation, transformationYaml);
88 LOGGER.warn("Invalid '{}' value in transformation '{}'", TRANSFORMATION_FOR.getName(),
89 transformationYaml.toString());
92 if (transformation.isValid()) {
93 return Optional.of(transformation);
96 return Optional.empty();
99 private static Set<TransformationProperty> readProperties(final Map<String, Object> transformationYaml) {
100 final Map<String, Object> propertyMap = (Map<String, Object>) transformationYaml.get(PROPERTIES.getName());
101 if (MapUtils.isEmpty(propertyMap)) {
102 return Collections.emptySet();
105 final Set<TransformationProperty> propertySet = new HashSet<>();
107 propertyMap.forEach((key, value) -> {
108 final TransformationPropertyType transformationPropertyType = TransformationPropertyType.parse(key)
111 if(transformationPropertyType != null) {
112 if (value instanceof String) {
113 propertySet.add(new TransformationProperty<>(transformationPropertyType, (String) value));
114 } else if (value instanceof Boolean) {
115 propertySet.add(new TransformationProperty<>(transformationPropertyType, (Boolean) value));
116 } else if (value instanceof Integer) {
117 propertySet.add(new TransformationProperty<>(transformationPropertyType, (Integer) value));
119 propertySet.add(new TransformationProperty<>(transformationPropertyType, value));
127 private static void parseTransformationBlock(final TransformationBlock transformationBlock,
128 final Transformation transformationReference,
129 final Map<String, Object> transformationYaml) {
130 if (transformationBlock == TransformationBlock.CUSTOM_NODE_TYPE) {
131 parseCustomNodeTypeBlock(transformationReference, transformationYaml);
135 ConversionQueryYamlParser.parse(transformationYaml.get(QUERY.getName()))
136 .ifPresent(transformationReference::setConversionQuery);
138 transformationReference.setConversionDefinitionList(parseConversions(transformationYaml));
141 private static void parseCustomNodeTypeBlock(final Transformation transformationReference,
142 final Map<String, Object> transformationYaml) {
143 final Object fromAttribute = transformationYaml.get(FROM.getName());
144 if (!(fromAttribute instanceof String)) {
147 final String from = parseStringAttribute(FROM.getName(), transformationYaml).orElse(null);
149 final Object toAttribute = transformationYaml.get(TO.getName());
150 if (!(toAttribute instanceof String)) {
153 final String to = parseStringAttribute(TO.getName(), transformationYaml).orElse(null);
155 final HashMap<String, String> transformationQuery = new HashMap<>();
156 transformationQuery.put(ToscaTagNamesEnum.DERIVED_FROM.getElementName(), from);
157 transformationReference.setConversionQuery(new ConversionQuery(transformationQuery));
159 final List<ConversionDefinition> conversionDefinitionList = new ArrayList<>();
160 final HashMap<String, String> conversionDefinitionQuery = new HashMap<>();
161 conversionDefinitionQuery.put(ToscaTagNamesEnum.TYPE.getElementName(), null);
162 ConversionDefinition conversionDefinition = new ConversionDefinition(new ConversionQuery(conversionDefinitionQuery)
163 , ToscaTagNamesEnum.TYPE.getElementName(), new ReplaceConversionStrategy(from, to));
164 conversionDefinitionList.add(conversionDefinition);
165 transformationReference.setConversionDefinitionList(conversionDefinitionList);
168 private static List<ConversionDefinition> parseConversions(final Map<String, Object> conversionYaml) {
169 final List<Object> conversionList = (List<Object>) conversionYaml.get(CONVERSIONS.getName());
171 if (CollectionUtils.isEmpty(conversionList)) {
172 return Collections.emptyList();
175 return conversionList.stream()
176 .map(conversion -> ConversionDefinitionYamlParser.parse((Map<String, Object>) conversion).orElse(null))
177 .filter(Objects::nonNull)
178 .collect(Collectors.toList());
181 private static Optional<String> parseStringAttribute(final String attribute, final Map<String, Object> transformationYaml) {
183 return Optional.of((String) transformationYaml.get(attribute));
184 } catch (final Exception e) {
185 LOGGER.warn("Could not parse the String '{}' in transformation '{}'",
186 attribute, transformationYaml.toString(), e);
187 return Optional.empty();