deb634e2327f0a665c53862723a390c7684d7d88
[sdc.git] /
1 package org.openecomp.sdc.be.components.property;
2
3 import fj.data.Either;
4 import org.junit.Assert;
5 import org.junit.Test;
6 import org.junit.runner.RunWith;
7 import org.mockito.*;
8 import org.mockito.junit.MockitoJUnitRunner;
9 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
10 import org.openecomp.sdc.be.components.utils.InputsBuilder;
11 import org.openecomp.sdc.be.components.utils.PropertyDataDefinitionBuilder;
12 import org.openecomp.sdc.be.components.utils.ResourceBuilder;
13 import org.openecomp.sdc.be.dao.utils.MapUtil;
14 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
15 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
16 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
17 import org.openecomp.sdc.be.model.*;
18 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
19 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
20 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation;
21 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
22
23 import java.util.*;
24 import java.util.stream.Collectors;
25 import java.util.stream.Stream;
26
27 import static org.assertj.core.api.Assertions.assertThat;
28 import static org.mockito.ArgumentMatchers.any;
29 import static org.mockito.ArgumentMatchers.eq;
30 import static org.mockito.Mockito.verifyZeroInteractions;
31 import static org.mockito.Mockito.when;
32 import static org.openecomp.sdc.be.components.property.CapabilityTestUtils.createCapabilityDefinition;
33 import static org.openecomp.sdc.be.components.property.CapabilityTestUtils.createProperties;
34
35
36 @RunWith(MockitoJUnitRunner.class)
37 public class ComponentInstancePropertyDeclaratorTest extends PropertyDeclaratorTestBase {
38
39     @InjectMocks
40     private ComponentInstancePropertyDeclarator testInstance;
41     @Mock
42     private ToscaOperationFacade toscaOperationFacade;
43     @Mock
44     private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
45     @Mock
46     private PropertyOperation propertyOperation;
47
48     @Captor
49     private ArgumentCaptor<Map<String, List<ComponentInstanceProperty>>> instancePropertiesCaptor;
50
51     @Test
52     public void declarePropertiesAsInputs_componentInstanceNotExist() {
53         Component cmpt = new Resource();
54         Either<List<InputDefinition>, StorageOperationStatus> createdInputs = testInstance.declarePropertiesAsInputs(cmpt, "someCmptInstId", Collections.emptyList());
55         assertThat(createdInputs.right().value()).isEqualTo(StorageOperationStatus.NOT_FOUND);
56         verifyZeroInteractions(toscaOperationFacade);
57     }
58
59     @Test
60     public void declarePropertiesAsInputs_singleNonComplexProperty() {
61         List<PropertyDataDefinition> properties = Collections.singletonList(prop1);
62         List<ComponentInstancePropInput> propsToDeclare = createInstancePropInputList(properties);
63         when(toscaOperationFacade.addComponentInstancePropertiesToComponent(eq(resource), instancePropertiesCaptor.capture())).thenReturn(Either.left(Collections.emptyMap()));
64         Either<List<InputDefinition>, StorageOperationStatus> createdInputs = testInstance.declarePropertiesAsInputs(resource, "inst1", propsToDeclare);
65         List<InputDefinition> inputs = createdInputs.left().value();
66         List<ComponentInstanceProperty> capturedInstanceProperties = instancePropertiesCaptor.getValue().get(INSTANCE_ID);
67         verifyCreatedInputs(properties, capturedInstanceProperties, inputs);
68         verifyUpdatedProperties(properties, capturedInstanceProperties, inputs);
69     }
70
71     @Test
72     public void declareCapabilitiesPropertiesAsInputs() {
73         prop1.setParentUniqueId("capUniqueId");
74         List<PropertyDataDefinition> properties = Collections.singletonList(prop1);
75         List<ComponentInstancePropInput> propsToDeclare = createInstancePropInputList(properties);
76         when(toscaOperationFacade.addComponentInstancePropertiesToComponent(eq(resource), instancePropertiesCaptor
77                 .capture())).thenReturn(Either.left(Collections.emptyMap()));
78
79         CapabilityDefinition capabilityDefinition = createCapabilityDefinition();
80
81         List<ComponentInstanceProperty> capPropList = new ArrayList<>();
82         ComponentInstanceProperty instanceProperty = createProperties();
83         capPropList.add(instanceProperty);
84         capabilityDefinition.setProperties(capPropList);
85
86         capabilityDefinition.setPath(Collections.singletonList("path"));
87         Map<String, List<CapabilityDefinition>> capabilityMap = new HashMap<>();
88         capabilityMap.put(capabilityDefinition.getType(), Collections.singletonList(capabilityDefinition));
89         resource.setCapabilities(capabilityMap);
90
91         Either<List<InputDefinition>, StorageOperationStatus> createdInputs = testInstance
92                 .declarePropertiesAsInputs(resource, "inst1", propsToDeclare);
93         Assert.assertTrue(createdInputs.isLeft());
94     }
95
96     @Test
97     public void testUnDeclarePropertiesAsInputs() throws Exception {
98         Component component = new ResourceBuilder().setComponentType(ComponentTypeEnum.RESOURCE).setUniqueId("resourceId")
99                 .setName("resourceName").build();
100         InputDefinition input = new InputDefinition();
101         input.setUniqueId("ComponentInput1_uniqueId");
102         input.setPropertyId("ComponentInput1_uniqueId");
103
104         CapabilityDefinition capabilityDefinition = createCapabilityDefinition();
105
106         List<ComponentInstanceProperty> properties = new ArrayList<>();
107         ComponentInstanceProperty instanceProperty = createProperties();
108
109         List<GetInputValueDataDefinition> valueDataDefinitionList = new ArrayList<>();
110         GetInputValueDataDefinition getInputValueDataDefinition = new GetInputValueDataDefinition();
111         getInputValueDataDefinition.setInputId("ComponentInput1_uniqueId");
112         getInputValueDataDefinition.setPropName("prop_name");
113         valueDataDefinitionList.add(getInputValueDataDefinition);
114
115         instanceProperty.setGetInputValues(valueDataDefinitionList);
116         properties.add(instanceProperty);
117         capabilityDefinition.setProperties(properties);
118         Map<String, List<CapabilityDefinition>> capabilityMap = new HashMap<>();
119         capabilityMap.put(capabilityDefinition.getType(), Collections.singletonList(capabilityDefinition));
120         component.setCapabilities(capabilityMap);
121         component.setInputs(Collections.singletonList(input));
122         when(toscaOperationFacade.updateInstanceCapabilityProperty(any(Resource.class), any(),
123                 any(ComponentInstanceProperty.class), any(CapabilityDefinition.class))).thenReturn(StorageOperationStatus.OK);
124
125         StorageOperationStatus result = testInstance.unDeclarePropertiesAsInputs(component, input);
126         Assert.assertEquals(StorageOperationStatus.OK, result);
127     }
128
129     @Test
130     public void declarePropertiesAsInputs_multipleNonComplexProperty() {
131         List<PropertyDataDefinition> properties = Arrays.asList(prop1, prop2);
132         List<ComponentInstancePropInput> propsToDeclare = createInstancePropInputList(properties);
133         when(toscaOperationFacade.addComponentInstancePropertiesToComponent(eq(resource), instancePropertiesCaptor.capture())).thenReturn(Either.left(Collections.emptyMap()));
134         Either<List<InputDefinition>, StorageOperationStatus> createdInputs = testInstance.declarePropertiesAsInputs(resource, "inst1", propsToDeclare);
135
136         List<InputDefinition> inputs = createdInputs.left().value();
137         List<ComponentInstanceProperty> capturedInstanceProperties = instancePropertiesCaptor.getValue().get(INSTANCE_ID);
138         verifyCreatedInputs(properties, capturedInstanceProperties, inputs);
139         verifyUpdatedProperties(properties, capturedInstanceProperties, inputs);
140     }
141
142     @Test
143     public void declarePropertiesAsInputs_singleComplexProperty() {
144         PropertyDefinition innerProp1 = new PropertyDataDefinitionBuilder()
145                 .setName(INNER_PROP1)
146                 .setValue("true")
147                 .setType("boolean")
148                 .setUniqueId(complexProperty.getType() + ".datatype.ecomp_generated_naming")
149                 .build();
150         PropertyDefinition innerProp2 = new PropertyDataDefinitionBuilder()
151                 .setName(INNER_PROP2)
152                 .setValue("abc")
153                 .setType("string")
154                 .setUniqueId(complexProperty.getType() + ".datatype.ecomp_generated_naming")
155                 .build();
156         List<ComponentInstancePropInput> propsToDeclare = createComplexPropInputList(innerProp1, innerProp2);
157         when(toscaOperationFacade.addComponentInstancePropertiesToComponent(eq(resource), instancePropertiesCaptor.capture())).thenReturn(Either.left(Collections.emptyMap()));
158         Either<List<InputDefinition>, StorageOperationStatus> createdInputs = testInstance.declarePropertiesAsInputs(resource, "inst1", propsToDeclare);
159
160         List<InputDefinition> inputs = createdInputs.left().value();
161         List<ComponentInstanceProperty> capturedInstanceProperties = instancePropertiesCaptor.getValue().get(INSTANCE_ID);
162
163         verifyCreatedInputsFromComplexProperty(propsToDeclare, capturedInstanceProperties, inputs);
164         verifyUpdatedComplexProperty(capturedInstanceProperties, inputs);
165     }
166
167     @Test
168     public void declarePropertiesAsListInput() {
169         // construct arguments
170         List<PropertyDataDefinition> properties = Arrays.asList(prop1, prop2);
171         List<ComponentInstancePropInput> propsToDeclare = createInstancePropInputList(properties);
172         InputDefinition input = new InputDefinition(new PropertyDataDefinitionBuilder()
173                 .setName("listinput")
174                 .setType("list")
175                 .setDescription("description")
176                 .setSchemaType("org.onap.datatype.listinput")
177                 .build());
178         // mock returns
179         when(toscaOperationFacade.addComponentInstancePropertiesToComponent(eq(resource), instancePropertiesCaptor.capture())).thenReturn(Either.left(Collections.emptyMap()));
180         Either<InputDefinition, StorageOperationStatus> result = testInstance.declarePropertiesAsListInput(resource, "inst1", propsToDeclare, input);
181         // validate result
182         assertThat(result.isLeft()).isTrue();
183         List<ComponentInstanceProperty> capturedInstanceProperties = instancePropertiesCaptor.getValue().get(INSTANCE_ID);
184         assertThat(capturedInstanceProperties.size()).isEqualTo(2);
185         Map<String, PropertyDataDefinition> propertiesMap =
186                 properties.stream().collect(Collectors.toMap(PropertyDataDefinition::getName, e->e));
187         for(ComponentInstanceProperty instanceProperty: capturedInstanceProperties) {
188             assertThat(propertiesMap.containsKey(instanceProperty.getName())).isTrue();
189             PropertyDataDefinition property = propertiesMap.get(instanceProperty.getName());
190             assertThat(instanceProperty.getType()).isEqualTo(property.getType());
191             assertThat(instanceProperty.isGetInputProperty()).isTrue();
192         }
193     }
194
195     @Test
196     public void declarePropertiesAsListInput_propertyOwnerNotFound() {
197         // construct arguments
198         List<PropertyDataDefinition> properties = Arrays.asList(prop1, prop2);
199         List<ComponentInstancePropInput> propsToDeclare = createInstancePropInputList(properties);
200         InputDefinition input = new InputDefinition(new PropertyDataDefinitionBuilder()
201                 .setName("listinput")
202                 .setType("list")
203                 .setDescription("description")
204                 .setSchemaType("org.onap.datatype.listinput")
205                 .build());
206         Either<InputDefinition, StorageOperationStatus> result = testInstance.declarePropertiesAsListInput(resource, "inst2", propsToDeclare, input);
207         // validate result
208         assertThat(result.isRight()).isTrue();
209         assertThat(result.right().value()).isEqualTo(StorageOperationStatus.NOT_FOUND);
210     }
211
212     @Test
213     public void unDeclarePropertiesAsListInputsTest() {
214         InputDefinition inputToDelete = new InputDefinition();
215         inputToDelete.setUniqueId(INPUT_ID);
216         inputToDelete.setName(INPUT_ID);
217         inputToDelete.setIsDeclaredListInput(true);
218
219         Component component = createComponentWithListInput(INPUT_ID, "innerPropName");
220         PropertyDefinition prop = new PropertyDataDefinitionBuilder()
221                 .setName("propName")
222                 .setValue(generateGetInputValueAsListInput(INPUT_ID, "innerPropName"))
223                 .setType("list")
224                 .setUniqueId("propName")
225                 .addGetInputValue(INPUT_ID)
226                 .build();
227         component.setProperties(Collections.singletonList(prop));
228
229         List<ComponentInstanceProperty> ciPropList = new ArrayList<>();
230         ComponentInstanceProperty ciProp = new ComponentInstanceProperty();
231         List<String> pathOfComponentInstances = new ArrayList<>();
232         pathOfComponentInstances.add("pathOfComponentInstances");
233         ciProp.setPath(pathOfComponentInstances);
234         ciProp.setUniqueId("componentInstanceId");
235         ciProp.setDefaultValue("default value");
236         ciProp.setComponentInstanceId("componentInstanceId");
237         ciProp.setComponentInstanceName("componentInstanceName");
238         ciProp.setValue(generateGetInputValueAsListInput(INPUT_ID, "innerPropName"));
239         ciPropList.add(ciProp);
240
241         when(componentInstanceBusinessLogic.getComponentInstancePropertiesByInputId(eq(component), eq(INPUT_ID))).thenReturn(ciPropList);
242         when(propertyOperation.findDefaultValueFromSecondPosition(eq(pathOfComponentInstances), eq(ciProp.getUniqueId()), eq(ciProp.getDefaultValue()))).thenReturn(Either.left(ciProp.getDefaultValue()));
243         when(toscaOperationFacade.updateComponentInstanceProperties(eq(component), eq(ciProp.getComponentInstanceId()), eq(ciPropList))).thenReturn(StorageOperationStatus.OK);
244         StorageOperationStatus storageOperationStatus = testInstance.unDeclarePropertiesAsListInputs(component, inputToDelete);
245
246         assertThat(storageOperationStatus).isEqualTo(StorageOperationStatus.OK);
247     }
248
249     @Test
250     public void unDeclarePropertiesAsListInputsTest_whenNoListInput_returnOk() {
251         InputDefinition input = new InputDefinition();
252         input.setUniqueId(INPUT_ID);
253         input.setName(INPUT_ID);
254         input.setValue("value");
255         List<ComponentInstanceProperty> resList = new ArrayList<>();
256         when(componentInstanceBusinessLogic.getComponentInstancePropertiesByInputId(eq(resource), eq(INPUT_ID))).thenReturn(resList);
257         StorageOperationStatus status = testInstance.unDeclarePropertiesAsListInputs(resource, input);
258         Assert.assertEquals(status, StorageOperationStatus.OK);
259     }
260     
261     private void verifyUpdatedProperties(List<PropertyDataDefinition> properties, List<ComponentInstanceProperty> capturedInstanceProperties, List<InputDefinition> inputs) {
262         assertThat(capturedInstanceProperties).hasSize(properties.size());
263         Map<String, ComponentInstanceProperty> updatedPropertiesByName = MapUtil.toMap(capturedInstanceProperties, ComponentInstanceProperty::getName);
264         properties.forEach(prop -> verifyUpdatedInstanceProperty(prop, updatedPropertiesByName.get(prop.getName()), inputs));
265     }
266
267     private void verifyUpdatedComplexProperty(List<ComponentInstanceProperty> capturedInstanceProperties, List<InputDefinition> inputs) {
268         assertThat(capturedInstanceProperties).hasSize(1);
269         verifyUpdatedInstanceComplexProperty(capturedInstanceProperties.get(0), inputs);
270     }
271
272     private void verifyCreatedInputs(List<PropertyDataDefinition> originalPropsToDeclare, List<ComponentInstanceProperty> capturedUpdatedProperties, List<InputDefinition> inputs) {
273         assertThat(inputs).hasSize(originalPropsToDeclare.size());
274         Map<String, InputDefinition> propertyIdToCreatedInput = MapUtil.toMap(inputs, InputDefinition::getPropertyId);
275         originalPropsToDeclare.forEach(propToDeclare -> verifyCreatedInput(propToDeclare, propertyIdToCreatedInput.get(propToDeclare.getUniqueId())));
276         capturedUpdatedProperties.forEach(updatedProperty -> verifyInputPropertiesList(updatedProperty, propertyIdToCreatedInput.get(updatedProperty.getUniqueId())));
277     }
278
279     private void verifyCreatedInputsFromComplexProperty(List<ComponentInstancePropInput> propsToDeclare, List<ComponentInstanceProperty> capturedInstanceProperties, List<InputDefinition> inputs) {
280         assertThat(inputs).hasSize(propsToDeclare.size());
281         Map<String, InputDefinition> inputsByName = MapUtil.toMap(inputs, InputDefinition::getName);
282         propsToDeclare.forEach(propToDeclare -> verifyCreatedInputFromComplexProperty(propToDeclare, inputsByName));
283         Map<String, List<InputDefinition>> propertyIdToCreatedInput = MapUtil.groupListBy(inputs, InputDefinition::getPropertyId);
284         capturedInstanceProperties.forEach(updatedProperty -> verifyInputPropertiesListFromComplexProperty(updatedProperty, propertyIdToCreatedInput.get(updatedProperty.getUniqueId())));
285     }
286
287     private void verifyInputPropertiesListFromComplexProperty(ComponentInstanceProperty updatedProperty, List<InputDefinition> inputs) {
288         inputs.forEach(input -> verifyInputPropertiesList(updatedProperty, input));
289     }
290
291     private void verifyCreatedInputFromComplexProperty(ComponentInstancePropInput parentProperty,  Map<String, InputDefinition> inputsByName) {
292         PropertyDefinition innerProperty = parentProperty.getInput();
293         String expectedInputName = generateExpectedInputName(parentProperty, innerProperty);
294         InputDefinition input = inputsByName.get(expectedInputName);
295         assertThat(input.getType()).isEqualTo(innerProperty.getType());
296         assertThat(input.getValue()).isEqualTo(innerProperty.getValue());
297 //        assertThat(input.getDefaultValue()).isEqualTo(innerProperty.getValue());//bug
298         assertThat(input.getUniqueId()).isEqualTo(UniqueIdBuilder.buildPropertyUniqueId(RESOURCE_ID, input.getName()));
299         assertThat(input.getPropertyId()).isEqualTo(parentProperty.getUniqueId());
300         assertThat(input.getInstanceUniqueId()).isEqualTo(INSTANCE_ID);
301
302     }
303
304     private void verifyInputPropertiesList(ComponentInstanceProperty updatedProperty, InputDefinition input) {
305         assertThat(input.getProperties()).hasSize(1);
306         assertThat(updatedProperty).isEqualTo(input.getProperties().get(0));
307     }
308
309
310     private List<ComponentInstancePropInput> createComplexPropInputList(PropertyDefinition ... innerProperties) {
311         return Stream.of(innerProperties).map(this::createComplexPropInput).collect(Collectors.toList());
312     }
313
314     private ComponentInstancePropInput createComplexPropInput(PropertyDefinition innerProp) {
315         ComponentInstancePropInput componentInstancePropInput = new ComponentInstancePropInput(new ComponentInstanceProperty(complexProperty));
316         componentInstancePropInput.setInput(innerProp);
317         componentInstancePropInput.setPropertiesName(complexProperty.getName() + "#" +  innerProp.getName());
318         return componentInstancePropInput;
319     }
320
321     private void verifyUpdatedInstanceProperty(PropertyDataDefinition originalProperty, ComponentInstanceProperty updatedProperty, List<InputDefinition> inputs) {
322         assertThat(updatedProperty.getValue()).isEqualTo(generateGetInputValue(generateExpectedInputName(originalProperty)));
323         assertThat(updatedProperty.isGetInputProperty()).isTrue();
324         assertThat(updatedProperty.getName()).isEqualTo(originalProperty.getName());
325         List<GetInputValueDataDefinition> getInputValues = updatedProperty.getGetInputValues();
326         verifyGetInputValues(getInputValues, inputs);
327     }
328
329     private void verifyUpdatedInstanceComplexProperty(ComponentInstanceProperty updatedComplexProperty, List<InputDefinition> inputs) {
330         assertThat(updatedComplexProperty.getValue()).isEqualTo(generateComplexGetInputValue(inputs));
331         assertThat(updatedComplexProperty.isGetInputProperty()).isTrue();
332         assertThat(updatedComplexProperty.getName()).isEqualTo(complexProperty.getName());
333         List<GetInputValueDataDefinition> getInputValues = updatedComplexProperty.getGetInputValues();
334         verifyGetInputValues(getInputValues, inputs);
335     }
336
337     private void verifyGetInputValues(List<GetInputValueDataDefinition> getInputValues, List<InputDefinition> inputs) {
338         Map<String, InputDefinition> inputsByName = MapUtil.toMap(inputs, InputDefinition::getName);
339         getInputValues.forEach(getInputVal -> {
340             InputDefinition input = inputsByName.get(getInputVal.getInputName());
341             assertThat(input.getUniqueId()).isEqualTo(getInputVal.getInputId());
342         });
343     }
344
345     private String generateComplexGetInputValue(List<InputDefinition> createdInputs) {
346         return String.format("{\"%s\":%s,\"%s\":%s}", INNER_PROP1, generateGetInputValue(createdInputs.get(0).getName()), INNER_PROP2, generateGetInputValue(createdInputs.get(1).getName()));
347     }
348
349     private String generateExpectedInputName(PropertyDataDefinition prop) {
350         return INSTANCE_ID + "_" + prop.getName();
351     }
352
353     private String generateExpectedInputName(PropertyDefinition parentProp, PropertyDefinition innerProperty) {
354         return INSTANCE_ID + "_" + parentProp.getName()+ "_" + innerProperty.getName();
355     }
356
357     private void verifyCreatedInput(PropertyDataDefinition property, InputDefinition input) {
358         assertThat(input.getType()).isEqualTo(property.getType());
359         assertThat(input.getName()).isEqualTo(generateExpectedInputName(property));
360         assertThat(input.getValue()).isEqualTo(property.getValue());
361         assertThat(input.getDefaultValue()).isEqualTo(property.getValue());
362         assertThat(input.getUniqueId()).isEqualTo(UniqueIdBuilder.buildPropertyUniqueId(RESOURCE_ID, input.getName()));
363         assertThat(input.getPropertyId()).isEqualTo(property.getUniqueId());
364         assertThat(input.getInstanceUniqueId()).isEqualTo(INSTANCE_ID);
365     }
366
367     private Component createComponentWithListInput(String inputName, String propName) {
368         InputDefinition input = InputsBuilder.create()
369                 .setName(inputName)
370                 .build();
371
372         input.setUniqueId(INPUT_ID);
373         input.setName(INPUT_ID);
374         input.setDefaultValue("defaultValue");
375         input.setValue(generateGetInputValueAsListInput(inputName, propName));
376
377         return new ResourceBuilder()
378                 .setUniqueId(RESOURCE_ID)
379                 .addInput(input)
380                 .build();
381     }
382 }