Remove deprecated DMAAP dependency
[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-2024 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         when(services.getDataManager()).thenReturn(dataMgr);
371         when(workMem.getFactHandle(any())).thenReturn(factHandle);
372         mgr.start();
373         var outcome = makeOutcome();
374         mgr.addToHistory(outcome);
375
376         mgr.storeInDataBase(mgr.getPartialHistory().peekLast());
377
378         verify(dataMgr).store(REQ_ID.toString(), event.getClosedLoopControlName(), event, null,
379                         mgr.getPartialHistory().peekLast().getClOperation());
380     }
381
382     @Test
383     void testMakeControlLoopResponse() {
384         final var outcome = new OperationOutcome();
385
386         // no message - should return null
387         checkResp(outcome, null);
388
389         // not a PciMessage - should return null
390         outcome.setResponse("not-a-pci-message");
391         checkResp(outcome, null);
392
393         /*
394          * now work with a PciMessage
395          */
396         var msg = new PciMessage();
397         outcome.setResponse(msg);
398
399         var body = new PciBody();
400         msg.setBody(body);
401
402         var output = new PciResponse();
403         body.setOutput(output);
404
405         output.setPayload("my-payload");
406
407         // should generate a response, with a payload
408         checkResp(outcome, "my-payload");
409
410         /*
411          * these should generate a response, with null payload
412          */
413         output.setPayload(null);
414         checkResp(outcome, null);
415
416         body.setOutput(null);
417         checkResp(outcome, null);
418
419         msg.setBody(null);
420         checkResp(outcome, null);
421
422         outcome.setResponse(null);
423         checkResp(outcome, null);
424     }
425
426     @Test
427     void testCheckEventSyntax() {
428         /*
429          * only need to check one success and one failure from the super class method
430          */
431
432         // initially, it's valid
433         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
434
435         event.setTarget("unknown-target");
436         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
437                         .hasMessage("target field invalid");
438
439         event.setTarget(null);
440         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
441                         .hasMessage("No target field");
442
443         event.setRequestId(null);
444         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
445                         .hasMessage("No request ID");
446     }
447
448     @Test
449     void testValidateStatus() {
450         /*
451          * only need to check one success and one failure from the super class method
452          */
453         event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET);
454         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
455
456         event.setClosedLoopEventStatus(null);
457         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
458                         .hasMessage("Invalid value in closedLoopEventStatus");
459     }
460
461     @Test
462     void testValidateAaiData() {
463         event.setTargetType("unknown-target-type");
464         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
465                         .hasMessage("The target type is not supported");
466
467         event.setTargetType(null);
468         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
469                         .hasMessage("The Target type is null");
470
471         event.setAai(null);
472         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
473                         .hasMessage("AAI is null");
474
475         // VM case
476         event.setTargetType(ControlLoopTargetType.VM);
477         event.setAai(Map.of(UsecasesConstants.GENERIC_VNF_VNF_ID, MY_TARGET));
478         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
479
480         event.setAai(Map.of());
481         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class);
482
483         // VNF case
484         event.setTargetType(ControlLoopTargetType.VNF);
485         event.setAai(Map.of(UsecasesConstants.GENERIC_VNF_VNF_ID, MY_TARGET));
486         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
487
488         event.setAai(Map.of());
489         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class);
490
491         // PNF case
492         event.setTargetType(ControlLoopTargetType.PNF);
493         event.setAai(Map.of(UsecasesConstants.PNF_NAME, MY_TARGET));
494         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
495
496         event.setAai(Map.of());
497         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class);
498     }
499
500     @Test
501     void testValidateAaiVmVnfData() {
502         event.setTargetType(ControlLoopTargetType.VM);
503         event.setAai(Map.of(UsecasesConstants.GENERIC_VNF_VNF_ID, MY_TARGET));
504         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
505
506         event.setAai(Map.of(UsecasesConstants.VSERVER_VSERVER_NAME, MY_TARGET));
507         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
508
509         event.setAai(Map.of(UsecasesConstants.GENERIC_VNF_VNF_NAME, MY_TARGET));
510         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
511
512         event.setAai(Map.of());
513         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class).hasMessage(
514                         "generic-vnf.vnf-id or generic-vnf.vnf-name or vserver.vserver-name information missing");
515     }
516
517     @Test
518     void testValidateAaiPnfData() {
519         event.setTargetType(ControlLoopTargetType.PNF);
520         event.setAai(Map.of(UsecasesConstants.PNF_NAME, MY_TARGET));
521         assertThatCode(() -> mgr.checkEventSyntax(event)).doesNotThrowAnyException();
522
523         event.setAai(Map.of());
524         assertThatCode(() -> mgr.checkEventSyntax(event)).isInstanceOf(ControlLoopException.class)
525                         .hasMessage("AAI PNF object key pnf-name is missing");
526     }
527
528     @Test
529     void testIsClosedLoopDisabled() {
530         var orig = event.getAai();
531
532         event.setAai(addAai(orig, UsecasesConstants.VSERVER_IS_CLOSED_LOOP_DISABLED, "true"));
533         assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
534                         .isInstanceOf(IllegalStateException.class);
535
536         event.setAai(addAai(orig, UsecasesConstants.GENERIC_VNF_IS_CLOSED_LOOP_DISABLED, "true"));
537         assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
538                         .isInstanceOf(IllegalStateException.class);
539
540         event.setAai(addAai(orig, UsecasesConstants.PNF_IS_IN_MAINT, "true"));
541         assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
542                         .isInstanceOf(IllegalStateException.class);
543     }
544
545     @Test
546     void testIsProvStatusInactive() {
547         var orig = event.getAai();
548
549         event.setAai(addAai(orig, UsecasesConstants.VSERVER_PROV_STATUS, "ACTIVE"));
550         assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
551
552         event.setAai(addAai(orig, UsecasesConstants.VSERVER_PROV_STATUS, "inactive"));
553         assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
554                         .isInstanceOf(IllegalStateException.class);
555
556         event.setAai(addAai(orig, UsecasesConstants.GENERIC_VNF_PROV_STATUS, "ACTIVE"));
557         assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
558
559         event.setAai(addAai(orig, UsecasesConstants.GENERIC_VNF_PROV_STATUS, "inactive"));
560         assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
561                         .isInstanceOf(IllegalStateException.class);
562     }
563
564     @Test
565     void testIsAaiTrue() {
566         var orig = event.getAai();
567
568         for (var value : Arrays.asList("yes", "y", "true", "t", "yEs", "trUe")) {
569             event.setAai(addAai(orig, UsecasesConstants.VSERVER_IS_CLOSED_LOOP_DISABLED, value));
570             assertThatThrownBy(() -> new UsecasesEventManager(services, params, event, workMem))
571                             .isInstanceOf(IllegalStateException.class);
572         }
573
574         event.setAai(addAai(orig, UsecasesConstants.VSERVER_IS_CLOSED_LOOP_DISABLED, "false"));
575         assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
576
577         event.setAai(addAai(orig, UsecasesConstants.VSERVER_IS_CLOSED_LOOP_DISABLED, "no"));
578         assertThatCode(() -> new UsecasesEventManager(services, params, event, workMem)).doesNotThrowAnyException();
579     }
580
581
582
583     private Map<String, String> addAai(Map<String, String> original, String key, String value) {
584         Map<String, String> map = new TreeMap<>(original);
585         map.put(key, value);
586         return map;
587     }
588
589     private void loadPolicy(String fileName) throws CoderException {
590         var template = yamlCoder.decode(ResourceUtils.getResourceAsString(fileName), ToscaServiceTemplate.class);
591         tosca = template.getToscaTopologyTemplate().getPolicies().get(0).values().iterator().next();
592
593         params.setToscaPolicy(tosca);
594     }
595
596     private void loadStepsWithProperties(String... properties) {
597         stepa = new Step2(mgr, ControlLoopOperationParams.builder().build(), event) {
598
599             @Override
600             public boolean isPolicyStep() {
601                 return false;
602             }
603
604             @Override
605             public List<String> getPropertyNames() {
606                 return List.of(properties);
607             }
608
609             @Override
610             protected Operation buildOperation() {
611                 return policyOperation;
612             }
613         };
614
615         mgr.getSteps().add(stepa);
616         mgr.getSteps().add(stepb);
617     }
618
619     private OperationOutcome makeCompletedOutcome() {
620         var outcome = makeOutcome();
621         outcome.setEnd(outcome.getStart());
622
623         return outcome;
624     }
625
626     private OperationOutcome makeOutcome() {
627         var outcome = new OperationOutcome();
628         outcome.setActor(SIMPLE_ACTOR);
629         outcome.setOperation(SIMPLE_OPERATION);
630         outcome.setMessage(OUTCOME_MSG);
631         outcome.setResult(OperationResult.SUCCESS);
632         outcome.setStart(Instant.now());
633         outcome.setTarget(MY_TARGET);
634
635         return outcome;
636     }
637
638     private void checkResp(OperationOutcome outcome, String expectedPayload) {
639         var resp = mgr.makeControlLoopResponse(outcome);
640         assertNotNull(resp);
641         assertEquals(REQ_ID, resp.getRequestId());
642         assertEquals(expectedPayload, resp.getPayload());
643     }
644
645     /**
646      * Sets the target entity so a step doesn't have to be added to set it.
647      */
648     private void setTargetEntity() {
649         mgr.setProperty(OperationProperties.AAI_TARGET_ENTITY, MY_TARGET);
650     }
651
652
653     private class MyManager extends UsecasesEventManager {
654         private static final long serialVersionUID = 1L;
655
656         public MyManager(EventManagerServices services, ControlLoopParams params, VirtualControlLoopEvent event,
657                         WorkingMemory workMem) throws ControlLoopException {
658
659             super(services, params, event, workMem);
660         }
661
662         @Override
663         protected ExecutorService getBlockingExecutor() {
664             return executor;
665         }
666
667         @Override
668         protected void makeLock(String targetEntity, String requestId, int holdSec, LockCallback callback) {
669             var lock = new LockImpl(LockState.ACTIVE, targetEntity, requestId, holdSec, callback);
670             locks.add(lock);
671             callback.lockAvailable(lock);
672         }
673
674         @Override
675         protected PolicyEngine getPolicyEngineManager() {
676             return engineMgr;
677         }
678     }
679 }