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