7695d5b20a9e08a3e1604c555a5d653bd2ba954e
[policy/drools-applications.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.drools.apps.controller.usecases.step;
22
23 import static org.assertj.core.api.Assertions.assertThat;
24 import static org.assertj.core.api.Assertions.assertThatCode;
25 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
26 import static org.junit.Assert.assertEquals;
27 import static org.junit.Assert.assertFalse;
28 import static org.junit.Assert.assertSame;
29 import static org.junit.Assert.assertTrue;
30 import static org.mockito.ArgumentMatchers.any;
31 import static org.mockito.ArgumentMatchers.anyString;
32 import static org.mockito.Mockito.mock;
33 import static org.mockito.Mockito.never;
34 import static org.mockito.Mockito.times;
35 import static org.mockito.Mockito.verify;
36 import static org.mockito.Mockito.when;
37
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.TreeMap;
42 import java.util.UUID;
43 import java.util.concurrent.BlockingQueue;
44 import java.util.concurrent.CompletableFuture;
45 import java.util.concurrent.ForkJoinPool;
46 import java.util.concurrent.LinkedBlockingQueue;
47 import org.junit.Before;
48 import org.junit.Test;
49 import org.mockito.Mock;
50 import org.mockito.MockitoAnnotations;
51 import org.onap.aai.domain.yang.CloudRegion;
52 import org.onap.aai.domain.yang.GenericVnf;
53 import org.onap.aai.domain.yang.ModelVer;
54 import org.onap.aai.domain.yang.ServiceInstance;
55 import org.onap.aai.domain.yang.Tenant;
56 import org.onap.policy.aai.AaiCqResponse;
57 import org.onap.policy.common.utils.coder.StandardCoderObject;
58 import org.onap.policy.controlloop.VirtualControlLoopEvent;
59 import org.onap.policy.controlloop.actor.aai.AaiGetPnfOperation;
60 import org.onap.policy.controlloop.actor.aai.AaiGetTenantOperation;
61 import org.onap.policy.controlloop.actorserviceprovider.ActorService;
62 import org.onap.policy.controlloop.actorserviceprovider.Operation;
63 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
64 import org.onap.policy.controlloop.actorserviceprovider.OperationProperties;
65 import org.onap.policy.controlloop.actorserviceprovider.Operator;
66 import org.onap.policy.controlloop.actorserviceprovider.TargetType;
67 import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
68 import org.onap.policy.controlloop.actorserviceprovider.spi.Actor;
69 import org.onap.policy.controlloop.eventmanager.StepContext;
70 import org.onap.policy.drools.apps.controller.usecases.UsecasesConstants;
71
72 public class Step2Test {
73     private static final UUID REQ_ID = UUID.randomUUID();
74     private static final String POLICY_ACTOR = "my-actor";
75     private static final String POLICY_OPERATION = "my-operation";
76     private static final String MY_TARGET = "my-target";
77     private static final String PAYLOAD_KEY = "payload-key";
78     private static final String PAYLOAD_VALUE = "payload-value";
79     private static final String NO_SLASH = "noslash";
80     private static final String ONE_SLASH = "/one";
81
82     @Mock
83     private Operator policyOperator;
84     @Mock
85     private Operation policyOperation;
86     @Mock
87     private Actor policyActor;
88     @Mock
89     private ActorService actors;
90     @Mock
91     private StepContext stepContext;
92     @Mock
93     private AaiCqResponse aaicq;
94
95     private CompletableFuture<OperationOutcome> future;
96     private Map<String, String> payload;
97     private VirtualControlLoopEvent event;
98     private BlockingQueue<OperationOutcome> starts;
99     private BlockingQueue<OperationOutcome> completions;
100     private ControlLoopOperationParams params;
101     private Step2 step;
102
103     /**
104      * Sets up.
105      */
106     @Before
107     public void setUp() {
108         MockitoAnnotations.initMocks(this);
109
110         future = new CompletableFuture<>();
111
112         // configure policy operation
113         when(actors.getActor(POLICY_ACTOR)).thenReturn(policyActor);
114         when(policyActor.getOperator(POLICY_OPERATION)).thenReturn(policyOperator);
115         when(policyOperator.buildOperation(any())).thenReturn(policyOperation);
116         when(policyOperation.start()).thenReturn(future);
117
118         when(policyOperation.getPropertyNames()).thenReturn(List.of());
119
120         when(stepContext.getProperty(AaiCqResponse.CONTEXT_KEY)).thenReturn(aaicq);
121
122         payload = Map.of(PAYLOAD_KEY, PAYLOAD_VALUE);
123
124         event = new VirtualControlLoopEvent();
125         event.setRequestId(REQ_ID);
126
127         starts = new LinkedBlockingQueue<>();
128         completions = new LinkedBlockingQueue<>();
129
130         Map<String, String> entityIds = new HashMap<>();
131
132         params = ControlLoopOperationParams.builder().actor(POLICY_ACTOR).actorService(actors)
133                         .completeCallback(completions::add).executor(ForkJoinPool.commonPool())
134                         .operation(POLICY_OPERATION).payload(new TreeMap<>(payload)).startCallback(starts::add)
135                         .targetType(TargetType.VM).targetEntityIds(entityIds).targetEntity(MY_TARGET)
136                         .requestId(REQ_ID).build();
137
138         step = new Step2(stepContext, params, event);
139         step.init();
140     }
141
142     @Test
143     public void testConstructor() {
144         assertSame(stepContext, step.stepContext);
145         assertSame(event, step.event);
146         assertSame(actors, step.getParams().getActorService());
147     }
148
149     @Test
150     public void testConstructorStep2() {
151         step = new Step2(step, "actorB", "operationB");
152         assertSame(stepContext, step.stepContext);
153         assertSame(event, step.event);
154
155         assertEquals("actorB", step.getActorName());
156         assertEquals("operationB", step.getOperationName());
157         assertSame(actors, step.getParams().getActorService());
158     }
159
160     @Test
161     public void testAcceptsEvent() {
162         // it's a policy step, thus it accepts events
163         assertTrue(step.acceptsEvent());
164
165         step = new Step2(step, "actorB", "operationB");
166
167         // it's not a policy step, thus it does not accept events
168         assertFalse(step.acceptsEvent());
169     }
170
171     @Test
172     public void testSuccess() {
173         assertThatCode(() -> step.success(null)).doesNotThrowAnyException();
174     }
175
176     @Test
177     public void testGetPropertyNames() {
178         // empty property list
179         assertThat(step.getPropertyNames()).isEmpty();
180
181         // try with non-empty list
182         when(policyOperation.getPropertyNames()).thenReturn(List.of("propA", "propB"));
183         assertThat(step.getPropertyNames()).isEqualTo(List.of("propA", "propB"));
184     }
185
186     @Test
187     public void testSetProperties() {
188         CloudRegion cloudRegion = new CloudRegion();
189         when(aaicq.getDefaultCloudRegion()).thenReturn(cloudRegion);
190
191         Tenant tenant = new Tenant();
192         when(aaicq.getDefaultTenant()).thenReturn(tenant);
193
194         when(policyOperation.getPropertyNames()).thenReturn(
195                         List.of(OperationProperties.AAI_DEFAULT_CLOUD_REGION, OperationProperties.AAI_DEFAULT_TENANT));
196
197         step.setProperties();
198
199         // should have been exactly two properties set
200         verify(policyOperation, times(2)).setProperty(any(), any());
201         verify(policyOperation).setProperty(OperationProperties.AAI_DEFAULT_CLOUD_REGION, cloudRegion);
202         verify(policyOperation).setProperty(OperationProperties.AAI_DEFAULT_TENANT, tenant);
203     }
204
205     /**
206      * Tests setProperties() when the property is unknown.
207      */
208     @Test
209     public void testSetPropertiesUnknown() {
210         when(policyOperation.getPropertyNames()).thenReturn(List.of("unknown-property"));
211
212         assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
213                         .withMessage("unknown property unknown-property needed by my-actor.my-operation");
214     }
215
216     @Test
217     public void testLoadCloudRegion_testGetCloudRegion() {
218         CloudRegion data = new CloudRegion();
219         when(aaicq.getDefaultCloudRegion()).thenReturn(data);
220         when(policyOperation.getPropertyNames()).thenReturn(List.of(OperationProperties.AAI_DEFAULT_CLOUD_REGION));
221
222         step.setProperties();
223         verify(policyOperation).setProperty(OperationProperties.AAI_DEFAULT_CLOUD_REGION, data);
224     }
225
226     @Test
227     public void testLoadTenant_testGetTenant() {
228         Tenant data = new Tenant();
229         when(aaicq.getDefaultTenant()).thenReturn(data);
230         when(policyOperation.getPropertyNames()).thenReturn(List.of(OperationProperties.AAI_DEFAULT_TENANT));
231
232         step.setProperties();
233         verify(policyOperation).setProperty(OperationProperties.AAI_DEFAULT_TENANT, data);
234     }
235
236     @Test
237     public void testLoadPnf_testGetPnf() {
238         StandardCoderObject data = new StandardCoderObject();
239         when(stepContext.getProperty(OperationProperties.AAI_TARGET_ENTITY)).thenReturn(MY_TARGET);
240         when(stepContext.getProperty(AaiGetPnfOperation.getKey(MY_TARGET))).thenReturn(data);
241         when(policyOperation.getPropertyNames()).thenReturn(List.of(OperationProperties.AAI_PNF));
242
243         step.setProperties();
244         verify(policyOperation).setProperty(OperationProperties.AAI_PNF, data);
245     }
246
247     @Test
248     public void testLoadResourceVnf_testGetResourceVnf() {
249         params.getTargetEntityIds().put(Step2.TARGET_RESOURCE_ID, "my-resource");
250         GenericVnf data = new GenericVnf();
251         when(aaicq.getGenericVnfByModelInvariantId("my-resource")).thenReturn(data);
252         when(policyOperation.getPropertyNames()).thenReturn(List.of(OperationProperties.AAI_RESOURCE_VNF));
253
254         step.setProperties();
255         verify(policyOperation).setProperty(OperationProperties.AAI_RESOURCE_VNF, data);
256
257         // missing resource ID
258         params.getTargetEntityIds().put(Step2.TARGET_RESOURCE_ID, null);
259         assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
260                         .withMessageContaining("missing Target resource ID");
261
262         // missing target entity IDs
263         params = params.toBuilder().targetEntityIds(null).build();
264         step = new Step2(stepContext, params, event);
265         step.init();
266         assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
267                         .withMessageContaining(Step2.TARGET_INFO_MSG);
268     }
269
270     @Test
271     public void testLoadService_testGetService() {
272         ServiceInstance data = new ServiceInstance();
273         when(aaicq.getServiceInstance()).thenReturn(data);
274         when(policyOperation.getPropertyNames()).thenReturn(List.of(OperationProperties.AAI_SERVICE));
275
276         step.setProperties();
277         verify(policyOperation).setProperty(OperationProperties.AAI_SERVICE, data);
278     }
279
280     @Test
281     public void testLoadServiceModel_testGetServiceModel() {
282         ServiceInstance service = new ServiceInstance();
283         service.setModelVersionId("my-service-version");
284         when(aaicq.getServiceInstance()).thenReturn(service);
285
286         ModelVer data = new ModelVer();
287         when(aaicq.getModelVerByVersionId("my-service-version")).thenReturn(data);
288         when(policyOperation.getPropertyNames()).thenReturn(List.of(OperationProperties.AAI_SERVICE_MODEL));
289
290         step.setProperties();
291         verify(policyOperation).setProperty(OperationProperties.AAI_SERVICE_MODEL, data);
292     }
293
294     @Test
295     public void testLoadVnf_testGetVnf() {
296         params.getTargetEntityIds().put(Step2.TARGET_MODEL_INVARIANT_ID, "my-model-invariant");
297         GenericVnf data = new GenericVnf();
298         when(aaicq.getGenericVnfByVfModuleModelInvariantId("my-model-invariant")).thenReturn(data);
299         when(policyOperation.getPropertyNames()).thenReturn(List.of(OperationProperties.AAI_VNF));
300
301         step.setProperties();
302         verify(policyOperation).setProperty(OperationProperties.AAI_VNF, data);
303
304         // missing model invariant ID
305         params.getTargetEntityIds().put(Step2.TARGET_MODEL_INVARIANT_ID, null);
306         assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
307                         .withMessageContaining("missing modelInvariantId");
308
309         // missing target
310         params = params.toBuilder().targetEntityIds(null).build();
311         step = new Step2(stepContext, params, event);
312         step.init();
313         assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
314                         .withMessageContaining(Step2.TARGET_INFO_MSG);
315     }
316
317     @Test
318     public void testLoadVnfModel_testGetVnfModel() {
319         params.getTargetEntityIds().put(Step2.TARGET_MODEL_INVARIANT_ID, "my-model-invariant");
320         GenericVnf vnf = new GenericVnf();
321         when(aaicq.getGenericVnfByVfModuleModelInvariantId("my-model-invariant")).thenReturn(vnf);
322
323         vnf.setModelVersionId("my-vnf-model-version-id");
324         ModelVer data = new ModelVer();
325         when(aaicq.getModelVerByVersionId("my-vnf-model-version-id")).thenReturn(data);
326         when(policyOperation.getPropertyNames()).thenReturn(List.of(OperationProperties.AAI_VNF_MODEL));
327
328         step.setProperties();
329         verify(policyOperation).setProperty(OperationProperties.AAI_VNF_MODEL, data);
330     }
331
332     @Test
333     public void testLoadVserverLink_testGetVserverLink() {
334         event.setAai(Map.of(Step2.VSERVER_VSERVER_NAME, "vserverB"));
335
336         StandardCoderObject tenant = mock(StandardCoderObject.class);
337         when(stepContext.getProperty(AaiGetTenantOperation.getKey("vserverB"))).thenReturn(tenant);
338
339         when(tenant.getString("result-data", 0, "resource-link")).thenReturn("/aai/v7/some/link/bbb");
340
341         when(policyOperation.getPropertyNames()).thenReturn(List.of(OperationProperties.AAI_VSERVER_LINK));
342
343         step.setProperties();
344         verify(policyOperation).setProperty(OperationProperties.AAI_VSERVER_LINK, "/some/link/bbb");
345
346         // missing resource link
347         when(tenant.getString("result-data", 0, "resource-link")).thenReturn(null);
348         assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
349                         .withMessageContaining("missing tenant data resource-link");
350
351         // missing tenant data
352         when(stepContext.getProperty(AaiGetTenantOperation.getKey("vserverB"))).thenReturn(null);
353         assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
354                         .withMessageContaining("missing tenant data for");
355
356         // empty vserver name
357         event.setAai(Map.of(Step2.VSERVER_VSERVER_NAME, ""));
358         assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
359                         .withMessageContaining("missing vserver.vserver-name");
360
361         // missing vserver name
362         event.setAai(Map.of());
363         assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
364                         .withMessageContaining("missing vserver.vserver-name");
365     }
366
367     @Test
368     public void testLoadVfCount_testGetVfCount() {
369         params.getTargetEntityIds().put(Step2.TARGET_MODEL_CUSTOMIZATION_ID, "vf-count-customization");
370         params.getTargetEntityIds().put(Step2.TARGET_MODEL_INVARIANT_ID, "vf-count-invariant");
371         params.getTargetEntityIds().put(Step2.TARGET_MODEL_VERSION_ID, "vf-count-version");
372         when(aaicq.getVfModuleCount("vf-count-customization", "vf-count-invariant", "vf-count-version")).thenReturn(11);
373         when(policyOperation.getPropertyNames()).thenReturn(List.of(OperationProperties.DATA_VF_COUNT));
374
375         step.setProperties();
376         verify(policyOperation).setProperty(OperationProperties.DATA_VF_COUNT, 11);
377
378         // missing model version id
379         params.getTargetEntityIds().put(Step2.TARGET_MODEL_VERSION_ID, null);
380         assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
381                         .withMessageContaining("missing target modelVersionId");
382
383         // missing model invariant id
384         params.getTargetEntityIds().put(Step2.TARGET_MODEL_INVARIANT_ID, null);
385         assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
386                         .withMessageContaining("missing target modelInvariantId");
387
388         // missing model customization id
389         params.getTargetEntityIds().put(Step2.TARGET_MODEL_CUSTOMIZATION_ID, null);
390         assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
391                         .withMessageContaining("missing target modelCustomizationId");
392
393         // missing target
394         params = params.toBuilder().targetEntityIds(null).build();
395         step = new Step2(stepContext, params, event);
396         step.init();
397         assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
398                         .withMessageContaining(Step2.TARGET_INFO_MSG);
399
400         // get it from the step context
401         when(stepContext.contains(OperationProperties.DATA_VF_COUNT)).thenReturn(true);
402         when(stepContext.getProperty(OperationProperties.DATA_VF_COUNT)).thenReturn(22);
403         step.setProperties();
404         verify(policyOperation).setProperty(OperationProperties.DATA_VF_COUNT, 22);
405     }
406
407     @Test
408     public void testLoadEnrichment_testGetEnrichment() {
409         event.setAai(Map.of("bandwidth", "bandwidth-value"));
410         when(policyOperation.getPropertyNames()).thenReturn(List.of(OperationProperties.ENRICHMENT_BANDWIDTH));
411
412         step.setProperties();
413         verify(policyOperation).setProperty(OperationProperties.ENRICHMENT_BANDWIDTH, "bandwidth-value");
414
415         // missing enrichment data
416         event.setAai(Map.of());
417         assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties());
418     }
419
420     @Test
421     public void testLoadAdditionalEventParams_testGetAdditionalEventParams() {
422         Map<String, String> data = Map.of("addA", "add-valueA", "addB", "add-valueB");
423         event.setAdditionalEventParams(data);
424         when(policyOperation.getPropertyNames()).thenReturn(List.of(OperationProperties.EVENT_ADDITIONAL_PARAMS));
425
426         step.setProperties();
427         verify(policyOperation).setProperty(OperationProperties.EVENT_ADDITIONAL_PARAMS, data);
428     }
429
430     @Test
431     public void testLoadEventPayload_testGetEventPayload() {
432         event.setPayload("some-event-payload");
433         when(policyOperation.getPropertyNames()).thenReturn(List.of(OperationProperties.EVENT_PAYLOAD));
434
435         step.setProperties();
436         verify(policyOperation).setProperty(OperationProperties.EVENT_PAYLOAD, "some-event-payload");
437     }
438
439     @Test
440     public void testLoadOptCdsGrpcAaiProperties() {
441         when(policyOperation.getPropertyNames()).thenReturn(List.of(OperationProperties.OPT_CDS_GRPC_AAI_PROPERTIES));
442
443         step.setProperties();
444         verify(policyOperation, never()).setProperty(any(), anyString());
445     }
446
447     @Test
448     public void testLoadDefaultGenericVnf_testGetDefaultGenericVnf() {
449         GenericVnf data = new GenericVnf();
450         when(aaicq.getDefaultGenericVnf()).thenReturn(data);
451         when(policyOperation.getPropertyNames()).thenReturn(List.of(UsecasesConstants.AAI_DEFAULT_GENERIC_VNF));
452
453         step.setProperties();
454         verify(policyOperation).setProperty(UsecasesConstants.AAI_DEFAULT_GENERIC_VNF, data);
455     }
456
457     @Test
458     public void testGetCustomQueryData() {
459         assertSame(aaicq, step.getCustomQueryData());
460
461         when(stepContext.getProperty(AaiCqResponse.CONTEXT_KEY)).thenReturn(null);
462
463         assertThatIllegalArgumentException().isThrownBy(() -> step.getCustomQueryData())
464                         .withMessage("missing custom query data for my-actor.my-operation");
465     }
466
467     @Test
468     public void testVerifyNotNull() {
469         assertThatCode(() -> step.verifyNotNull("verifyA", "verify-value-A")).doesNotThrowAnyException();
470
471         assertThatIllegalArgumentException().isThrownBy(() -> step.verifyNotNull("verifyB", null))
472                         .withMessage("missing verifyB for my-actor.my-operation");
473     }
474
475     @Test
476     public void testStripPrefix() {
477         assertEquals(NO_SLASH, Step2.stripPrefix(NO_SLASH, 0));
478         assertEquals(NO_SLASH, Step2.stripPrefix(NO_SLASH, 1));
479         assertEquals(NO_SLASH, Step2.stripPrefix(NO_SLASH, 2));
480
481         assertEquals(ONE_SLASH, Step2.stripPrefix(ONE_SLASH, 1));
482         assertEquals(ONE_SLASH, Step2.stripPrefix(ONE_SLASH, 2));
483
484         assertEquals("/slashes", Step2.stripPrefix("/two/slashes", 2));
485         assertEquals("/slashes", Step2.stripPrefix("/two/slashes", 3));
486
487         assertEquals("/and/more", Step2.stripPrefix("/three/slashes/and/more", 3));
488
489         assertEquals("/and/more", Step2.stripPrefix("prefix/three/slashes/and/more", 3));
490     }
491
492 }