2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.sdc.toscaparser.api.functions;
24 import org.onap.sdc.toscaparser.api.TopologyTemplate;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.LinkedHashMap;
31 public abstract class Function {
33 protected static final String GET_PROPERTY = "get_property";
34 protected static final String GET_ATTRIBUTE = "get_attribute";
35 protected static final String GET_INPUT = "get_input";
36 protected static final String GET_OPERATION_OUTPUT = "get_operation_output";
37 protected static final String CONCAT = "concat";
38 protected static final String TOKEN = "token";
40 protected static final String SELF = "SELF";
41 protected static final String HOST = "HOST";
42 protected static final String TARGET = "TARGET";
43 protected static final String SOURCE = "SOURCE";
45 protected static final String HOSTED_ON = "tosca.relationships.HostedOn";
47 protected static HashMap<String, String> functionMappings = _getFunctionMappings();
49 private static HashMap<String, String> _getFunctionMappings() {
50 HashMap<String, String> map = new HashMap<>();
51 map.put(GET_PROPERTY, "GetProperty");
52 map.put(GET_INPUT, "GetInput");
53 map.put(GET_ATTRIBUTE, "GetAttribute");
54 map.put(GET_OPERATION_OUTPUT, "GetOperationOutput");
55 map.put(CONCAT, "Concat");
56 map.put(TOKEN, "Token");
60 protected TopologyTemplate toscaTpl;
61 protected Object context;
62 protected String name;
63 protected ArrayList<Object> args;
66 public Function(TopologyTemplate _toscaTpl, Object _context, String _name, ArrayList<Object> _args) {
75 abstract Object result();
77 abstract void validate();
79 @SuppressWarnings("unchecked")
80 public static boolean isFunction(Object funcObj) {
81 // Returns True if the provided function is a Tosca intrinsic function.
85 //* "{ get_property: { SELF, port } }"
86 //* "{ get_input: db_name }"
89 //:param function: Function as string or a Function instance.
90 //:return: True if function is a Tosca intrinsic function, otherwise False.
93 if (funcObj instanceof LinkedHashMap) {
94 LinkedHashMap<String, Object> function = (LinkedHashMap<String, Object>) funcObj;
95 if (function.size() == 1) {
96 String funcName = (new ArrayList<String>(function.keySet())).get(0);
97 return functionMappings.keySet().contains(funcName);
100 return (funcObj instanceof Function);
103 @SuppressWarnings("unchecked")
104 public static Object getFunction(TopologyTemplate ttpl, Object context, Object rawFunctionObj, boolean resolveGetInput) {
105 // Gets a Function instance representing the provided template function.
107 // If the format provided raw_function format is not relevant for template
108 // functions or if the function name doesn't exist in function mapping the
109 // method returns the provided raw_function.
111 // :param tosca_tpl: The tosca template.
112 // :param node_template: The node template the function is specified for.
113 // :param raw_function: The raw function as dict.
114 // :return: Template function as Function instance or the raw_function if
115 // parsing was unsuccessful.
118 // iterate over leaves of the properties's tree and convert function leaves to function object,
119 // support List and Map nested,
120 // assuming that leaf value of function is always map type contains 1 item (e.g. my_leaf: {get_input: xxx}).
122 if (rawFunctionObj instanceof LinkedHashMap) { // In map type case
123 LinkedHashMap rawFunction = ((LinkedHashMap) rawFunctionObj);
124 if (rawFunction.size() == 1 &&
125 !(rawFunction.values().iterator().next() instanceof LinkedHashMap)) { // End point
126 return getFunctionForObjectItem(ttpl, context, rawFunction, resolveGetInput);
128 return getFunctionForMap(ttpl, context, rawFunction, resolveGetInput);
130 } else if (rawFunctionObj instanceof ArrayList) { // In list type case
131 return getFunctionForList(ttpl, context, (ArrayList) rawFunctionObj, resolveGetInput);
134 return rawFunctionObj;
137 private static Object getFunctionForList(TopologyTemplate ttpl, Object context, ArrayList rawFunctionObj, boolean resolveGetInput) {
138 // iterate over list properties in recursion, convert leaves to function,
139 // and collect them in the same hierarchy as the original list.
140 ArrayList<Object> rawFunctionObjList = new ArrayList<>();
141 for (Object rawFunctionObjItem : rawFunctionObj) {
142 rawFunctionObjList.add(getFunction(ttpl, context, rawFunctionObjItem, resolveGetInput));
144 return rawFunctionObjList;
147 private static Object getFunctionForMap(TopologyTemplate ttpl, Object context, LinkedHashMap rawFunction, boolean resolveGetInput) {
148 // iterate over map nested properties in recursion, convert leaves to function,
149 // and collect them in the same hierarchy as the original map.
150 LinkedHashMap rawFunctionObjMap = new LinkedHashMap();
151 for (Object rawFunctionObjItem : rawFunction.entrySet()) {
152 Object itemValue = getFunction(ttpl, context, ((Map.Entry) rawFunctionObjItem).getValue(), resolveGetInput);
153 rawFunctionObjMap.put(((Map.Entry) rawFunctionObjItem).getKey(), itemValue);
155 return rawFunctionObjMap;
158 private static Object getFunctionForObjectItem(TopologyTemplate ttpl, Object context, Object rawFunctionObjItem, boolean resolveGetInput) {
159 if (isFunction(rawFunctionObjItem)) {
160 LinkedHashMap<String, Object> rawFunction = (LinkedHashMap<String, Object>) rawFunctionObjItem;
161 String funcName = (new ArrayList<String>(rawFunction.keySet())).get(0);
162 if (functionMappings.keySet().contains(funcName)) {
163 String funcType = functionMappings.get(funcName);
164 Object oargs = (new ArrayList<Object>(rawFunction.values())).get(0);
165 ArrayList<Object> funcArgs;
166 if (oargs instanceof ArrayList) {
167 funcArgs = (ArrayList<Object>) oargs;
169 funcArgs = new ArrayList<>();
175 if (resolveGetInput) {
176 GetInput input = new GetInput(ttpl, context, funcName, funcArgs);
177 return input.result();
179 return new GetInput(ttpl, context, funcName, funcArgs);
181 return new GetAttribute(ttpl, context, funcName, funcArgs);
183 return new GetProperty(ttpl, context, funcName, funcArgs);
184 case "GetOperationOutput":
185 return new GetOperationOutput(ttpl, context, funcName, funcArgs);
187 return new Concat(ttpl, context, funcName, funcArgs);
189 return new Token(ttpl, context, funcName, funcArgs);
194 return rawFunctionObjItem;
198 public String toString() {
199 String argsStr = args.size() > 1 ? args.toString() : args.get(0).toString();
200 return name + ":" + argsStr;
206 from toscaparser.common.exception import ValidationIsshueCollector
207 from toscaparser.common.exception import UnknownInputError
208 from toscaparser.dataentity import DataEntity
209 from toscaparser.elements.constraints import Schema
210 from toscaparser.elements.datatype import DataType
211 from toscaparser.elements.entity_type import EntityType
212 from toscaparser.elements.relationshiptype import RelationshipType
213 from toscaparser.elements.statefulentitytype import StatefulEntityType
214 from toscaparser.utils.gettextutils import _
217 GET_PROPERTY = 'get_property'
218 GET_ATTRIBUTE = 'get_attribute'
219 GET_INPUT = 'get_input'
220 GET_OPERATION_OUTPUT = 'get_operation_output'
229 HOSTED_ON = 'tosca.relationships.HostedOn'
232 @six.add_metaclass(abc.ABCMeta)
233 class Function(object):
234 """An abstract type for representing a Tosca template function."""
236 def __init__(self, tosca_tpl, context, name, args):
237 self.tosca_tpl = tosca_tpl
238 self.context = context
245 """Invokes the function and returns its result
247 Some methods invocation may only be relevant on runtime (for example,
248 getting runtime properties) and therefore its the responsibility of
249 the orchestrator/translator to take care of such functions invocation.
251 :return: Function invocation result.
253 return {self.name: self.args}
257 """Validates function arguments."""