Support complex types in interface operation inputs
[sdc.git] / catalog-be / src / test / java / org / openecomp / sdc / be / tosca / InterfacesOperationsConverterTest.java
1 /*
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2020 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
8  *
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.
15  *
16  *  SPDX-License-Identifier: Apache-2.0
17  *  ============LICENSE_END=========================================================
18  */
19
20 package org.openecomp.sdc.be.tosca;
21
22 import static org.hamcrest.MatcherAssert.assertThat;
23 import static org.hamcrest.Matchers.allOf;
24 import static org.hamcrest.Matchers.anEmptyMap;
25 import static org.hamcrest.Matchers.containsInAnyOrder;
26 import static org.hamcrest.Matchers.containsString;
27 import static org.hamcrest.Matchers.equalTo;
28 import static org.hamcrest.Matchers.is;
29 import static org.hamcrest.Matchers.nullValue;
30 import static org.junit.jupiter.api.Assertions.assertEquals;
31 import static org.junit.jupiter.api.Assertions.assertFalse;
32 import static org.junit.jupiter.api.Assertions.assertTrue;
33 import static org.junit.jupiter.api.Assertions.fail;
34 import static org.openecomp.sdc.be.tosca.InterfacesOperationsConverter.SELF;
35 import static org.openecomp.sdc.be.tosca.InterfacesOperationsConverter.addInterfaceTypeElement;
36 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DEFAULT;
37 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DESCRIPTION;
38 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.INPUTS;
39 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.INTERFACES;
40 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.NODE_TYPES;
41 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.REQUIRED;
42 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.TYPE;
43
44 import com.fasterxml.jackson.databind.DeserializationFeature;
45 import com.fasterxml.jackson.databind.ObjectMapper;
46 import com.google.gson.Gson;
47 import java.util.ArrayList;
48 import java.util.Collections;
49 import java.util.HashMap;
50 import java.util.List;
51 import java.util.Map;
52 import java.util.Map.Entry;
53 import java.util.Objects;
54 import java.util.function.Function;
55 import java.util.stream.Collectors;
56 import org.apache.commons.collections4.MapUtils;
57 import org.junit.jupiter.api.BeforeAll;
58 import org.junit.jupiter.api.BeforeEach;
59 import org.junit.jupiter.api.Test;
60 import org.onap.sdc.tosca.services.YamlUtil;
61 import org.openecomp.sdc.be.DummyConfigurationManager;
62 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
63 import org.openecomp.sdc.be.datatypes.elements.InputDataDefinition;
64 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
65 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
66 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
67 import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition;
68 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
69 import org.openecomp.sdc.be.model.Component;
70 import org.openecomp.sdc.be.model.DataTypeDefinition;
71 import org.openecomp.sdc.be.model.InputDefinition;
72 import org.openecomp.sdc.be.model.InterfaceDefinition;
73 import org.openecomp.sdc.be.model.Resource;
74 import org.openecomp.sdc.be.model.Service;
75 import org.openecomp.sdc.be.model.ServiceMetadataDefinition;
76 import org.openecomp.sdc.be.tosca.model.ToscaInterfaceDefinition;
77 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
78 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
79 import org.openecomp.sdc.common.util.YamlToObjectConverter;
80 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
81 import org.yaml.snakeyaml.Yaml;
82
83 class InterfacesOperationsConverterTest {
84
85     private static final String MAPPED_PROPERTY_NAME = "mapped_property";
86     private static final String INPUT_NAME_PREFIX = "input_";
87     private static final String OUTPUT_NAME_PREFIX = "output_";
88     private static final String NODE_TYPE_NAME = "test";
89     private final String[] inputTypes = {"string", "integer", "float", "boolean"};
90     private static ObjectMapper mapper;
91     private static final Map<String, DataTypeDefinition> dataTypes = new HashMap<>();
92
93     private InterfacesOperationsConverter interfacesOperationsConverter;
94
95     @BeforeAll
96     public static void setUp() {
97         //initialize the static configuration manager
98         new DummyConfigurationManager();
99         mapper = new ObjectMapper();
100         mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
101     }
102
103     @BeforeEach
104     public void setUpBeforeTest() {
105         interfacesOperationsConverter =
106             new InterfacesOperationsConverter(new PropertyConvertor());
107     }
108
109     @Test
110     void addInterfaceTypeElementToResource() {
111         Component component = new Resource();
112         component.setNormalizedName("normalizedComponentName");
113         component.setComponentMetadataDefinition(new ServiceMetadataDefinition());
114         component.getComponentMetadataDefinition().getMetadataDataDefinition().setName("NodeTypeName");
115         component.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName("NodeTypeName");
116         InterfaceDefinition addedInterface = new InterfaceDefinition();
117         addedInterface.setType("Local");
118         addOperationsToInterface(component, addedInterface, 5, 3, true, false);
119         final String interfaceType = "normalizedComponentName-interface";
120         component.setInterfaces(new HashMap<>());
121         component.getInterfaces().put(interfaceType, addedInterface);
122         final Map<String, Object> interfaceTypeElement =
123             addInterfaceTypeElement(component, new ArrayList<>());
124
125         ToscaExportHandler handler = new ToscaExportHandler(null, null, null, null, null, null, null, null, null, null,
126             interfacesOperationsConverter, null);
127         ToscaTemplate template = new ToscaTemplate("test");
128         template.setInterface_types(interfaceTypeElement);
129         final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template);
130
131         assertTrue(all(
132             containsAll("NodeTypeName"),
133             containsNone("operations")
134         ).apply(new String(toscaRepresentation.getMainYaml())));
135     }
136
137     @Test
138     void addInterfaceTypeElementToService() {
139         Component component = new Service();
140         component.setNormalizedName("normalizedServiceComponentName");
141         component.setComponentMetadataDefinition(new ServiceMetadataDefinition());
142         component.getComponentMetadataDefinition().getMetadataDataDefinition().setName("NodeTypeName");
143         component.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName("NodeTypeName");
144         InterfaceDefinition addedInterface = new InterfaceDefinition();
145         addedInterface.setType("Local");
146         addOperationsToInterface(component, addedInterface, 5, 3, true, false);
147         final String interfaceType = "normalizedServiceComponentName-interface";
148         component.setInterfaces(new HashMap<>());
149         component.getInterfaces().put(interfaceType, addedInterface);
150         final Map<String, Object> interfaceTypeElement =
151             addInterfaceTypeElement(component, new ArrayList<>());
152
153         ToscaExportHandler handler = new ToscaExportHandler(null, null, null, null, null, null, null, null, null, null,
154             interfacesOperationsConverter, null);
155         ToscaTemplate template = new ToscaTemplate("testService");
156         template.setInterface_types(interfaceTypeElement);
157         final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template);
158
159         assertTrue(all(
160             containsAll("NodeTypeName"),
161             containsNone("operations")
162         ).apply(new String(toscaRepresentation.getMainYaml())));
163     }
164
165     @Test
166     void addInterfaceDefinitionElementToResource() {
167         Component component = new Resource();
168         component.setNormalizedName("normalizedComponentName");
169         InterfaceDefinition addedInterface = new InterfaceDefinition();
170         addedInterface.setType("com.some.resource.or.other.resourceName");
171
172         addOperationsToInterface(component, addedInterface, 3, 2, true, false);
173         final String interfaceType = "normalizedComponentName-interface";
174         component.setInterfaces(new HashMap<>());
175         component.getInterfaces().put(interfaceType, addedInterface);
176         ToscaNodeType nodeType = new ToscaNodeType();
177         interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false);
178
179         ToscaExportHandler handler = new ToscaExportHandler(null, null, null, null, null, null, null, null, null, null,
180             interfacesOperationsConverter, null);
181         ToscaTemplate template = new ToscaTemplate(NODE_TYPE_NAME);
182         Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
183         nodeTypes.put(NODE_TYPE_NAME, nodeType);
184         template.setNode_types(nodeTypes);
185         final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template);
186
187         String mainYaml = new String(toscaRepresentation.getMainYaml());
188         assertTrue(all(
189             containsAll("resourceName:", "inputs:", "has description", MAPPED_PROPERTY_NAME, "com.some.resource.or.other.resourceName"),
190             containsNone("operations", "defaultp")
191         ).apply(mainYaml));
192
193         validateOperationInputs(mainYaml, 2, null);
194     }
195
196     @Test
197     void addInterfaceDefinitionElementToService() {
198         Component component = new Service();
199         component.setNormalizedName("normalizedServiceComponentName");
200         InterfaceDefinition addedInterface = new InterfaceDefinition();
201         addedInterface.setType("com.some.service.or.other.serviceName");
202         addOperationsToInterface(component, addedInterface, 3, 2, true, false);
203         final String interfaceType = "normalizedServiceComponentName-interface";
204         component.setInterfaces(new HashMap<>());
205         component.getInterfaces().put(interfaceType, addedInterface);
206         ToscaNodeType nodeType = new ToscaNodeType();
207         interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false);
208
209         ToscaExportHandler handler = new ToscaExportHandler(null, null, null, null, null, null, null, null, null, null, null, null);
210         ToscaTemplate template = new ToscaTemplate("testService");
211         Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
212         nodeTypes.put(NODE_TYPE_NAME, nodeType);
213         template.setNode_types(nodeTypes);
214         final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template);
215         String mainYaml = new String(toscaRepresentation.getMainYaml());
216         assertTrue(all(
217             containsAll("serviceName", "inputs:", "has description", MAPPED_PROPERTY_NAME, "com.some.service.or.other.serviceName"),
218             containsNone("operations", "defaultp")
219         ).apply(mainYaml));
220         validateOperationInputs(mainYaml, 2, null);
221     }
222
223
224     @Test
225     void testGetInterfaceAsMapServiceProxy() {
226         Component component = new Resource();
227         component.setNormalizedName("normalizedComponentName");
228         InterfaceDefinition addedInterface = new InterfaceDefinition();
229         addedInterface.setToscaResourceName("com.some.resource.or.other.resourceName");
230         addedInterface.setType("com.some.resource.or.other.resourceName");
231         addOperationsToInterface(component, addedInterface, 3, 2, true, false);
232         final String interfaceType = "normalizedComponentName-interface";
233         component.setInterfaces(new HashMap<>());
234         component.getInterfaces().put(interfaceType, addedInterface);
235         Map<String, Object> interfacesMap = interfacesOperationsConverter
236             .getInterfacesMap(component, null, component.getInterfaces(), null, false, true);
237         ToscaNodeType nodeType = new ToscaNodeType();
238         nodeType.setInterfaces(interfacesMap);
239         ToscaExportHandler handler = new ToscaExportHandler(null, null, null, null, null, null, null, null, null, null, null, null);
240         ToscaTemplate template = new ToscaTemplate(NODE_TYPE_NAME);
241         Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
242         nodeTypes.put(NODE_TYPE_NAME, nodeType);
243         template.setNode_types(nodeTypes);
244         final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template);
245
246         String mainYaml = new String(toscaRepresentation.getMainYaml());
247         assertTrue(all(
248             containsAll("resourceName:", "inputs:", "has description", MAPPED_PROPERTY_NAME, "com.some.resource.or.other.resourceName"),
249             containsNone("operations", "defaultp")
250         ).apply(mainYaml));
251         validateServiceProxyOperationInputs(mainYaml);
252     }
253
254     @Test
255     void addInterfaceDefinitionElement_noInputs() {
256         Component component = new Resource();
257         component.setNormalizedName("normalizedComponentName");
258         InterfaceDefinition addedInterface = new InterfaceDefinition();
259         addedInterface.setType("com.some.resource.or.other.resourceNameNoInputs");
260         addOperationsToInterface(component, addedInterface, 3, 3, false, false);
261         final String interfaceType = "normalizedComponentName-interface";
262         component.setInterfaces(new HashMap<>());
263         component.getInterfaces().put(interfaceType, addedInterface);
264         ToscaNodeType nodeType = new ToscaNodeType();
265         interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, null, false);
266
267         ToscaExportHandler handler = new ToscaExportHandler(null, null, null, null, null, null, null, null, null, null,
268             interfacesOperationsConverter, null);
269         ToscaTemplate template = new ToscaTemplate("test");
270         Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
271         nodeTypes.put("test", nodeType);
272         template.setNode_types(nodeTypes);
273         final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template);
274
275         assertTrue(all(
276             containsAll("resourceNameNoInputs", "has description", "com.some.resource.or.other.resourceName"),
277             containsNone("operations", INPUT_NAME_PREFIX, "defaultp")
278         ).apply(new String(toscaRepresentation.getMainYaml())));
279     }
280
281     @Test
282     void addInterfaceDefinitionElementInputMappedToOtherOperationOutput() {
283         String addedInterfaceType = "com.some.resource.or.other.resourceNameInputMappedToOutput";
284         Component component = new Resource();
285         component.setNormalizedName("normalizedComponentName");
286         InterfaceDefinition addedInterface = new InterfaceDefinition();
287         addedInterface.setType(addedInterfaceType);
288         addOperationsToInterface(component, addedInterface, 2, 2, true, true);
289         addedInterface.getOperationsMap().values().stream()
290             .filter(operationInputDefinition -> operationInputDefinition.getName().equalsIgnoreCase(
291                 "name_for_op_0"))
292             .forEach(operation -> operation.getInputs().getListToscaDataDefinition().stream()
293                 .filter(operationInputDefinition -> operationInputDefinition.getName().contains("integer"))
294                 .forEach(operationInputDefinition -> operationInputDefinition.setInputId(addedInterfaceType +
295                     ".name_for_op_1.output_integer_1")));
296         component.setInterfaces(new HashMap<>());
297         component.getInterfaces().put(addedInterfaceType, addedInterface);
298         ToscaNodeType nodeType = new ToscaNodeType();
299         interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false);
300
301         ToscaExportHandler handler = new ToscaExportHandler(null, null, null, null, null, null, null, null, null, null,
302             interfacesOperationsConverter, null);
303         ToscaTemplate template = new ToscaTemplate("test");
304         Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
305         nodeTypes.put("test", nodeType);
306         template.setNode_types(nodeTypes);
307         final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template);
308         String mainYaml = new String(toscaRepresentation.getMainYaml());
309         assertTrue(all(
310             containsAll("resourceNameInputMappedToOutput:", "inputs:"),
311             containsNone("operations")
312         ).apply(mainYaml));
313         validateOperationInputs(mainYaml, 2, "name_for_op_1");
314     }
315
316     @Test
317     void addInterfaceDefinitionElementInputMappedToOtherOperationOutputFromOtherInterface() {
318         String addedInterfaceType = "com.some.resource.or.other.resourceNameInputMappedToOutput";
319         Component component = new Resource();
320         component.setNormalizedName("normalizedComponentName");
321         InterfaceDefinition addedInterface = new InterfaceDefinition();
322         addedInterface.setType(addedInterfaceType);
323         addOperationsToInterface(component, addedInterface, 2, 2, true, true);
324         addedInterface.getOperationsMap().values().stream()
325             .filter(operationInputDefinition -> operationInputDefinition.getName().equalsIgnoreCase(
326                 "name_for_op_0"))
327             .forEach(operation -> operation.getInputs().getListToscaDataDefinition().stream()
328                 .filter(opInputDef -> opInputDef.getName().contains("integer"))
329                 .forEach(opInputDef -> opInputDef.setInputId(
330                     addedInterfaceType + ".name_for_op_1.output_integer_1")));
331         //Mapping to operation from another interface
332         String secondInterfaceType = "org.test.lifecycle.standard.interfaceType.second";
333         InterfaceDefinition secondInterface = new InterfaceDefinition();
334         secondInterface.setType(secondInterfaceType);
335         addOperationsToInterface(component, secondInterface, 2, 2, true, true);
336         secondInterface.getOperationsMap().values().stream()
337             .filter(operationInputDefinition -> operationInputDefinition.getName().equalsIgnoreCase(
338                 "name_for_op_0"))
339             .forEach(operation -> operation.getInputs().getListToscaDataDefinition().stream()
340                 .filter(opInputDef -> opInputDef.getName().contains("integer"))
341                 .forEach(opInputDef -> opInputDef.setInputId(
342                     addedInterfaceType + ".name_for_op_1.output_integer_1")));
343         component.setInterfaces(new HashMap<>());
344         component.getInterfaces().put(addedInterfaceType, addedInterface);
345         component.getInterfaces().put(secondInterfaceType, secondInterface);
346
347         ToscaNodeType nodeType = new ToscaNodeType();
348         interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false);
349
350         ToscaExportHandler handler = new ToscaExportHandler(null, null, null, null, null, null, null, null, null, null,
351             interfacesOperationsConverter, null);
352         ToscaTemplate template = new ToscaTemplate("test");
353         Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
354         nodeTypes.put("test", nodeType);
355         template.setNode_types(nodeTypes);
356         final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template);
357
358         String mainYaml = new String(toscaRepresentation.getMainYaml());
359         assertTrue(all(
360             containsAll("resourceNameInputMappedToOutput:", "inputs:"),
361             containsNone("operations")
362         ).apply(mainYaml));
363         validateOperationInputs(mainYaml, 2, "name_for_op_1");
364     }
365
366     @Test
367     void interfaceWithInputsToscaExportTest() {
368         final Component component = new Service();
369         final InterfaceDefinition aInterfaceWithInput = new InterfaceDefinition();
370         final String interfaceName = "myInterfaceName";
371         final String interfaceType = "my.type." + interfaceName;
372         aInterfaceWithInput.setType(interfaceType);
373         final String input1Name = "input1";
374         final InputDataDefinition input1 = createInput("string", "input1 description", false, "input1 value");
375         final String input2Name = "input2";
376         final InputDataDefinition input2 = createInput("string", "input2 description", true, "input2 value");
377         final Map<String, InputDataDefinition> inputMap = new HashMap<>();
378         inputMap.put(input1Name, input1);
379         inputMap.put(input2Name, input2);
380         aInterfaceWithInput.setInputs(inputMap);
381         component.setInterfaces(new HashMap<>());
382         component.getInterfaces().put(interfaceName, aInterfaceWithInput);
383         final ToscaNodeType nodeType = new ToscaNodeType();
384         interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false);
385         final ToscaExportHandler handler = new ToscaExportHandler(null, null, null, null, null, null, null, null, null, null,
386             interfacesOperationsConverter, null);
387         final ToscaTemplate template = new ToscaTemplate("testService");
388         final Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
389         nodeTypes.put(NODE_TYPE_NAME, nodeType);
390         template.setNode_types(nodeTypes);
391         final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template);
392         final String toscaTemplateYaml = new String(toscaRepresentation.getMainYaml());
393         assertThat(toscaTemplateYaml,
394             allOf(containsString(INPUTS.getElementName() + ":"), containsString(input1Name), containsString(interfaceName)));
395         validateInterfaceInputs(toscaTemplateYaml, interfaceName, inputMap);
396     }
397
398     private void validateInterfaceInputs(final String yaml, final String interfaceName, final Map<String, InputDataDefinition> expectedInputMap) {
399         String fixedMainYaml = yaml;
400         final String nullString = "null";
401         if (fixedMainYaml.startsWith(nullString)) {
402             fixedMainYaml = yaml.substring(nullString.length());
403         }
404         if (fixedMainYaml.endsWith(nullString)) {
405             fixedMainYaml = fixedMainYaml.substring(0, fixedMainYaml.length() - nullString.length());
406         }
407         final Map<String, Object> yamlMap = (Map<String, Object>) new Yaml().load(fixedMainYaml);
408         final Map<String, Object> nodeTypesMap = (Map<String, Object>) yamlMap.get(NODE_TYPES.getElementName());
409         final Map<String, Object> node = (Map<String, Object>) nodeTypesMap.get(NODE_TYPE_NAME);
410         final Map<String, Object> interfacesMap = (Map<String, Object>) node.get(INTERFACES.getElementName());
411         final Map<String, Object> interface1 = (Map<String, Object>) interfacesMap.get(interfaceName);
412         final Map<String, Object> actualInputsMap = (Map<String, Object>) interface1.get(INPUTS.getElementName());
413         assertThat(actualInputsMap.keySet(), containsInAnyOrder(expectedInputMap.keySet().toArray()));
414         expectedInputMap.forEach((inputName, inputDataDefinition) -> {
415             final Map<String, Object> actualInput = (Map<String, Object>) actualInputsMap.get(inputName);
416             compareInputYaml(inputName, actualInput, inputDataDefinition);
417         });
418     }
419
420     private void compareInputYaml(final String inputName, final Map<String, Object> actualInput,
421                                   final InputDataDefinition expectedInput) {
422         final String msgFormat = "%s should be equal in input %s";
423         String field = TYPE.getElementName();
424         assertThat(String.format(msgFormat, field, inputName),
425             actualInput.get(field), equalTo(expectedInput.getType()));
426         field = DESCRIPTION.getElementName();
427         assertThat(String.format(msgFormat, field, inputName),
428             actualInput.get(field), equalTo(expectedInput.getDescription()));
429         field = REQUIRED.getElementName();
430         assertThat(String.format(msgFormat, field, inputName),
431             actualInput.get(field), equalTo(expectedInput.getRequired()));
432         field = DEFAULT.getElementName();
433         assertThat(String.format(msgFormat, field, inputName),
434             actualInput.get(field), equalTo(expectedInput.getDefaultValue()));
435     }
436
437     @FunctionalInterface
438     interface MainYamlAssertion extends Function<String, Boolean> {}
439
440     private static Function<String, Boolean> all(MainYamlAssertion... fs) {
441         return s -> io.vavr.collection.List.of(fs).map(f -> f.apply(s)).fold(true, (l, r) -> l && r);
442     }
443
444     private static MainYamlAssertion containsNone(String... expected) {
445         return s -> io.vavr.collection.List.of(expected).map(e -> !s.contains(e)).fold(true, (l, r) -> l && r);
446     }
447
448     private static MainYamlAssertion containsAll(String... expected) {
449         return s -> io.vavr.collection.List.of(expected).map(s::contains).fold(true, (l, r) -> l && r);
450     }
451
452     private void addOperationsToInterface(Component component, InterfaceDefinition addedInterface, int numOfOps,
453                                           int numOfInputsPerOp, boolean hasInputs, boolean hasOutputs) {
454
455         addedInterface.setOperations(new HashMap<>());
456         for (int i = 0; i < numOfOps; i++) {
457             final OperationDataDefinition operation = new OperationDataDefinition();
458             operation.setName("name_for_op_" + i);
459             operation.setDescription("op " + i + " has description");
460             final ArtifactDataDefinition implementation = new ArtifactDataDefinition();
461             implementation.setArtifactName(i + "_createBPMN.bpmn");
462             operation.setImplementation(implementation);
463             if (hasInputs) {
464                 operation.setInputs(createInputs(component, numOfInputsPerOp));
465             }
466             if (hasOutputs) {
467                 operation.setOutputs(createOutputs(addedInterface.getToscaResourceName(),
468                     operation.getName(), numOfInputsPerOp));
469             }
470             addedInterface.getOperations().put(operation.getName(), operation);
471         }
472     }
473
474     private InputDataDefinition createInput(final String type, final String description, final Boolean isRequired,
475                                             final String defaultValue) {
476         final PropertyDataDefinition propertyDataDefinition = new PropertyDataDefinition();
477         if (type != null) {
478             propertyDataDefinition.setType(type);
479         }
480         if (description != null) {
481             propertyDataDefinition.setDescription(description);
482         }
483         if (defaultValue != null) {
484             propertyDataDefinition.setDefaultValue(defaultValue);
485         }
486         if (isRequired != null) {
487             propertyDataDefinition.setRequired(isRequired);
488         }
489         return new InputDataDefinition(propertyDataDefinition);
490     }
491
492     private ListDataDefinition<OperationInputDefinition> createInputs(Component component, int numOfInputs) {
493         ListDataDefinition<OperationInputDefinition> operationInputDefinitionList = new ListDataDefinition<>();
494         for (int i = 0; i < numOfInputs; i++) {
495             String mappedPropertyName = java.util.UUID.randomUUID() + "." + MAPPED_PROPERTY_NAME + i;
496             operationInputDefinitionList.add(createMockOperationInputDefinition(
497                 INPUT_NAME_PREFIX + inputTypes[i] + "_" + i, mappedPropertyName, i));
498             addMappedPropertyAsComponentInput(component, mappedPropertyName);
499
500         }
501         return operationInputDefinitionList;
502     }
503
504     private void addMappedPropertyAsComponentInput(Component component, String mappedPropertyName) {
505         InputDefinition componentInput = new InputDefinition();
506         componentInput.setUniqueId(mappedPropertyName.split("\\.")[0]);
507         componentInput.setName(mappedPropertyName.split("\\.")[1]);
508         if (Objects.isNull(component.getInputs())) {
509             component.setInputs(new ArrayList<>());
510         }
511         component.getInputs().add(componentInput);
512     }
513
514     private ListDataDefinition<OperationOutputDefinition> createOutputs(String interfaceName,
515                                                                         String operationName,
516                                                                         int numOfOutputs) {
517         ListDataDefinition<OperationOutputDefinition> operationOutputDefinitionList = new ListDataDefinition<>();
518         for (int i = 0; i < numOfOutputs; i++) {
519             operationOutputDefinitionList.add(createMockOperationOutputDefinition(interfaceName, operationName,
520                 OUTPUT_NAME_PREFIX + inputTypes[i] + "_" + i, i));
521         }
522         return operationOutputDefinitionList;
523     }
524
525     private OperationInputDefinition createMockOperationInputDefinition(String name, String id, int index) {
526         OperationInputDefinition operationInputDefinition = new OperationInputDefinition();
527         operationInputDefinition.setName(name);
528         operationInputDefinition.setInputId(id);
529         operationInputDefinition.setType(inputTypes[index]);
530         operationInputDefinition.setRequired(index % 2 == 0);
531         Map<String, List<String>> toscaDefaultValueMap = new HashMap<>();
532         List<String> toscaDefaultValues = new ArrayList<>();
533         toscaDefaultValues.add(SELF);
534         toscaDefaultValues.add(id.substring(id.lastIndexOf('.') + 1));
535         toscaDefaultValueMap.put(ToscaFunctions.GET_PROPERTY.getFunctionName(), toscaDefaultValues);
536         operationInputDefinition.setToscaDefaultValue(new Gson().toJson(toscaDefaultValueMap));
537         operationInputDefinition.setSource("ServiceInput");
538         return operationInputDefinition;
539     }
540
541     private OperationOutputDefinition createMockOperationOutputDefinition(String interfaceName, String operationName,
542                                                                           String outputName, int index) {
543         OperationOutputDefinition operationInputDefinition = new OperationOutputDefinition();
544         operationInputDefinition.setName(outputName);
545         operationInputDefinition.setType(inputTypes[index]);
546         operationInputDefinition.setRequired(index % 2 == 0);
547         List<String> toscaDefaultValues = new ArrayList<>();
548         toscaDefaultValues.add(SELF);
549         toscaDefaultValues.add(interfaceName);
550         toscaDefaultValues.add(operationName);
551         toscaDefaultValues.add(outputName);
552         Map<String, List<String>> toscaDefaultValueMap = new HashMap<>();
553         toscaDefaultValueMap.put(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName(), toscaDefaultValues);
554         return operationInputDefinition;
555     }
556
557     private void validateOperationInputs(final String mainYaml, int numOfInputsPerOp, String mappedOperationName) {
558         String nodeTypeKey = NODE_TYPE_NAME + ":";
559         String nodeTypesRepresentation = mainYaml.substring(mainYaml.indexOf(nodeTypeKey) + nodeTypeKey.length(),
560             mainYaml.lastIndexOf(MAPPED_PROPERTY_NAME) + MAPPED_PROPERTY_NAME.length()
561                 + String.valueOf(numOfInputsPerOp).length());
562         YamlToObjectConverter objectConverter = new YamlToObjectConverter();
563         ToscaNodeType toscaNodeType = objectConverter.convert(nodeTypesRepresentation.getBytes(), ToscaNodeType.class);
564         Map<String, Object> interfaces = toscaNodeType.getInterfaces();
565         for (Map.Entry<String, Object> interfaceEntry : interfaces.entrySet()) {
566             Map<String, Object> interfaceDefinition = mapper.convertValue(interfaceEntry.getValue(), Map.class);
567             final Map<String, Object> operationsMap = interfaceDefinition.entrySet().stream()
568                 .filter(entry -> !INPUTS.getElementName().equals(entry.getKey()) &&
569                     !TYPE.getElementName().equals(entry.getKey()))
570                 .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
571             for (Map.Entry<String, Object> operationEntry : operationsMap.entrySet()) {
572                 Object operationVal = operationEntry.getValue();
573                 if (operationVal instanceof Map) {
574                     //Since the inputs are mapped to output operations from only first interface so using that name
575                     validateOperationInputDefinition(interfaces.keySet().iterator().next(), mappedOperationName,
576                         operationVal);
577                 }
578             }
579         }
580     }
581
582     private void validateOperationInputDefinition(String interfaceType, String operationName, Object operationVal) {
583         Map<String, Object> operation = mapper.convertValue(operationVal, Map.class);
584         Map<String, Object> inputs = (Map<String, Object>) operation.get("inputs");
585         for (Map.Entry<String, Object> inputEntry : inputs.entrySet()) {
586             String[] inputNameSplit = inputEntry.getKey().split("_");
587             Map<String, Object> inputValueObject = (Map<String, Object>) inputEntry.getValue();
588             validateOperationInputDefinitionDefaultValue(interfaceType, operationName, inputNameSplit[1],
589                 Integer.parseInt(inputNameSplit[2]), inputValueObject);
590         }
591     }
592
593
594     private void validateOperationInputDefinitionDefaultValue(String interfaceType, String operationName,
595                                                               String inputType, int index,
596                                                               Map<String, Object> inputValueObject) {
597         if (inputValueObject.containsKey(ToscaFunctions.GET_PROPERTY.getFunctionName())) {
598             String mappedPropertyValue = MAPPED_PROPERTY_NAME + index;
599             List<String> mappedPropertyDefaultValue = (List<String>) inputValueObject
600                 .get(ToscaFunctions.GET_PROPERTY.getFunctionName());
601             assertEquals(2, mappedPropertyDefaultValue.size());
602             assertTrue(mappedPropertyDefaultValue.contains(SELF));
603             assertTrue(mappedPropertyDefaultValue.contains(mappedPropertyValue));
604         } else if (inputValueObject.containsKey(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName())) {
605             List<String> mappedPropertyDefaultValue = (List<String>) inputValueObject
606                 .get(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName());
607             assertEquals(4, mappedPropertyDefaultValue.size());
608             String mappedPropertyValue = OUTPUT_NAME_PREFIX + inputType + "_" + index;
609             assertTrue(mappedPropertyDefaultValue.contains(SELF));
610             assertTrue(mappedPropertyDefaultValue.contains(interfaceType));
611             assertTrue(mappedPropertyDefaultValue.contains(operationName));
612             assertTrue(mappedPropertyDefaultValue.contains(mappedPropertyValue));
613         } else {
614             fail("Invalid Tosca function in default value. Allowed values: " + ToscaFunctions.GET_PROPERTY.getFunctionName() +
615                 "/" + ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName());
616         }
617     }
618
619     private void validateServiceProxyOperationInputs(String mainYaml) {
620         String nodeTypeKey = NODE_TYPE_NAME + ":";
621         String nodeTypesRepresentation = mainYaml.substring(mainYaml.indexOf(nodeTypeKey) + nodeTypeKey.length(),
622             mainYaml.lastIndexOf(MAPPED_PROPERTY_NAME) + MAPPED_PROPERTY_NAME.length());
623         YamlUtil yamlUtil = new YamlUtil();
624         ToscaNodeType toscaNodeType = yamlUtil.yamlToObject(nodeTypesRepresentation, ToscaNodeType.class);
625         for (Object interfaceVal : toscaNodeType.getInterfaces().values()) {
626             Map<String, Object> interfaceDefinition = mapper.convertValue(interfaceVal, Map.class);
627             for (Object operationVal : interfaceDefinition.values()) {
628                 if (operationVal instanceof Map) {
629                     Map<String, Object> operation = (Map<String, Object>) mapper.convertValue(operationVal, Map.class);
630                     Map<String, Object> operationInputs = (Map<String, Object>) operation.get("inputs");
631                     for (Object inputValue : operationInputs.values()) {
632                         Map<String, Object> inputValueAsMap = (Map<String, Object>) inputValue;
633                         assertFalse(inputValueAsMap.keySet().contains("type"));
634                         assertFalse(inputValueAsMap.keySet().contains("required"));
635                         assertFalse(inputValueAsMap.keySet().contains("default"));
636                     }
637                 }
638             }
639         }
640     }
641
642     @Test
643     void testAddInterfaceTypeElementGetCorrectLocalInterfaceName() {
644         Service service = new Service();
645         service.setComponentMetadataDefinition(new ServiceMetadataDefinition());
646         service.getComponentMetadataDefinition().getMetadataDataDefinition().setName("LocalInterface");
647         service.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName("LocalInterface");
648         service.setInterfaces(Collections.singletonMap("Local", new InterfaceDefinition("Local", null, new HashMap<>())));
649
650         Map<String, Object> resultMap = InterfacesOperationsConverter.addInterfaceTypeElement(service,
651             Collections.singletonList("org.openecomp.interfaces.node.lifecycle.Standard"));
652
653         assertTrue(MapUtils.isNotEmpty(resultMap)
654             && resultMap.containsKey("org.openecomp.interfaces.node.lifecycle.LocalInterface"));
655     }
656
657     @Test
658     void testAddInterfaceTypeElementNoTypeChangeIfNotLocal() {
659         Service service = new Service();
660         service.setComponentMetadataDefinition(new ServiceMetadataDefinition());
661         service.getComponentMetadataDefinition().getMetadataDataDefinition().setName("LocalInterface");
662         service.setInterfaces(Collections.singletonMap("NotLocal", new InterfaceDefinition("NotLocal", null,
663             new HashMap<>())));
664
665         Map<String, Object> resultMap = interfacesOperationsConverter.getInterfacesMap(service, null,
666             service.getInterfaces(), null, false, false);
667
668         assertTrue(MapUtils.isNotEmpty(resultMap)
669             && resultMap.containsKey("NotLocal"));
670     }
671
672     @Test
673     void testRemoveInterfacesWithoutOperationsEmptyMap() {
674         final Map<String, Object> interfaceMap = new HashMap<>();
675         interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
676         assertThat(interfaceMap, is(anEmptyMap()));
677     }
678
679     @Test
680     void testRemoveInterfacesWithoutOperationsNullParameter() {
681         final Map<String, Object> interfaceMap = null;
682         interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
683         assertThat(interfaceMap, is(nullValue()));
684     }
685
686     @Test
687     void testRemoveInterfacesWithoutOperationsSuccess() {
688         final Map<String, Object> interfaceMap = new HashMap<>();
689         final ToscaInterfaceDefinition toscaInterfaceDefinition1 = new ToscaInterfaceDefinition();
690         interfaceMap.put("toscaInterfaceDefinition1", toscaInterfaceDefinition1);
691
692         final ToscaInterfaceDefinition toscaInterfaceDefinition2 = new ToscaInterfaceDefinition();
693         final Map<String, Object> toscaInterfaceDefinition2OperationMap = new HashMap<>();
694         toscaInterfaceDefinition2OperationMap.put("operation1", new Object());
695         toscaInterfaceDefinition2.setOperations(toscaInterfaceDefinition2OperationMap);
696         interfaceMap.put("toscaInterfaceDefinition2", toscaInterfaceDefinition2);
697
698         final Map<String, Object> toscaInterfaceDefinition3 = new HashMap<>();
699         interfaceMap.put("toscaInterfaceDefinition3", toscaInterfaceDefinition3);
700
701         final Map<String, Object> toscaInterfaceDefinition4 = new HashMap<>();
702         toscaInterfaceDefinition4.put("operation1", new Object());
703         interfaceMap.put("toscaInterfaceDefinition4", toscaInterfaceDefinition4);
704
705         final Object notAToscaInterfaceDefinition = new Object();
706         interfaceMap.put("notAToscaInterfaceDefinition", notAToscaInterfaceDefinition);
707
708         interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
709         assertFalse(interfaceMap.containsKey("toscaInterfaceDefinition1"));
710         assertTrue(interfaceMap.containsKey("toscaInterfaceDefinition2"));
711         assertFalse(interfaceMap.containsKey("toscaInterfaceDefinition3"));
712         assertTrue(interfaceMap.containsKey("toscaInterfaceDefinition4"));
713         assertTrue(interfaceMap.containsKey("notAToscaInterfaceDefinition"));
714     }
715 }