Support complex types in artifact properties
[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.datatypes.elements.SchemaDefinition;
70 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
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.model.tosca.ToscaType;
79 import org.openecomp.sdc.be.tosca.model.ToscaInterfaceDefinition;
80 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
81 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
82 import org.openecomp.sdc.common.util.YamlToObjectConverter;
83 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
84 import org.yaml.snakeyaml.Yaml;
85
86 class InterfacesOperationsConverterTest {
87
88     private static final String MAPPED_PROPERTY_NAME = "mapped_property";
89     private static final String INPUT_NAME_PREFIX = "input_";
90     private static final String OUTPUT_NAME_PREFIX = "output_";
91     private static final String NODE_TYPE_NAME = "test";
92     private final String[] inputTypes = {"string", "integer", "float", "boolean"};
93     private static ObjectMapper mapper;
94     private static final Map<String, DataTypeDefinition> dataTypes = new HashMap<>();
95
96     private InterfacesOperationsConverter interfacesOperationsConverter;
97
98     @BeforeAll
99     public static void setUp() {
100         //initialize the static configuration manager
101         new DummyConfigurationManager();
102         mapper = new ObjectMapper();
103         mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
104     }
105
106     @BeforeEach
107     public void setUpBeforeTest() {
108         interfacesOperationsConverter =
109             new InterfacesOperationsConverter(new PropertyConvertor());
110     }
111
112     @Test
113     void addInterfaceTypeElementToResource() {
114         Component component = new Resource();
115         component.setNormalizedName("normalizedComponentName");
116         component.setComponentMetadataDefinition(new ServiceMetadataDefinition());
117         component.getComponentMetadataDefinition().getMetadataDataDefinition().setName("NodeTypeName");
118         component.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName("NodeTypeName");
119         InterfaceDefinition addedInterface = new InterfaceDefinition();
120         addedInterface.setType("Local");
121         addOperationsToInterface(component, addedInterface, 5, 3, true, false);
122         final String interfaceType = "normalizedComponentName-interface";
123         component.setInterfaces(new HashMap<>());
124         component.getInterfaces().put(interfaceType, addedInterface);
125         final Map<String, Object> interfaceTypeElement =
126             addInterfaceTypeElement(component, new ArrayList<>());
127
128         ToscaExportHandler handler = new ToscaExportHandler(null, null, null, null, null, null, null, null, null, null,
129             interfacesOperationsConverter, null);
130         ToscaTemplate template = new ToscaTemplate("test");
131         template.setInterface_types(interfaceTypeElement);
132         final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template);
133
134         assertTrue(all(
135             containsAll("NodeTypeName"),
136             containsNone("operations")
137         ).apply(new String(toscaRepresentation.getMainYaml())));
138     }
139
140     @Test
141     void addInterfaceTypeElementToService() {
142         Component component = new Service();
143         component.setNormalizedName("normalizedServiceComponentName");
144         component.setComponentMetadataDefinition(new ServiceMetadataDefinition());
145         component.getComponentMetadataDefinition().getMetadataDataDefinition().setName("NodeTypeName");
146         component.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName("NodeTypeName");
147         InterfaceDefinition addedInterface = new InterfaceDefinition();
148         addedInterface.setType("Local");
149         addOperationsToInterface(component, addedInterface, 5, 3, true, false);
150         final String interfaceType = "normalizedServiceComponentName-interface";
151         component.setInterfaces(new HashMap<>());
152         component.getInterfaces().put(interfaceType, addedInterface);
153         final Map<String, Object> interfaceTypeElement =
154             addInterfaceTypeElement(component, new ArrayList<>());
155
156         ToscaExportHandler handler = new ToscaExportHandler(null, null, null, null, null, null, null, null, null, null,
157             interfacesOperationsConverter, null);
158         ToscaTemplate template = new ToscaTemplate("testService");
159         template.setInterface_types(interfaceTypeElement);
160         final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template);
161
162         assertTrue(all(
163             containsAll("NodeTypeName"),
164             containsNone("operations")
165         ).apply(new String(toscaRepresentation.getMainYaml())));
166     }
167
168     @Test
169     void addInterfaceDefinitionElementToResource() {
170         Component component = new Resource();
171         component.setNormalizedName("normalizedComponentName");
172         InterfaceDefinition addedInterface = new InterfaceDefinition();
173         addedInterface.setType("com.some.resource.or.other.resourceName");
174
175         addOperationsToInterface(component, addedInterface, 3, 2, true, false);
176         final String interfaceType = "normalizedComponentName-interface";
177         component.setInterfaces(new HashMap<>());
178         component.getInterfaces().put(interfaceType, addedInterface);
179         ToscaNodeType nodeType = new ToscaNodeType();
180         interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false);
181
182         ToscaExportHandler handler = new ToscaExportHandler(null, null, null, null, null, null, null, null, null, null,
183             interfacesOperationsConverter, null);
184         ToscaTemplate template = new ToscaTemplate(NODE_TYPE_NAME);
185         Map<String, ToscaNodeType> nodeTypes = new HashMap<>();
186         nodeTypes.put(NODE_TYPE_NAME, nodeType);
187         template.setNode_types(nodeTypes);
188         final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template);
189
190         String mainYaml = new String(toscaRepresentation.getMainYaml());
191         assertTrue(all(
192             containsAll("resourceName:", "inputs:", "has description", MAPPED_PROPERTY_NAME, "com.some.resource.or.other.resourceName"),
193             containsNone("operations", "defaultp")
194         ).apply(mainYaml));
195
196         validateOperationInputs(mainYaml, 2, null);
197     }
198
199     @Test
200     void addInterfaceDefinitionElementToService() {
201         Component component = new Service();
202         component.setNormalizedName("normalizedServiceComponentName");
203         InterfaceDefinition addedInterface = new InterfaceDefinition();
204         addedInterface.setType("com.some.service.or.other.serviceName");
205         addOperationsToInterface(component, addedInterface, 3, 2, true, false);
206         final String interfaceType = "normalizedServiceComponentName-interface";
207         component.setInterfaces(new HashMap<>());
208         component.getInterfaces().put(interfaceType, addedInterface);
209         ToscaNodeType nodeType = new ToscaNodeType();
210         interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false);
211
212         ToscaExportHandler handler = new ToscaExportHandler(null, null, null, null, null, null, null, null, null, null, null, null);
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(null, null, null, null, null, null, null, null, null, null, null, null);
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, null,
271             interfacesOperationsConverter, null);
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, null,
305             interfacesOperationsConverter, null);
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, null,
354             interfacesOperationsConverter, null);
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 anInterfaceWithInput = new InterfaceDefinition();
373         final String interfaceName = "myInterfaceName";
374         final String interfaceType = "my.type." + interfaceName;
375         anInterfaceWithInput.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         anInterfaceWithInput.setInputs(inputMap);
384         component.setInterfaces(new HashMap<>());
385         component.getInterfaces().put(interfaceName, anInterfaceWithInput);
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, null,
389             interfacesOperationsConverter, null);
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,
397             allOf(containsString(INPUTS.getElementName() + ":"), containsString(input1Name), containsString(interfaceName)));
398         validateInterfaceInputs(toscaTemplateYaml, interfaceName, inputMap);
399     }
400
401     @Test
402     void interfaceWithOperationImplementationArtifactPropertiesTest() {
403         //given
404         final Component component = new Service();
405         final InterfaceDefinition interfaceDefinition = new InterfaceDefinition();
406         final String interfaceName = "myInterfaceName";
407         interfaceDefinition.setType("my.type." + interfaceName);
408         final var operation1DataDefinition = new OperationDataDefinition();
409         operation1DataDefinition.setName("anOperation");
410
411         final PropertyDataDefinition listOfStringProperty = new PropertyDataDefinition();
412         listOfStringProperty.setName("listProperty");
413         listOfStringProperty.setType(ToscaType.LIST.getType());
414         final PropertyDataDefinition listOfStringSchemaProperty = new PropertyDataDefinition();
415         listOfStringSchemaProperty.setType(ToscaType.STRING.getType());
416         final SchemaDefinition listPropertySchema = new SchemaDefinition();
417         listPropertySchema.setProperty(listOfStringProperty);
418         listOfStringProperty.setSchema(listPropertySchema);
419         listOfStringProperty.setValue("[ \"value1\", \"value2\", \"value3\" ]");
420         final ArrayList<Object> propertyList = new ArrayList<>();
421         propertyList.add(listOfStringProperty);
422         final HashMap<String, Object> artifactDefinitionMapInitializer = new HashMap<>();
423         artifactDefinitionMapInitializer.put(JsonPresentationFields.PROPERTIES.getPresentation(), propertyList);
424         final ArtifactDataDefinition artifactDataDefinition = new ArtifactDataDefinition(artifactDefinitionMapInitializer);
425         artifactDataDefinition.setArtifactName("artifact1");
426         artifactDataDefinition.setArtifactType("my.artifact.Type");
427         operation1DataDefinition.setImplementation(artifactDataDefinition);
428         interfaceDefinition.setOperations(Map.of(operation1DataDefinition.getName(), operation1DataDefinition));
429         component.setInterfaces(new HashMap<>());
430         component.getInterfaces().put(interfaceName, interfaceDefinition);
431         //when
432         Map<String, Object> interfacesMap = interfacesOperationsConverter
433             .getInterfacesMap(component, null, component.getInterfaces(), null, false, true);
434         //then
435         assertTrue(interfacesMap.containsKey(interfaceName));
436         final Map<String, Object> actualInterfaceMap = (Map<String, Object>) interfacesMap.get(interfaceName);
437         assertTrue(actualInterfaceMap.containsKey(operation1DataDefinition.getName()));
438         final Map<String, Object> actualOperationMap = (Map<String, Object>) actualInterfaceMap.get(operation1DataDefinition.getName());
439         assertTrue(actualOperationMap.containsKey("implementation"));
440         final Map<String, Object> actualImplementationMap = (Map<String, Object>) actualOperationMap.get("implementation");
441         assertTrue(actualImplementationMap.containsKey("primary"));
442         final Map<String, Object> actualArtifactImplementationMap = (Map<String, Object>) actualImplementationMap.get("primary");
443         assertTrue(actualArtifactImplementationMap.containsKey("properties"));
444         final Map<String, Object> actualArtifactPropertiesMap = (Map<String, Object>) actualArtifactImplementationMap.get("properties");
445         assertEquals(actualArtifactPropertiesMap.keySet().size(), 1);
446         assertTrue(actualArtifactPropertiesMap.containsKey(listOfStringProperty.getName()));
447         final Object expectedListObject = actualArtifactPropertiesMap.get(listOfStringProperty.getName());
448         assertTrue(expectedListObject instanceof List);
449         final List<String> expectedListOfStringPropValue = (List<String>) expectedListObject;
450         assertEquals(expectedListOfStringPropValue.size(), 3);
451         assertTrue(expectedListOfStringPropValue.contains("value1"));
452         assertTrue(expectedListOfStringPropValue.contains("value2"));
453         assertTrue(expectedListOfStringPropValue.contains("value3"));
454     }
455
456
457     private void validateInterfaceInputs(final String yaml, final String interfaceName, final Map<String, InputDataDefinition> expectedInputMap) {
458         String fixedMainYaml = yaml;
459         final String nullString = "null";
460         if (fixedMainYaml.startsWith(nullString)) {
461             fixedMainYaml = yaml.substring(nullString.length());
462         }
463         if (fixedMainYaml.endsWith(nullString)) {
464             fixedMainYaml = fixedMainYaml.substring(0, fixedMainYaml.length() - nullString.length());
465         }
466         final Map<String, Object> yamlMap = new Yaml().load(fixedMainYaml);
467         final Map<String, Object> nodeTypesMap = (Map<String, Object>) yamlMap.get(NODE_TYPES.getElementName());
468         final Map<String, Object> node = (Map<String, Object>) nodeTypesMap.get(NODE_TYPE_NAME);
469         final Map<String, Object> interfacesMap = (Map<String, Object>) node.get(INTERFACES.getElementName());
470         final Map<String, Object> interface1 = (Map<String, Object>) interfacesMap.get(interfaceName);
471         final Map<String, Object> actualInputsMap = (Map<String, Object>) interface1.get(INPUTS.getElementName());
472         assertThat(actualInputsMap.keySet(), containsInAnyOrder(expectedInputMap.keySet().toArray()));
473         expectedInputMap.forEach((inputName, inputDataDefinition) -> {
474             final Map<String, Object> actualInput = (Map<String, Object>) actualInputsMap.get(inputName);
475             compareInputYaml(inputName, actualInput, inputDataDefinition);
476         });
477     }
478
479     private void compareInputYaml(final String inputName, final Map<String, Object> actualInput,
480                                   final InputDataDefinition expectedInput) {
481         final String msgFormat = "%s should be equal in input %s";
482         String field = TYPE.getElementName();
483         assertThat(String.format(msgFormat, field, inputName),
484             actualInput.get(field), equalTo(expectedInput.getType()));
485         field = DESCRIPTION.getElementName();
486         assertThat(String.format(msgFormat, field, inputName),
487             actualInput.get(field), equalTo(expectedInput.getDescription()));
488         field = REQUIRED.getElementName();
489         assertThat(String.format(msgFormat, field, inputName),
490             actualInput.get(field), equalTo(expectedInput.getRequired()));
491         field = DEFAULT.getElementName();
492         assertThat(String.format(msgFormat, field, inputName),
493             actualInput.get(field), equalTo(expectedInput.getDefaultValue()));
494     }
495
496     @FunctionalInterface
497     interface MainYamlAssertion extends Function<String, Boolean> {}
498
499     private static Function<String, Boolean> all(MainYamlAssertion... fs) {
500         return s -> io.vavr.collection.List.of(fs).map(f -> f.apply(s)).fold(true, (l, r) -> l && r);
501     }
502
503     private static MainYamlAssertion containsNone(String... expected) {
504         return s -> io.vavr.collection.List.of(expected).map(e -> !s.contains(e)).fold(true, (l, r) -> l && r);
505     }
506
507     private static MainYamlAssertion containsAll(String... expected) {
508         return s -> io.vavr.collection.List.of(expected).map(s::contains).fold(true, (l, r) -> l && r);
509     }
510
511     private void addOperationsToInterface(Component component, InterfaceDefinition addedInterface, int numOfOps,
512                                           int numOfInputsPerOp, boolean hasInputs, boolean hasOutputs) {
513
514         addedInterface.setOperations(new HashMap<>());
515         for (int i = 0; i < numOfOps; i++) {
516             final OperationDataDefinition operation = new OperationDataDefinition();
517             operation.setName("name_for_op_" + i);
518             operation.setDescription("op " + i + " has description");
519             final ArtifactDataDefinition implementation = new ArtifactDataDefinition();
520             implementation.setArtifactName(i + "_createBPMN.bpmn");
521             operation.setImplementation(implementation);
522             if (hasInputs) {
523                 operation.setInputs(createInputs(component, numOfInputsPerOp));
524             }
525             if (hasOutputs) {
526                 operation.setOutputs(createOutputs(addedInterface.getToscaResourceName(),
527                     operation.getName(), numOfInputsPerOp));
528             }
529             addedInterface.getOperations().put(operation.getName(), operation);
530         }
531     }
532
533     private InputDataDefinition createInput(final String type, final String description, final Boolean isRequired,
534                                             final String defaultValue) {
535         final PropertyDataDefinition propertyDataDefinition = new PropertyDataDefinition();
536         if (type != null) {
537             propertyDataDefinition.setType(type);
538         }
539         if (description != null) {
540             propertyDataDefinition.setDescription(description);
541         }
542         if (defaultValue != null) {
543             propertyDataDefinition.setDefaultValue(defaultValue);
544         }
545         if (isRequired != null) {
546             propertyDataDefinition.setRequired(isRequired);
547         }
548         return new InputDataDefinition(propertyDataDefinition);
549     }
550
551     private ListDataDefinition<OperationInputDefinition> createInputs(Component component, int numOfInputs) {
552         ListDataDefinition<OperationInputDefinition> operationInputDefinitionList = new ListDataDefinition<>();
553         for (int i = 0; i < numOfInputs; i++) {
554             String mappedPropertyName = java.util.UUID.randomUUID() + "." + MAPPED_PROPERTY_NAME + i;
555             operationInputDefinitionList.add(createMockOperationInputDefinition(
556                 INPUT_NAME_PREFIX + inputTypes[i] + "_" + i, mappedPropertyName, i));
557             addMappedPropertyAsComponentInput(component, mappedPropertyName);
558
559         }
560         return operationInputDefinitionList;
561     }
562
563     private void addMappedPropertyAsComponentInput(Component component, String mappedPropertyName) {
564         InputDefinition componentInput = new InputDefinition();
565         componentInput.setUniqueId(mappedPropertyName.split("\\.")[0]);
566         componentInput.setName(mappedPropertyName.split("\\.")[1]);
567         if (Objects.isNull(component.getInputs())) {
568             component.setInputs(new ArrayList<>());
569         }
570         component.getInputs().add(componentInput);
571     }
572
573     private ListDataDefinition<OperationOutputDefinition> createOutputs(String interfaceName,
574                                                                         String operationName,
575                                                                         int numOfOutputs) {
576         ListDataDefinition<OperationOutputDefinition> operationOutputDefinitionList = new ListDataDefinition<>();
577         for (int i = 0; i < numOfOutputs; i++) {
578             operationOutputDefinitionList.add(createMockOperationOutputDefinition(interfaceName, operationName,
579                 OUTPUT_NAME_PREFIX + inputTypes[i] + "_" + i, i));
580         }
581         return operationOutputDefinitionList;
582     }
583
584     private OperationInputDefinition createMockOperationInputDefinition(String name, String id, int index) {
585         OperationInputDefinition operationInputDefinition = new OperationInputDefinition();
586         operationInputDefinition.setName(name);
587         operationInputDefinition.setInputId(id);
588         operationInputDefinition.setType(inputTypes[index]);
589         operationInputDefinition.setRequired(index % 2 == 0);
590         Map<String, List<String>> toscaDefaultValueMap = new HashMap<>();
591         List<String> toscaDefaultValues = new ArrayList<>();
592         toscaDefaultValues.add(SELF);
593         toscaDefaultValues.add(id.substring(id.lastIndexOf('.') + 1));
594         toscaDefaultValueMap.put(ToscaFunctions.GET_PROPERTY.getFunctionName(), toscaDefaultValues);
595         operationInputDefinition.setToscaDefaultValue(new Gson().toJson(toscaDefaultValueMap));
596         operationInputDefinition.setSource("ServiceInput");
597         return operationInputDefinition;
598     }
599
600     private OperationOutputDefinition createMockOperationOutputDefinition(String interfaceName, String operationName,
601                                                                           String outputName, int index) {
602         OperationOutputDefinition operationInputDefinition = new OperationOutputDefinition();
603         operationInputDefinition.setName(outputName);
604         operationInputDefinition.setType(inputTypes[index]);
605         operationInputDefinition.setRequired(index % 2 == 0);
606         List<String> toscaDefaultValues = new ArrayList<>();
607         toscaDefaultValues.add(SELF);
608         toscaDefaultValues.add(interfaceName);
609         toscaDefaultValues.add(operationName);
610         toscaDefaultValues.add(outputName);
611         Map<String, List<String>> toscaDefaultValueMap = new HashMap<>();
612         toscaDefaultValueMap.put(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName(), toscaDefaultValues);
613         return operationInputDefinition;
614     }
615
616     private void validateOperationInputs(final String mainYaml, int numOfInputsPerOp, String mappedOperationName) {
617         String nodeTypeKey = NODE_TYPE_NAME + ":";
618         String nodeTypesRepresentation = mainYaml.substring(mainYaml.indexOf(nodeTypeKey) + nodeTypeKey.length(),
619             mainYaml.lastIndexOf(MAPPED_PROPERTY_NAME) + MAPPED_PROPERTY_NAME.length()
620                 + String.valueOf(numOfInputsPerOp).length());
621         YamlToObjectConverter objectConverter = new YamlToObjectConverter();
622         ToscaNodeType toscaNodeType = objectConverter.convert(nodeTypesRepresentation.getBytes(), ToscaNodeType.class);
623         Map<String, Object> interfaces = toscaNodeType.getInterfaces();
624         for (Map.Entry<String, Object> interfaceEntry : interfaces.entrySet()) {
625             Map<String, Object> interfaceDefinition = mapper.convertValue(interfaceEntry.getValue(), Map.class);
626             final Map<String, Object> operationsMap = interfaceDefinition.entrySet().stream()
627                 .filter(entry -> !INPUTS.getElementName().equals(entry.getKey()) &&
628                     !TYPE.getElementName().equals(entry.getKey()))
629                 .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
630             for (Map.Entry<String, Object> operationEntry : operationsMap.entrySet()) {
631                 Object operationVal = operationEntry.getValue();
632                 if (operationVal instanceof Map) {
633                     //Since the inputs are mapped to output operations from only first interface so using that name
634                     validateOperationInputDefinition(interfaces.keySet().iterator().next(), mappedOperationName,
635                         operationVal);
636                 }
637             }
638         }
639     }
640
641     private void validateOperationInputDefinition(String interfaceType, String operationName, Object operationVal) {
642         Map<String, Object> operation = mapper.convertValue(operationVal, Map.class);
643         Map<String, Object> inputs = (Map<String, Object>) operation.get("inputs");
644         for (Map.Entry<String, Object> inputEntry : inputs.entrySet()) {
645             String[] inputNameSplit = inputEntry.getKey().split("_");
646             Map<String, Object> inputValueObject = (Map<String, Object>) inputEntry.getValue();
647             validateOperationInputDefinitionDefaultValue(interfaceType, operationName, inputNameSplit[1],
648                 Integer.parseInt(inputNameSplit[2]), inputValueObject);
649         }
650     }
651
652
653     private void validateOperationInputDefinitionDefaultValue(String interfaceType, String operationName,
654                                                               String inputType, int index,
655                                                               Map<String, Object> inputValueObject) {
656         if (inputValueObject.containsKey(ToscaFunctions.GET_PROPERTY.getFunctionName())) {
657             String mappedPropertyValue = MAPPED_PROPERTY_NAME + index;
658             List<String> mappedPropertyDefaultValue = (List<String>) inputValueObject
659                 .get(ToscaFunctions.GET_PROPERTY.getFunctionName());
660             assertEquals(2, mappedPropertyDefaultValue.size());
661             assertTrue(mappedPropertyDefaultValue.contains(SELF));
662             assertTrue(mappedPropertyDefaultValue.contains(mappedPropertyValue));
663         } else if (inputValueObject.containsKey(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName())) {
664             List<String> mappedPropertyDefaultValue = (List<String>) inputValueObject
665                 .get(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName());
666             assertEquals(4, mappedPropertyDefaultValue.size());
667             String mappedPropertyValue = OUTPUT_NAME_PREFIX + inputType + "_" + index;
668             assertTrue(mappedPropertyDefaultValue.contains(SELF));
669             assertTrue(mappedPropertyDefaultValue.contains(interfaceType));
670             assertTrue(mappedPropertyDefaultValue.contains(operationName));
671             assertTrue(mappedPropertyDefaultValue.contains(mappedPropertyValue));
672         } else {
673             fail("Invalid Tosca function in default value. Allowed values: " + ToscaFunctions.GET_PROPERTY.getFunctionName() +
674                 "/" + ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName());
675         }
676     }
677
678     private void validateServiceProxyOperationInputs(String mainYaml) {
679         String nodeTypeKey = NODE_TYPE_NAME + ":";
680         String nodeTypesRepresentation = mainYaml.substring(mainYaml.indexOf(nodeTypeKey) + nodeTypeKey.length(),
681             mainYaml.lastIndexOf(MAPPED_PROPERTY_NAME) + MAPPED_PROPERTY_NAME.length());
682         YamlUtil yamlUtil = new YamlUtil();
683         ToscaNodeType toscaNodeType = yamlUtil.yamlToObject(nodeTypesRepresentation, ToscaNodeType.class);
684         for (Object interfaceVal : toscaNodeType.getInterfaces().values()) {
685             Map<String, Object> interfaceDefinition = mapper.convertValue(interfaceVal, Map.class);
686             for (Object operationVal : interfaceDefinition.values()) {
687                 if (operationVal instanceof Map) {
688                     Map<String, Object> operation = (Map<String, Object>) mapper.convertValue(operationVal, Map.class);
689                     Map<String, Object> operationInputs = (Map<String, Object>) operation.get("inputs");
690                     for (Object inputValue : operationInputs.values()) {
691                         Map<String, Object> inputValueAsMap = (Map<String, Object>) inputValue;
692                         assertFalse(inputValueAsMap.keySet().contains("type"));
693                         assertFalse(inputValueAsMap.keySet().contains("required"));
694                         assertFalse(inputValueAsMap.keySet().contains("default"));
695                     }
696                 }
697             }
698         }
699     }
700
701     @Test
702     void testAddInterfaceTypeElementGetCorrectLocalInterfaceName() {
703         Service service = new Service();
704         service.setComponentMetadataDefinition(new ServiceMetadataDefinition());
705         service.getComponentMetadataDefinition().getMetadataDataDefinition().setName("LocalInterface");
706         service.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName("LocalInterface");
707         service.setInterfaces(Collections.singletonMap("Local", new InterfaceDefinition("Local", null, new HashMap<>())));
708
709         Map<String, Object> resultMap = InterfacesOperationsConverter.addInterfaceTypeElement(service,
710             Collections.singletonList("org.openecomp.interfaces.node.lifecycle.Standard"));
711
712         assertTrue(MapUtils.isNotEmpty(resultMap)
713             && resultMap.containsKey("org.openecomp.interfaces.node.lifecycle.LocalInterface"));
714     }
715
716     @Test
717     void testAddInterfaceTypeElementNoTypeChangeIfNotLocal() {
718         Service service = new Service();
719         service.setComponentMetadataDefinition(new ServiceMetadataDefinition());
720         service.getComponentMetadataDefinition().getMetadataDataDefinition().setName("LocalInterface");
721         service.setInterfaces(Collections.singletonMap("NotLocal", new InterfaceDefinition("NotLocal", null,
722             new HashMap<>())));
723
724         Map<String, Object> resultMap = interfacesOperationsConverter.getInterfacesMap(service, null,
725             service.getInterfaces(), null, false, false);
726
727         assertTrue(MapUtils.isNotEmpty(resultMap)
728             && resultMap.containsKey("NotLocal"));
729     }
730
731     @Test
732     void testRemoveInterfacesWithoutOperationsEmptyMap() {
733         final Map<String, Object> interfaceMap = new HashMap<>();
734         interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
735         assertThat(interfaceMap, is(anEmptyMap()));
736     }
737
738     @Test
739     void testRemoveInterfacesWithoutOperationsNullParameter() {
740         final Map<String, Object> interfaceMap = null;
741         interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
742         assertThat(interfaceMap, is(nullValue()));
743     }
744
745     @Test
746     void testRemoveInterfacesWithoutOperationsSuccess() {
747         final Map<String, Object> interfaceMap = new HashMap<>();
748         final ToscaInterfaceDefinition toscaInterfaceDefinition1 = new ToscaInterfaceDefinition();
749         interfaceMap.put("toscaInterfaceDefinition1", toscaInterfaceDefinition1);
750
751         final ToscaInterfaceDefinition toscaInterfaceDefinition2 = new ToscaInterfaceDefinition();
752         final Map<String, Object> toscaInterfaceDefinition2OperationMap = new HashMap<>();
753         toscaInterfaceDefinition2OperationMap.put("operation1", new Object());
754         toscaInterfaceDefinition2.setOperations(toscaInterfaceDefinition2OperationMap);
755         interfaceMap.put("toscaInterfaceDefinition2", toscaInterfaceDefinition2);
756
757         final Map<String, Object> toscaInterfaceDefinition3 = new HashMap<>();
758         interfaceMap.put("toscaInterfaceDefinition3", toscaInterfaceDefinition3);
759
760         final Map<String, Object> toscaInterfaceDefinition4 = new HashMap<>();
761         toscaInterfaceDefinition4.put("operation1", new Object());
762         interfaceMap.put("toscaInterfaceDefinition4", toscaInterfaceDefinition4);
763
764         final Object notAToscaInterfaceDefinition = new Object();
765         interfaceMap.put("notAToscaInterfaceDefinition", notAToscaInterfaceDefinition);
766
767         interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap);
768         assertFalse(interfaceMap.containsKey("toscaInterfaceDefinition1"));
769         assertTrue(interfaceMap.containsKey("toscaInterfaceDefinition2"));
770         assertFalse(interfaceMap.containsKey("toscaInterfaceDefinition3"));
771         assertTrue(interfaceMap.containsKey("toscaInterfaceDefinition4"));
772         assertTrue(interfaceMap.containsKey("notAToscaInterfaceDefinition"));
773     }
774 }