3b64638199a596bb0e12695b36eaead16c8097c8
[policy/drools-applications.git] / controlloop / common / controller-usecases / src / test / java / org / onap / policy / drools / apps / controller / usecases / UsecasesEventManagerTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2020-2021, 2023 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2023 Nordix Foundation.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.drools.apps.controller.usecases;
23
24 import static org.assertj.core.api.Assertions.assertThat;
25 import static org.assertj.core.api.Assertions.assertThatCode;
26 import static org.assertj.core.api.Assertions.assertThatThrownBy;
27 import static org.junit.jupiter.api.Assertions.assertEquals;
28 import static org.junit.jupiter.api.Assertions.assertFalse;
29 import static org.junit.jupiter.api.Assertions.assertNotNull;
30 import static org.junit.jupiter.api.Assertions.assertSame;
31 import static org.junit.jupiter.api.Assertions.assertTrue;
32 import static org.mockito.ArgumentMatchers.any;
33 import static org.mockito.Mockito.mock;
34 import static org.mockito.Mockito.verify;
35 import static org.mockito.Mockito.when;
36
37 import java.time.Instant;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.TreeMap;
43 import java.util.UUID;
44 import java.util.concurrent.ExecutorService;
45 import org.drools.core.WorkingMemory;
46 import org.drools.core.common.InternalFactHandle;
47 import org.junit.jupiter.api.BeforeEach;
48 import org.junit.jupiter.api.Test;
49 import org.onap.policy.common.utils.coder.Coder;
50 import org.onap.policy.common.utils.coder.CoderException;
51 import org.onap.policy.common.utils.coder.StandardYamlCoder;
52 import org.onap.policy.common.utils.resources.ResourceUtils;
53 import org.onap.policy.controlloop.ControlLoopEventStatus;
54 import org.onap.policy.controlloop.ControlLoopException;
55 import org.onap.policy.controlloop.ControlLoopTargetType;
56 import org.onap.policy.controlloop.VirtualControlLoopEvent;
57 import org.onap.policy.controlloop.actorserviceprovider.Operation;
58 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
59 import org.onap.policy.controlloop.actorserviceprovider.OperationProperties;
60 import org.onap.policy.controlloop.actorserviceprovider.OperationResult;
61 import org.onap.policy.controlloop.actorserviceprovider.Operator;
62 import org.onap.policy.controlloop.actorserviceprovider.TargetType;
63 import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
64 import org.onap.policy.controlloop.actorserviceprovider.spi.Actor;
65 import org.onap.policy.controlloop.drl.legacy.ControlLoopParams;
66 import org.onap.policy.controlloop.eventmanager.ActorConstants;
67 import org.onap.policy.controlloop.eventmanager.EventManagerServices;
68 import org.onap.policy.controlloop.ophistory.OperationHistoryDataManager;
69 import org.onap.policy.drools.apps.controller.usecases.step.AaiCqStep2;
70 import org.onap.policy.drools.apps.controller.usecases.step.AaiGetPnfStep2;
71 import org.onap.policy.drools.apps.controller.usecases.step.AaiGetTenantStep2;
72 import org.onap.policy.drools.apps.controller.usecases.step.GetTargetEntityStep2;
73 import org.onap.policy.drools.apps.controller.usecases.step.GuardStep2;
74 import org.onap.policy.drools.apps.controller.usecases.step.Step2;
75 import org.onap.policy.drools.core.lock.LockCallback;
76 import org.onap.policy.drools.core.lock.LockImpl;
77 import org.onap.policy.drools.core.lock.LockState;
78 import org.onap.policy.drools.system.PolicyEngine;
79 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
80 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
81 import org.onap.policy.sdnr.PciBody;
82 import org.onap.policy.sdnr.PciMessage;
83 import org.onap.policy.sdnr.PciResponse;
84
85 class UsecasesEventManagerTest {
86     private static final UUID REQ_ID = UUID.randomUUID();
87     private static final String CL_NAME = "my-closed-loop-name";
88     private static final String POLICY_NAME = "my-policy-name";
89     private static final String POLICY_SCOPE = "my-scope";
90     private static final String POLICY_VERSION = "1.2.3";
91     private static final String SIMPLE_ACTOR = "First";
92     private static final String SIMPLE_OPERATION = "OperationA";
93     private static final String MY_TARGET = "my-target";
94     private static final String EVENT_MGR_SIMPLE_YAML =
95                     "../eventmanager/src/test/resources/eventManager/event-mgr-simple.yaml";
96     private static final Coder yamlCoder = new StandardYamlCoder();
97     private static final String OUTCOME_MSG = "my outcome message";
98
99     private final PolicyEngine engineMgr = mock(PolicyEngine.class);
100     private final WorkingMemory workMem = mock(WorkingMemory.class);
101     private final InternalFactHandle factHandle = mock(InternalFactHandle.class);
102     private final Operator policyOperator = mock(Operator.class);
103     private final Operation policyOperation = mock(Operation.class);
104     private final Actor policyActor = mock(Actor.class);
105     private final EventManagerServices services = mock(EventManagerServices.class);
106     private final OperationHistoryDataManager dataMgr = mock(OperationHistoryDataManager.class);
107     private final ExecutorService executor = mock(ExecutorService.class);
108     private Step2 stepa = mock(Step2.class);
109     private final Step2 stepb = mock(Step2.class);
110
111     private List<LockImpl> locks;
112     private ToscaPolicy tosca;
113     private ControlLoopParams params;
114     private VirtualControlLoopEvent event;
115     private UsecasesEventManager mgr;
116
117     /**
118      * Sets up.
119      */
120     @BeforeEach
121     public void setUp() throws ControlLoopException, CoderException {
122         when(services.getDataManager()).thenReturn(dataMgr);
123
124         when(workMem.getFactHandle(any())).thenReturn(factHandle);
125
126         event = new VirtualControlLoopEvent();
127         event.setRequestId(REQ_ID);
128         event.setTarget(UsecasesConstants.VSERVER_VSERVER_NAME);
129         event.setAai(new TreeMap<>(Map.of(UsecasesConstants.VSERVER_VSERVER_NAME, MY_TARGET)));
130         event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET);
131         event.setClosedLoopControlName(CL_NAME);
132         event.setTargetType(ControlLoopTargetType.VNF);
133
134         params = new ControlLoopParams();
135         params.setClosedLoopControlName(CL_NAME);
136         params.setPolicyName(POLICY_NAME);
137         params.setPolicyScope(POLICY_SCOPE);
138         params.setPolicyVersion(POLICY_VERSION);
139
140         loadPolicy(EVENT_MGR_SIMPLE_YAML);
141
142         locks = new ArrayList<>();
143
144         mgr = new MyManager(services, params, event, workMem);
145     }
146
147     @Test
148     void testConstructor() {
149         assertEquals(POLICY_NAME, mgr.getPolicyName());
150         assertSame(event, mgr.getEvent());
151
152         var orig = event.getAai();
153
154         event.setAai(addAai(orig, UsecasesConstants.VSERVER_IS_CLOSED_LOOP_DISABLED, "true"));
155         assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
156                         .hasMessage("is-closed-loop-disabled is set to true on VServer or VNF");
157
158         // vserver ACTIVE
159         event.setAai(addAai(orig, UsecasesConstants.VSERVER_PROV_STATUS,
160                         UsecasesConstants.PROV_STATUS_ACTIVE.toUpperCase()));
161         assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
162
163         // vserver active
164         event.setAai(addAai(orig, UsecasesConstants.VSERVER_PROV_STATUS,
165                         UsecasesConstants.PROV_STATUS_ACTIVE.toLowerCase()));
166         assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
167
168         // vserver inactive
169         event.setAai(addAai(orig, UsecasesConstants.VSERVER_PROV_STATUS, "inactive"));
170         assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
171                         .hasMessage("prov-status is not ACTIVE on VServer or VNF");
172
173         // vnf ACTIVE
174         event.setAai(addAai(orig, UsecasesConstants.GENERIC_VNF_PROV_STATUS,
175                         UsecasesConstants.PROV_STATUS_ACTIVE.toUpperCase()));
176         assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
177
178         // vnf active
179         event.setAai(addAai(orig, UsecasesConstants.GENERIC_VNF_PROV_STATUS,
180                         UsecasesConstants.PROV_STATUS_ACTIVE.toLowerCase()));
181         assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
182
183         // vnf inactive
184         event.setAai(addAai(orig, UsecasesConstants.GENERIC_VNF_PROV_STATUS, "inactive"));
185         assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
186                         .hasMessage("prov-status is not ACTIVE on VServer or VNF");
187
188         // valid
189         event.setAai(orig);
190         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
191
192         // invalid
193         event.setTarget("unknown-target");
194         assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
195                         .isInstanceOf(ControlLoopException.class);
196     }
197
198     @Test
199     void testLoadPreprocessorSteps() {
200         stepa = new Step2(mgr, ControlLoopOperationParams.builder().build(), event) {
201             @Override
202             public List<String> getPropertyNames() {
203                 return List.of(OperationProperties.AAI_DEFAULT_CLOUD_REGION);
204             }
205
206             @Override
207             protected Operation buildOperation() {
208                 return policyOperation;
209             }
210         };
211
212         mgr.getSteps().add(stepa);
213         mgr.getSteps().add(stepb);
214
215         mgr.loadPreprocessorSteps();
216
217         var steps = mgr.getSteps();
218
219         Step2 lockStep = steps.poll();
220         assertNotNull(lockStep);
221         assertEquals(ActorConstants.LOCK_ACTOR, lockStep.getActorName());
222         assertThat(steps.poll()).isInstanceOf(AaiCqStep2.class);
223         assertThat(steps.poll()).isInstanceOf(GuardStep2.class);
224         assertSame(stepa, steps.poll());
225         assertSame(stepb, steps.poll());
226         assertThat(steps).isEmpty();
227     }
228
229     /**
230      * Tests loadPreprocessorSteps() when no additional steps are needed.
231      */
232     @Test
233     void testLoadPreprocessorStepsNothingToLoad() {
234         when(stepa.isPolicyStep()).thenReturn(false);
235         when(stepa.getPropertyNames()).thenReturn(List.of("unknown-property"));
236
237         var steps = mgr.getSteps();
238         steps.add(stepa);
239         steps.add(stepb);
240
241         setTargetEntity();
242         mgr.loadPreprocessorSteps();
243
244         assertSame(stepa, steps.poll());
245         assertSame(stepb, steps.poll());
246         assertThat(steps).isEmpty();
247     }
248
249     /**
250      * Tests loadPreprocessorSteps() when an A&AI custom query is needed.
251      */
252     @Test
253     void testLoadPreprocessorStepsCq() {
254         loadStepsWithProperties(OperationProperties.AAI_DEFAULT_CLOUD_REGION, OperationProperties.AAI_DEFAULT_TENANT);
255
256         setTargetEntity();
257         mgr.loadPreprocessorSteps();
258
259         var steps = mgr.getSteps();
260
261         assertThat(steps.poll()).isInstanceOf(AaiCqStep2.class);
262         assertSame(stepa, steps.poll());
263         assertSame(stepb, steps.poll());
264         assertThat(steps).isEmpty();
265     }
266
267     /**
268      * Tests loadPreprocessorSteps() when an A&AI PNF query is needed.
269      */
270     @Test
271     void testLoadPreprocessorStepsPnf() {
272         // doubling up the property to check both branches
273         loadStepsWithProperties(OperationProperties.AAI_PNF, OperationProperties.AAI_PNF);
274
275         setTargetEntity();
276         mgr.loadPreprocessorSteps();
277
278         var steps = mgr.getSteps();
279
280         assertThat(steps.poll()).isInstanceOf(AaiGetPnfStep2.class);
281         assertSame(stepa, steps.poll());
282         assertSame(stepb, steps.poll());
283         assertThat(steps).isEmpty();
284     }
285
286     /**
287      * Tests loadPreprocessorSteps() when an A&AI Tenant query is needed.
288      */
289     @Test
290     void testLoadPreprocessorStepsTenant() {
291         // doubling up the property to check both branches
292         event.getAai().put(Step2.VSERVER_VSERVER_NAME, "my-vserver");
293         loadStepsWithProperties(OperationProperties.AAI_VSERVER_LINK, OperationProperties.AAI_VSERVER_LINK);
294
295         setTargetEntity();
296         mgr.loadPreprocessorSteps();
297
298         var steps = mgr.getSteps();
299
300         assertThat(steps.poll()).isInstanceOf(AaiGetTenantStep2.class);
301         assertSame(stepa, steps.poll());
302         assertSame(stepb, steps.poll());
303         assertThat(steps).isEmpty();
304     }
305
306     /**
307      * Tests loadPreprocessorSteps() when the target entity is unset.
308      */
309     @Test
310     void testLoadPreprocessorStepsNeedTargetEntity() {
311         stepa = new Step2(mgr, ControlLoopOperationParams.builder()
312                         .targetType(TargetType.toTargetType(event.getTargetType())).targetEntityIds(Map.of()).build(),
313                         event) {
314             @Override
315             public List<String> getPropertyNames() {
316                 return List.of(OperationProperties.AAI_TARGET_ENTITY);
317             }
318
319             @Override
320             protected Operation buildOperation() {
321                 return policyOperation;
322             }
323
324             @Override
325             public boolean isPolicyStep() {
326                 return false;
327             }
328         };
329
330         var steps = mgr.getSteps();
331         steps.add(stepa);
332         steps.add(stepb);
333
334         mgr.loadPreprocessorSteps();
335
336         Step2 entityStep = steps.poll();
337
338         assertThat(entityStep).isInstanceOf(GetTargetEntityStep2.class);
339         assertSame(stepa, steps.poll());
340         assertSame(stepb, steps.poll());
341         assertThat(steps).isEmpty();
342
343         // put get-target-entity back onto the queue and ensure nothing else is added
344         steps.add(entityStep);
345         mgr.loadPreprocessorSteps();
346         assertSame(entityStep, steps.poll());
347         assertThat(steps).isEmpty();
348     }
349
350     @Test
351     void testIsAbort() {
352         var outcome = makeCompletedOutcome();
353         outcome.setResult(OperationResult.FAILURE);
354
355         // closed loop timeout
356         outcome.setActor(ActorConstants.CL_TIMEOUT_ACTOR);
357         assertTrue(mgr.isAbort(outcome));
358
359         // lost lock
360         outcome.setActor(ActorConstants.LOCK_ACTOR);
361         assertTrue(mgr.isAbort(outcome));
362
363         // no effect for success
364         outcome.setResult(OperationResult.SUCCESS);
365         assertFalse(mgr.isAbort(outcome));
366     }
367
368     @Test
369     void testStoreInDataBase() throws ControlLoopException {
370         mgr.start();
371         var outcome = makeOutcome();
372         mgr.addToHistory(outcome);
373
374         mgr.storeInDataBase(mgr.getPartialHistory().peekLast());
375
376         verify(dataMgr).store(REQ_ID.toString(), event.getClosedLoopControlName(), event, null,
377                         mgr.getPartialHistory().peekLast().getClOperation());
378     }
379
380     @Test
381     void testMakeControlLoopResponse() {
382         final var outcome = new OperationOutcome();
383
384         // no message - should return null
385         checkResp(outcome, null);
386
387         // not a PciMessage - should return null
388         outcome.setResponse("not-a-pci-message");
389         checkResp(outcome, null);
390
391         /*
392          * now work with a PciMessage
393          */
394         var msg = new PciMessage();
395         outcome.setResponse(msg);
396
397         var body = new PciBody();
398         msg.setBody(body);
399
400         var output = new PciResponse();
401         body.setOutput(output);
402
403         output.setPayload("my-payload");
404
405         // should generate a response, with a payload
406         checkResp(outcome, "my-payload");
407
408         /*
409          * these should generate a response, with null payload
410          */
411         output.setPayload(null);
412         checkResp(outcome, null);
413
414         body.setOutput(null);
415         checkResp(outcome, null);
416
417         msg.setBody(null);
418         checkResp(outcome, null);
419
420         outcome.setResponse(null);
421         checkResp(outcome, null);
422     }
423
424     @Test
425     void testCheckEventSyntax() {
426         /*
427          * only need to check one success and one failure from the super class method
428          */
429
430         // initially, it's valid
431         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
432
433         event.setTarget("unknown-target");
434         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
435                         .hasMessage("target field invalid");
436
437         event.setTarget(null);
438         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
439                         .hasMessage("No target field");
440
441         event.setRequestId(null);
442         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
443                         .hasMessage("No request ID");
444     }
445
446     @Test
447     void testValidateStatus() {
448         /*
449          * only need to check one success and one failure from the super class method
450          */
451         event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET);
452         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
453
454         event.setClosedLoopEventStatus(null);
455         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
456                         .hasMessage("Invalid value in closedLoopEventStatus");
457     }
458
459     @Test
460     void testValidateAaiData() {
461         event.setTargetType("unknown-target-type");
462         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
463                         .hasMessage("The target type is not supported");
464
465         event.setTargetType(null);
466         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
467                         .hasMessage("The Target type is null");
468
469         event.setAai(null);
470         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
471                         .hasMessage("AAI is null");
472
473         // VM case
474         event.setTargetType(ControlLoopTargetType.VM);
475         event.setAai(Map.of(UsecasesConstants.GENERIC_VNF_VNF_ID, MY_TARGET));
476         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
477
478         event.setAai(Map.of());
479         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class);
480
481         // VNF case
482         event.setTargetType(ControlLoopTargetType.VNF);
483         event.setAai(Map.of(UsecasesConstants.GENERIC_VNF_VNF_ID, MY_TARGET));
484         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
485
486         event.setAai(Map.of());
487         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class);
488
489         // PNF case
490         event.setTargetType(ControlLoopTargetType.PNF);
491         event.setAai(Map.of(UsecasesConstants.PNF_NAME, MY_TARGET));
492         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
493
494         event.setAai(Map.of());
495         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class);
496     }
497
498     @Test
499     void testValidateAaiVmVnfData() {
500         event.setTargetType(ControlLoopTargetType.VM);
501         event.setAai(Map.of(UsecasesConstants.GENERIC_VNF_VNF_ID, MY_TARGET));
502         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
503
504         event.setAai(Map.of(UsecasesConstants.VSERVER_VSERVER_NAME, MY_TARGET));
505         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
506
507         event.setAai(Map.of(UsecasesConstants.GENERIC_VNF_VNF_NAME, MY_TARGET));
508         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
509
510         event.setAai(Map.of());
511         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class).hasMessage(
512                         "generic-vnf.vnf-id or generic-vnf.vnf-name or vserver.vserver-name information missing");
513     }
514
515     @Test
516     void testValidateAaiPnfData() {
517         event.setTargetType(ControlLoopTargetType.PNF);
518         event.setAai(Map.of(UsecasesConstants.PNF_NAME, MY_TARGET));
519         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
520
521         event.setAai(Map.of());
522         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
523                         .hasMessage("AAI PNF object key pnf-name is missing");
524     }
525
526     @Test
527     void testIsClosedLoopDisabled() {
528         var orig = event.getAai();
529
530         event.setAai(addAai(orig, UsecasesConstants.VSERVER_IS_CLOSED_LOOP_DISABLED, "true"));
531         assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
532                         .isInstanceOf(IllegalStateException.class);
533
534         event.setAai(addAai(orig, UsecasesConstants.GENERIC_VNF_IS_CLOSED_LOOP_DISABLED, "true"));
535         assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
536                         .isInstanceOf(IllegalStateException.class);
537
538         event.setAai(addAai(orig, UsecasesConstants.PNF_IS_IN_MAINT, "true"));
539         assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
540                         .isInstanceOf(IllegalStateException.class);
541     }
542
543     @Test
544     void testIsProvStatusInactive() {
545         var orig = event.getAai();
546
547         event.setAai(addAai(orig, UsecasesConstants.VSERVER_PROV_STATUS, "ACTIVE"));
548         assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
549
550         event.setAai(addAai(orig, UsecasesConstants.VSERVER_PROV_STATUS, "inactive"));
551         assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
552                         .isInstanceOf(IllegalStateException.class);
553
554         event.setAai(addAai(orig, UsecasesConstants.GENERIC_VNF_PROV_STATUS, "ACTIVE"));
555         assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
556
557         event.setAai(addAai(orig, UsecasesConstants.GENERIC_VNF_PROV_STATUS, "inactive"));
558         assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
559                         .isInstanceOf(IllegalStateException.class);
560     }
561
562     @Test
563     void testIsAaiTrue() {
564         var orig = event.getAai();
565
566         for (var value : Arrays.asList("yes", "y", "true", "t", "yEs", "trUe")) {
567             event.setAai(addAai(orig, UsecasesConstants.VSERVER_IS_CLOSED_LOOP_DISABLED, value));
568             assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
569                             .isInstanceOf(IllegalStateException.class);
570         }
571
572         event.setAai(addAai(orig, UsecasesConstants.VSERVER_IS_CLOSED_LOOP_DISABLED, "false"));
573         assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
574
575         event.setAai(addAai(orig, UsecasesConstants.VSERVER_IS_CLOSED_LOOP_DISABLED, "no"));
576         assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
577     }
578
579
580
581     private Map<String, String> addAai(Map<String, String> original, String key, String value) {
582         Map<String, String> map = new TreeMap<>(original);
583         map.put(key, value);
584         return map;
585     }
586
587     private void loadPolicy(String fileName) throws CoderException {
588         var template = yamlCoder.decode(ResourceUtils.getResourceAsString(fileName), ToscaServiceTemplate.class);
589         tosca = template.getToscaTopologyTemplate().getPolicies().get(0).values().iterator().next();
590
591         params.setToscaPolicy(tosca);
592     }
593
594     private void loadStepsWithProperties(String... properties) {
595         stepa = new Step2(mgr, ControlLoopOperationParams.builder().build(), event) {
596
597             @Override
598             public boolean isPolicyStep() {
599                 return false;
600             }
601
602             @Override
603             public List<String> getPropertyNames() {
604                 return List.of(properties);
605             }
606
607             @Override
608             protected Operation buildOperation() {
609                 return policyOperation;
610             }
611         };
612
613         mgr.getSteps().add(stepa);
614         mgr.getSteps().add(stepb);
615     }
616
617     private OperationOutcome makeCompletedOutcome() {
618         var outcome = makeOutcome();
619         outcome.setEnd(outcome.getStart());
620
621         return outcome;
622     }
623
624     private OperationOutcome makeOutcome() {
625         var outcome = new OperationOutcome();
626         outcome.setActor(SIMPLE_ACTOR);
627         outcome.setOperation(SIMPLE_OPERATION);
628         outcome.setMessage(OUTCOME_MSG);
629         outcome.setResult(OperationResult.SUCCESS);
630         outcome.setStart(Instant.now());
631         outcome.setTarget(MY_TARGET);
632
633         return outcome;
634     }
635
636     private void checkResp(OperationOutcome outcome, String expectedPayload) {
637         var resp = mgr.makeControlLoopResponse(outcome);
638         assertNotNull(resp);
639         assertEquals(REQ_ID, resp.getRequestId());
640         assertEquals(expectedPayload, resp.getPayload());
641     }
642
643     /**
644      * Sets the target entity so a step doesn't have to be added to set it.
645      */
646     private void setTargetEntity() {
647         mgr.setProperty(OperationProperties.AAI_TARGET_ENTITY, MY_TARGET);
648     }
649
650
651     private class MyManager extends UsecasesEventManager {
652         private static final long serialVersionUID = 1L;
653
654         public MyManager(EventManagerServices services, ControlLoopParams params, VirtualControlLoopEvent event,
655                         WorkingMemory workMem) throws ControlLoopException {
656
657             super(services, params, event, workMem);
658         }
659
660         @Override
661         protected ExecutorService getBlockingExecutor() {
662             return executor;
663         }
664
665         @Override
666         protected void makeLock(String targetEntity, String requestId, int holdSec, LockCallback callback) {
667             var lock = new LockImpl(LockState.ACTIVE, targetEntity, requestId, holdSec, callback);
668             locks.add(lock);
669             callback.lockAvailable(lock);
670         }
671
672         @Override
673         protected PolicyEngine getPolicyEngineManager() {
674             return engineMgr;
675         }
676     }
677 }