74aed124710ca1c7b431624f3c483bbc8b6c7511
[sdc.git] / common-be / src / main / java / org / openecomp / sdc / be / datatypes / elements / ToscaFunctionJsonDeserializer.java
1 /*
2  * -
3  *  ============LICENSE_START=======================================================
4  *  Copyright (C) 2022 Nordix Foundation.
5  *  ================================================================================
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *       http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  *
18  *  SPDX-License-Identifier: Apache-2.0
19  *  ============LICENSE_END=========================================================
20  */
21
22 package org.openecomp.sdc.be.datatypes.elements;
23
24 import com.fasterxml.jackson.core.JsonParser;
25 import com.fasterxml.jackson.databind.DeserializationContext;
26 import com.fasterxml.jackson.databind.JsonMappingException;
27 import com.fasterxml.jackson.databind.JsonNode;
28 import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
29 import java.io.IOException;
30 import java.util.ArrayList;
31 import java.util.List;
32 import org.apache.commons.lang3.StringUtils;
33 import org.openecomp.sdc.be.datatypes.enums.PropertySource;
34 import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType;
35 import org.yaml.snakeyaml.Yaml;
36
37 public class ToscaFunctionJsonDeserializer extends StdDeserializer<ToscaFunction> {
38
39     public ToscaFunctionJsonDeserializer() {
40         this(null);
41     }
42
43     public ToscaFunctionJsonDeserializer(Class<?> vc) {
44         super(vc);
45     }
46
47     @Override
48     public ToscaFunction deserialize(final JsonParser jsonParser, final DeserializationContext context) throws IOException {
49         final JsonNode node = jsonParser.getCodec().readTree(jsonParser);
50         return deserializeToscaFunction(node, context);
51     }
52
53     private ToscaFunction deserializeToscaFunction(final JsonNode node, final DeserializationContext context) throws IOException {
54         final String functionType;
55         if (node.get("type") != null) {
56             functionType = node.get("type").asText();
57         } else if (node.get("functionType") != null) {
58             //support for legacy tosca function
59             functionType = node.get("functionType").asText();
60         } else {
61             throw context.instantiationException(ToscaFunction.class, "Attribute type not provided");
62         }
63         final ToscaFunctionType toscaFunctionType = ToscaFunctionType.findType(functionType)
64             .orElseThrow(() -> context.instantiationException(ToscaFunction.class,
65                 String.format("Invalid function type '%s' or attribute type not provided", functionType))
66             );
67         if (toscaFunctionType == ToscaFunctionType.GET_INPUT || toscaFunctionType == ToscaFunctionType.GET_ATTRIBUTE
68             || toscaFunctionType == ToscaFunctionType.GET_PROPERTY) {
69             return deserializeToscaGetFunction(toscaFunctionType, node, context);
70         }
71
72         if (toscaFunctionType == ToscaFunctionType.CONCAT) {
73             return this.deserializeConcatFunction(node, context);
74         }
75
76         if (toscaFunctionType == ToscaFunctionType.YAML) {
77             return this.deserializeYamlFunction(node);
78         }
79
80         return null;
81     }
82
83     private ToscaFunction deserializeYamlFunction(JsonNode node) {
84         var yamlFunction = new CustomYamlFunction();
85         final Object value = new Yaml().load(node.get("value").asText());
86         yamlFunction.setYamlValue(value);
87         return yamlFunction;
88     }
89
90     private ToscaGetFunctionDataDefinition deserializeToscaGetFunction(final ToscaFunctionType toscaFunctionType, final JsonNode node,
91                                                                        final DeserializationContext context) throws JsonMappingException {
92         final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition();
93         toscaGetFunction.setFunctionType(ToscaGetFunctionType.fromToscaFunctionType(toscaFunctionType).orElse(null));
94         toscaGetFunction.setSourceName(node.get("sourceName").asText());
95         toscaGetFunction.setPropertyUniqueId(node.get("propertyUniqueId").asText());
96         final String propertySource = node.get("propertySource").asText();
97         if (StringUtils.isNotEmpty(propertySource)) {
98             final PropertySource propertySource1 = PropertySource.findType(propertySource).orElseThrow(() ->
99                 context.instantiationException(ToscaGetFunctionDataDefinition.class,
100                     String.format("Invalid propertySource '%s'", propertySource))
101             );
102             toscaGetFunction.setPropertySource(propertySource1);
103         }
104         toscaGetFunction.setPropertyName(node.get("propertyName").asText());
105         toscaGetFunction.setSourceName(node.get("sourceName").asText());
106         toscaGetFunction.setSourceUniqueId(node.get("sourceUniqueId").asText());
107         final JsonNode propertyPathFromSourceNode = node.get("propertyPathFromSource");
108         if (propertyPathFromSourceNode != null) {
109             if (!propertyPathFromSourceNode.isArray()) {
110                 throw context.instantiationException(ToscaGetFunctionDataDefinition.class, "Expecting an array for propertyPathFromSource attribute");
111             }
112             final List<String> pathFromSource = new ArrayList<>();
113             propertyPathFromSourceNode.forEach(jsonNode -> pathFromSource.add(jsonNode.asText()));
114             toscaGetFunction.setPropertyPathFromSource(pathFromSource);
115         }
116
117         return toscaGetFunction;
118     }
119
120     private ToscaConcatFunction deserializeConcatFunction(final JsonNode concatFunctionJsonNode,
121                                                           final DeserializationContext context) throws IOException {
122         final var toscaConcatFunction = new ToscaConcatFunction();
123         final List<ToscaFunctionParameter> functionParameterList = new ArrayList<>();
124         final JsonNode parametersNode = concatFunctionJsonNode.get("parameters");
125         if (!parametersNode.isArray()) {
126             throw context.instantiationException(List.class, "");
127         }
128         for (final JsonNode parameterNode : parametersNode) {
129             final JsonNode typeJsonNode = parameterNode.get("type");
130             if (typeJsonNode == null) {
131                 throw context.instantiationException(ToscaConcatFunction.class, "TOSCA concat function parameter type attribute not provided");
132             }
133             final String parameterType = typeJsonNode.asText();
134             final ToscaFunctionType toscaFunctionType = ToscaFunctionType.findType(parameterType)
135                 .orElseThrow(() -> context.instantiationException(ToscaConcatFunction.class,
136                     String.format("Invalid TOSCA concat function parameter type '%s'", parameterType))
137                 );
138             if (toscaFunctionType == ToscaFunctionType.STRING) {
139                 final ToscaStringParameter toscaStringParameter = new ToscaStringParameter();
140                 toscaStringParameter.setValue(parameterNode.get("value").asText());
141                 functionParameterList.add(toscaStringParameter);
142             } else {
143                 final ToscaFunction toscaFunction = this.deserializeToscaFunction(parameterNode, context);
144                 functionParameterList.add((ToscaFunctionParameter) toscaFunction);
145             }
146         }
147         toscaConcatFunction.setParameters(functionParameterList);
148         return toscaConcatFunction;
149     }
150
151 }