2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.policy.drools.apps.controller.usecases.step;
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;
38 import java.util.HashMap;
39 import java.util.List;
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;
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";
83 private Operator policyOperator;
85 private Operation policyOperation;
87 private Actor policyActor;
89 private ActorService actors;
91 private StepContext stepContext;
93 private AaiCqResponse aaicq;
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;
107 public void setUp() {
108 MockitoAnnotations.initMocks(this);
110 future = new CompletableFuture<>();
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);
118 when(policyOperation.getPropertyNames()).thenReturn(List.of());
120 when(stepContext.getProperty(AaiCqResponse.CONTEXT_KEY)).thenReturn(aaicq);
122 payload = Map.of(PAYLOAD_KEY, PAYLOAD_VALUE);
124 event = new VirtualControlLoopEvent();
125 event.setRequestId(REQ_ID);
127 starts = new LinkedBlockingQueue<>();
128 completions = new LinkedBlockingQueue<>();
130 Map<String, String> entityIds = new HashMap<>();
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)
136 .requestId(REQ_ID).build();
138 step = new Step2(stepContext, params, event);
143 public void testConstructor() {
144 assertSame(stepContext, step.stepContext);
145 assertSame(event, step.event);
146 assertSame(actors, step.getParams().getActorService());
150 public void testConstructorStep2() {
151 step = new Step2(step, "actorB", "operationB");
152 assertSame(stepContext, step.stepContext);
153 assertSame(event, step.event);
155 assertEquals("actorB", step.getActorName());
156 assertEquals("operationB", step.getOperationName());
157 assertSame(actors, step.getParams().getActorService());
161 public void testAcceptsEvent() {
162 // it's a policy step, thus it accepts events
163 assertTrue(step.acceptsEvent());
165 step = new Step2(step, "actorB", "operationB");
167 // it's not a policy step, thus it does not accept events
168 assertFalse(step.acceptsEvent());
172 public void testSuccess() {
173 assertThatCode(() -> step.success(null)).doesNotThrowAnyException();
177 public void testGetPropertyNames() {
178 // empty property list
179 assertThat(step.getPropertyNames()).isEmpty();
181 // try with non-empty list
182 when(policyOperation.getPropertyNames()).thenReturn(List.of("propA", "propB"));
183 assertThat(step.getPropertyNames()).isEqualTo(List.of("propA", "propB"));
187 public void testSetProperties() {
188 CloudRegion cloudRegion = new CloudRegion();
189 when(aaicq.getDefaultCloudRegion()).thenReturn(cloudRegion);
191 Tenant tenant = new Tenant();
192 when(aaicq.getDefaultTenant()).thenReturn(tenant);
194 when(policyOperation.getPropertyNames()).thenReturn(
195 List.of(OperationProperties.AAI_DEFAULT_CLOUD_REGION, OperationProperties.AAI_DEFAULT_TENANT));
197 step.setProperties();
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);
206 * Tests setProperties() when the property is unknown.
209 public void testSetPropertiesUnknown() {
210 when(policyOperation.getPropertyNames()).thenReturn(List.of("unknown-property"));
212 assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
213 .withMessage("unknown property unknown-property needed by my-actor.my-operation");
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));
222 step.setProperties();
223 verify(policyOperation).setProperty(OperationProperties.AAI_DEFAULT_CLOUD_REGION, data);
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));
232 step.setProperties();
233 verify(policyOperation).setProperty(OperationProperties.AAI_DEFAULT_TENANT, data);
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));
243 step.setProperties();
244 verify(policyOperation).setProperty(OperationProperties.AAI_PNF, data);
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));
254 step.setProperties();
255 verify(policyOperation).setProperty(OperationProperties.AAI_RESOURCE_VNF, data);
257 // missing resource ID
258 params.getTargetEntityIds().put(Step2.TARGET_RESOURCE_ID, null);
259 assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
260 .withMessageContaining("missing Target resource ID");
262 // missing target entity IDs
263 params = params.toBuilder().targetEntityIds(null).build();
264 step = new Step2(stepContext, params, event);
266 assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
267 .withMessageContaining(Step2.TARGET_INFO_MSG);
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));
276 step.setProperties();
277 verify(policyOperation).setProperty(OperationProperties.AAI_SERVICE, data);
281 public void testLoadServiceModel_testGetServiceModel() {
282 ServiceInstance service = new ServiceInstance();
283 service.setModelVersionId("my-service-version");
284 when(aaicq.getServiceInstance()).thenReturn(service);
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));
290 step.setProperties();
291 verify(policyOperation).setProperty(OperationProperties.AAI_SERVICE_MODEL, data);
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));
301 step.setProperties();
302 verify(policyOperation).setProperty(OperationProperties.AAI_VNF, data);
304 // missing model invariant ID
305 params.getTargetEntityIds().put(Step2.TARGET_MODEL_INVARIANT_ID, null);
306 assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
307 .withMessageContaining("missing modelInvariantId");
310 params = params.toBuilder().targetEntityIds(null).build();
311 step = new Step2(stepContext, params, event);
313 assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
314 .withMessageContaining(Step2.TARGET_INFO_MSG);
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);
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));
328 step.setProperties();
329 verify(policyOperation).setProperty(OperationProperties.AAI_VNF_MODEL, data);
333 public void testLoadVserverLink_testGetVserverLink() {
334 event.setAai(Map.of(Step2.VSERVER_VSERVER_NAME, "vserverB"));
336 StandardCoderObject tenant = mock(StandardCoderObject.class);
337 when(stepContext.getProperty(AaiGetTenantOperation.getKey("vserverB"))).thenReturn(tenant);
339 when(tenant.getString("result-data", 0, "resource-link")).thenReturn("/aai/v7/some/link/bbb");
341 when(policyOperation.getPropertyNames()).thenReturn(List.of(OperationProperties.AAI_VSERVER_LINK));
343 step.setProperties();
344 verify(policyOperation).setProperty(OperationProperties.AAI_VSERVER_LINK, "/some/link/bbb");
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");
351 // missing tenant data
352 when(stepContext.getProperty(AaiGetTenantOperation.getKey("vserverB"))).thenReturn(null);
353 assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
354 .withMessageContaining("missing tenant data for");
356 // empty vserver name
357 event.setAai(Map.of(Step2.VSERVER_VSERVER_NAME, ""));
358 assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
359 .withMessageContaining("missing vserver.vserver-name");
361 // missing vserver name
362 event.setAai(Map.of());
363 assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
364 .withMessageContaining("missing vserver.vserver-name");
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));
375 step.setProperties();
376 verify(policyOperation).setProperty(OperationProperties.DATA_VF_COUNT, 11);
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");
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");
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");
394 params = params.toBuilder().targetEntityIds(null).build();
395 step = new Step2(stepContext, params, event);
397 assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties())
398 .withMessageContaining(Step2.TARGET_INFO_MSG);
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);
408 public void testLoadEnrichment_testGetEnrichment() {
409 event.setAai(Map.of("bandwidth", "bandwidth-value"));
410 when(policyOperation.getPropertyNames()).thenReturn(List.of(OperationProperties.ENRICHMENT_BANDWIDTH));
412 step.setProperties();
413 verify(policyOperation).setProperty(OperationProperties.ENRICHMENT_BANDWIDTH, "bandwidth-value");
415 // missing enrichment data
416 event.setAai(Map.of());
417 assertThatIllegalArgumentException().isThrownBy(() -> step.setProperties());
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));
426 step.setProperties();
427 verify(policyOperation).setProperty(OperationProperties.EVENT_ADDITIONAL_PARAMS, data);
431 public void testLoadEventPayload_testGetEventPayload() {
432 event.setPayload("some-event-payload");
433 when(policyOperation.getPropertyNames()).thenReturn(List.of(OperationProperties.EVENT_PAYLOAD));
435 step.setProperties();
436 verify(policyOperation).setProperty(OperationProperties.EVENT_PAYLOAD, "some-event-payload");
440 public void testLoadOptCdsGrpcAaiProperties() {
441 when(policyOperation.getPropertyNames()).thenReturn(List.of(OperationProperties.OPT_CDS_GRPC_AAI_PROPERTIES));
443 step.setProperties();
444 verify(policyOperation, never()).setProperty(any(), anyString());
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));
453 step.setProperties();
454 verify(policyOperation).setProperty(UsecasesConstants.AAI_DEFAULT_GENERIC_VNF, data);
458 public void testGetCustomQueryData() {
459 assertSame(aaicq, step.getCustomQueryData());
461 when(stepContext.getProperty(AaiCqResponse.CONTEXT_KEY)).thenReturn(null);
463 assertThatIllegalArgumentException().isThrownBy(() -> step.getCustomQueryData())
464 .withMessage("missing custom query data for my-actor.my-operation");
468 public void testVerifyNotNull() {
469 assertThatCode(() -> step.verifyNotNull("verifyA", "verify-value-A")).doesNotThrowAnyException();
471 assertThatIllegalArgumentException().isThrownBy(() -> step.verifyNotNull("verifyB", null))
472 .withMessage("missing verifyB for my-actor.my-operation");
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));
481 assertEquals(ONE_SLASH, Step2.stripPrefix(ONE_SLASH, 1));
482 assertEquals(ONE_SLASH, Step2.stripPrefix(ONE_SLASH, 2));
484 assertEquals("/slashes", Step2.stripPrefix("/two/slashes", 2));
485 assertEquals("/slashes", Step2.stripPrefix("/two/slashes", 3));
487 assertEquals("/and/more", Step2.stripPrefix("/three/slashes/and/more", 3));
489 assertEquals("/and/more", Step2.stripPrefix("prefix/three/slashes/and/more", 3));