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