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