f5346def85b6553afae878f29566545d0f171286
[policy/drools-applications.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.controlloop.common.rules.test;
22
23 import static org.junit.Assert.assertEquals;
24
25 import java.util.List;
26 import java.util.Map;
27 import java.util.UUID;
28 import java.util.concurrent.TimeUnit;
29 import java.util.function.Supplier;
30 import java.util.stream.Collectors;
31 import lombok.AccessLevel;
32 import lombok.Getter;
33 import org.awaitility.Awaitility;
34 import org.junit.Test;
35 import org.onap.policy.appc.Request;
36 import org.onap.policy.appclcm.AppcLcmDmaapWrapper;
37 import org.onap.policy.common.utils.coder.Coder;
38 import org.onap.policy.common.utils.coder.CoderException;
39 import org.onap.policy.common.utils.coder.StandardCoder;
40 import org.onap.policy.common.utils.coder.StandardCoderInstantAsMillis;
41 import org.onap.policy.controlloop.ControlLoopNotificationType;
42 import org.onap.policy.controlloop.VirtualControlLoopNotification;
43 import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager2;
44 import org.onap.policy.drools.system.PolicyEngineConstants;
45 import org.onap.policy.drools.system.internal.SimpleLockManager;
46 import org.onap.policy.drools.system.internal.SimpleLockManager.SimpleLock;
47 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
48 import org.onap.policy.sdnr.PciMessage;
49 import org.powermock.reflect.Whitebox;
50
51 /**
52  * Superclass used for rule tests.
53  */
54 public abstract class BaseTest {
55     private static final String APPC_RESTART_OP = "restart";
56     private static final String APPC_MODIFY_CONFIG_OP = "ModifyConfig";
57
58     /*
59      * Canonical Topic Names.
60      */
61     protected static final String DCAE_TOPIC = "DCAE_TOPIC";
62     protected static final String APPC_LCM_WRITE_TOPIC = "APPC-LCM-WRITE";
63     protected static final String POLICY_CL_MGT_TOPIC = "POLICY-CL-MGT";
64     protected static final String APPC_LCM_READ_TOPIC = "APPC-LCM-READ";
65     protected static final String APPC_CL_TOPIC = "APPC-CL";
66     protected static final String SDNR_CL_TOPIC = "SDNR-CL";
67     protected static final String SDNR_CL_RSP_TOPIC = "SDNR-CL-RSP";
68
69     /*
70      * Constants for each test case.
71      */
72
73     // service123 (i.e., multi-operation policy)
74     private static final String SERVICE123_TOSCA_COMPLIANT_POLICY = "service123/tosca-compliant-service123.json";
75     private static final String SERVICE123_ONSET = "service123/service123.onset.json";
76     private static final String SERVICE123_APPC_RESTART_FAILURE = "service123/service123.appc.restart.failure.json";
77     private static final String SERVICE123_APPC_REBUILD_FAILURE = "service123/service123.appc.rebuild.failure.json";
78     private static final String SERVICE123_APPC_MIGRATE_SUCCESS = "service123/service123.appc.migrate.success.json";
79
80     // duplicates (i.e., mutliple events in the engine at the same time)
81     private static final String DUPLICATES_TOSCA_COMPLIANT_POLICY = "duplicates/tosca-compliant-duplicates.json";
82     private static final String DUPLICATES_ONSET_1 = "duplicates/duplicates.onset.1.json";
83     private static final String DUPLICATES_ONSET_2 = "duplicates/duplicates.onset.2.json";
84     private static final String DUPLICATES_APPC_SUCCESS = "duplicates/duplicates.appc.success.json";
85
86     // VCPE
87     private static final String VCPE_TOSCA_COMPLIANT_POLICY = "vcpe/tosca-compliant-vcpe.json";
88     private static final String VCPE_ONSET_1 = "vcpe/vcpe.onset.1.json";
89     private static final String VCPE_ONSET_2 = "vcpe/vcpe.onset.2.json";
90     private static final String VCPE_ONSET_3 = "vcpe/vcpe.onset.3.json";
91     private static final String VCPE_APPC_SUCCESS = "vcpe/vcpe.appc.success.json";
92
93     // VDNS
94     private static final String VDNS_TOSCA_COMPLIANT_POLICY = "vdns/tosca-compliant-vdns.json";
95     private static final String VDNS_TOSCA_COMPLIANT_RAINY_POLICY = "vdns/tosca-compliant-vdns-rainy.json";
96     private static final String VDNS_ONSET = "vdns/vdns.onset.json";
97
98     // VFW
99     private static final String VFW_TOSCA_COMPLIANT_POLICY = "vfw/tosca-compliant-vfw.json";
100     private static final String VFW_TOSCA_COMPLIANT_TIME_OUT_POLICY = "vfw/tosca-compliant-timeout-vfw.json";
101     private static final String VFW_ONSET = "vfw/vfw.onset.json";
102     private static final String VFW_APPC_SUCCESS = "vfw/vfw.appc.success.json";
103     private static final String VFW_APPC_FAILURE = "vfw/vfw.appc.failure.json";
104
105     // VPCI
106     private static final String VPCI_TOSCA_COMPLIANT_POLICY = "vpci/tosca-compliant-vpci.json";
107     private static final String VPCI_ONSET = "vpci/vpci.onset.json";
108     private static final String VPCI_SDNR_SUCCESS = "vpci/vpci.sdnr.success.json";
109
110     // VSONH
111     private static final String VSONH_TOSCA_COMPLIANT_POLICY = "vsonh/tosca-compliant-vsonh.json";
112     private static final String VSONH_ONSET = "vsonh/vsonh.onset.json";
113     private static final String VSONH_SDNR_SUCCESS = "vsonh/vsonh.sdnr.success.json";
114
115     /*
116      * Coders used to decode requests and responses.
117      */
118     protected static final Coder APPC_LEGACY_CODER = new StandardCoderInstantAsMillis();
119     protected static final Coder APPC_LCM_CODER = new StandardCoder();
120     protected static final Coder POLICY_CL_MGT_CODER = new PolicyClMgtCoder();
121
122     /*
123      * Coders used to decode requests and responses.
124      */
125     private static final Coder SDNR_CODER = new StandardCoder();
126
127     // these may be overridden by junit tests
128     protected static Supplier<HttpClients> httpClientMaker = HttpClients::new;
129     protected static Supplier<Simulators> simMaker = Simulators::new;
130     protected static Supplier<Topics> topicMaker = Topics::new;
131
132     protected static Rules rules;
133     protected static HttpClients httpClients;
134     protected static Simulators simulators;
135
136     // used to inject and wait for messages
137     @Getter(AccessLevel.PROTECTED)
138     protected static Topics topics;
139
140     // used to wait for messages on SINK topics
141     protected Listener<VirtualControlLoopNotification> policyClMgt;
142     protected Listener<Request> appcClSink;
143     protected Listener<AppcLcmDmaapWrapper> appcLcmRead;
144     protected Listener<PciMessage> sdnrClSink;
145
146     /*
147      * Tosca Policy that was loaded.
148      */
149     protected ToscaPolicy policy;
150
151     /**
152      * Initializes {@link #rules}, {@link #httpClients}, and {@link #simulators}.
153      */
154     public static void initStatics() {
155         httpClients = httpClientMaker.get();
156         simulators = simMaker.get();
157     }
158
159     /**
160      * Destroys {@link #httpClients}, {@link #simulators}, and {@link #rules}.
161      */
162     public static void finishStatics() {
163         httpClients.destroy();
164         simulators.destroy();
165     }
166
167     /**
168      * Initializes {@link #topics} and {@link #controller}.
169      */
170     public void init() {
171         topics = topicMaker.get();
172
173         Map<String, SimpleLock> locks = getLockMap();
174         if (locks != null) {
175             locks.clear();
176         }
177     }
178
179     /**
180      * Destroys {@link #topics} and resets the rule facts.
181      */
182     public void finish() {
183         topics.destroy();
184     }
185
186     // Service123 (i.e., Policy with multiple operations)
187
188     /**
189      * Service123 with Tosca Compliant Policy.
190      */
191     @Test
192     public void testService123Compliant() {
193         policyClMgt = createNoficationTopicListener();
194         appcLcmRead = topics.createListener(APPC_LCM_READ_TOPIC, AppcLcmDmaapWrapper.class, APPC_LCM_CODER);
195         policy = checkPolicy(SERVICE123_TOSCA_COMPLIANT_POLICY);
196
197         // inject an ONSET event over the DCAE topic
198         topics.inject(DCAE_TOPIC, SERVICE123_ONSET);
199         /* Wait to acquire a LOCK and a PDP-X PERMIT */
200
201         waitForLockAndPermit(policy, policyClMgt);
202
203         // restart request should be sent and fail four times (i.e., because retry=3)
204         for (int count = 0; count < 4; ++count) {
205             AppcLcmDmaapWrapper appcreq = appcLcmRead.await(req -> APPC_RESTART_OP.equals(req.getRpcName()));
206
207             topics.inject(APPC_LCM_WRITE_TOPIC, SERVICE123_APPC_RESTART_FAILURE,
208                             appcreq.getBody().getInput().getCommonHeader().getSubRequestId());
209         }
210         // rebuild request should be sent and fail once
211         AppcLcmDmaapWrapper appcreq = appcLcmRead.await(req -> "rebuild".equals(req.getRpcName()));
212         topics.inject(APPC_LCM_WRITE_TOPIC, SERVICE123_APPC_REBUILD_FAILURE,
213                         appcreq.getBody().getInput().getCommonHeader().getSubRequestId());
214         // migrate request should be sent and succeed
215         appcreq = appcLcmRead.await(req -> "migrate".equals(req.getRpcName()));
216         topics.inject(APPC_LCM_WRITE_TOPIC, SERVICE123_APPC_MIGRATE_SUCCESS,
217                         appcreq.getBody().getInput().getCommonHeader().getSubRequestId());
218         /* --- Operation Completed --- */
219         waitForOperationSuccess();
220         /* --- Transaction Completed --- */
221         waitForFinalSuccess(policy, policyClMgt);
222
223         verifyUnlocked();
224     }
225
226     // Duplicate events
227
228     /**
229      * This test case tests the scenario where 3 events occur and 2 of the requests refer
230      * to the same target entity while the 3rd is for another entity. The expected result
231      * is that the event with the duplicate target entity will have a final success result
232      * for one of the events, and a rejected message for the one that was unable to obtain
233      * the lock. The event that is referring to a different target entity should be able
234      * to obtain a lock since it is a different target. After processing of all events
235      * there should only be the policy and params objects left in memory.
236      */
237     @Test
238     public void testDuplicatesEvents() {
239         policyClMgt = createNoficationTopicListener();
240         appcLcmRead = topics.createListener(APPC_LCM_READ_TOPIC, AppcLcmDmaapWrapper.class, APPC_LCM_CODER);
241
242         policy = checkPolicy(DUPLICATES_TOSCA_COMPLIANT_POLICY);
243
244         final long initCount = getCreateCount();
245
246         /*
247          * Inject ONSET events over the DCAE topic. First and last have the same target
248          * entity, but different request IDs - only one should succeed. The middle one is
249          * for a different target entity, so it should succeed.
250          */
251         topics.inject(DCAE_TOPIC, DUPLICATES_ONSET_1, UUID.randomUUID().toString());
252         topics.inject(DCAE_TOPIC, DUPLICATES_ONSET_2);
253         topics.inject(DCAE_TOPIC, DUPLICATES_ONSET_1, UUID.randomUUID().toString());
254
255         // should see two restarts
256         for (int count = 0; count < 2; ++count) {
257             AppcLcmDmaapWrapper appcreq = appcLcmRead.await(req -> APPC_RESTART_OP.equals(req.getRpcName()));
258
259             // indicate success
260             topics.inject(APPC_LCM_WRITE_TOPIC, DUPLICATES_APPC_SUCCESS,
261                             appcreq.getBody().getInput().getCommonHeader().getSubRequestId());
262         }
263
264         // should see two FINAL successes
265         VirtualControlLoopNotification notif1 = waitForFinalSuccess(policy, policyClMgt);
266         VirtualControlLoopNotification notif2 = waitForFinalSuccess(policy, policyClMgt);
267
268         // get the list of target names so we can ensure there's one of each
269         List<String> actual = List.of(notif1, notif2).stream().map(notif -> notif.getAai().get("generic-vnf.vnf-id"))
270                         .sorted().collect(Collectors.toList());
271
272         assertEquals(List.of("duplicate-VNF", "vCPE_Infrastructure_vGMUX_demo_app").toString(), actual.toString());
273
274         long added = getCreateCount() - initCount;
275         assertEquals(2, added);
276
277         verifyUnlocked();
278     }
279
280     // VCPE
281
282     /**
283      * Sunny Day with Tosca Compliant Policy.
284      */
285     @Test
286     public void testVcpeSunnyDayCompliant() {
287         appcLcmSunnyDay(VCPE_TOSCA_COMPLIANT_POLICY, VCPE_ONSET_1, APPC_RESTART_OP);
288     }
289
290     /**
291      * An ONSET flood prevention test that injects a few ONSETs at once. It attempts to
292      * simulate the flooding behavior of the DCAE TCA microservice. TCA could blast tens
293      * or hundreds of ONSETs within sub-second intervals.
294      */
295     @Test
296     public void testVcpeOnsetFloodPrevention() {
297         appcLcmSunnyDay(VCPE_TOSCA_COMPLIANT_POLICY, List.of(VCPE_ONSET_1, VCPE_ONSET_2, VCPE_ONSET_3),
298                         APPC_RESTART_OP);
299     }
300
301     // VDNS
302
303     /**
304      * Sunny Day with Tosca Compliant Policy.
305      */
306     @Test
307     public void testVdnsSunnyDayCompliant() {
308         httpSunnyDay(VDNS_TOSCA_COMPLIANT_POLICY, VDNS_ONSET);
309     }
310
311     /**
312      * Vdns Rainy Day with Compliant Tosca Policy.
313      */
314     @Test
315     public void testVdnsRainyDayCompliant() {
316         httpRainyDay(VDNS_TOSCA_COMPLIANT_RAINY_POLICY, VDNS_ONSET);
317     }
318
319
320     // VFW
321
322     /**
323      * VFW Sunny Day with Tosca Compliant Policy.
324      */
325     @Test
326     public void testVfwSunnyDayCompliant() {
327         appcLegacySunnyDay(VFW_TOSCA_COMPLIANT_POLICY, VFW_ONSET, APPC_MODIFY_CONFIG_OP);
328     }
329
330     /**
331      * VFW Rainy Day using compliant tosca policy (final failure).
332      */
333     @Test
334     public void testVfwRainyDayOverallTimeout() {
335         appcLegacyRainyDayNoResponse(VFW_TOSCA_COMPLIANT_TIME_OUT_POLICY, VFW_ONSET, APPC_MODIFY_CONFIG_OP);
336     }
337
338     /**
339      * VFW Rainy day using compliant tosca policy (final failure due to timeout).
340      */
341     @Test
342     public void testVfwRainyDayCompliantTimeout() {
343         appcLegacyRainyDayNoResponse(VFW_TOSCA_COMPLIANT_POLICY, VFW_ONSET, APPC_MODIFY_CONFIG_OP);
344     }
345
346     /**
347      * VPCI Sunny Day Tosca Policy.
348      */
349     @Test
350     public void testVpciSunnyDayCompliant() {
351         sdnrSunnyDay(VPCI_TOSCA_COMPLIANT_POLICY, VPCI_ONSET, VPCI_SDNR_SUCCESS, "ModifyConfig");
352     }
353
354     // VSONH
355
356     /**
357      * VSONH Sunny Day with Tosca Policy.
358      */
359     @Test
360     public void testVsonhSunnyDayCompliant() {
361         sdnrSunnyDay(VSONH_TOSCA_COMPLIANT_POLICY, VSONH_ONSET, VSONH_SDNR_SUCCESS, "ModifyConfigANR");
362     }
363
364     /**
365      * Sunny day scenario for use cases that use APPC-LCM.
366      *
367      * @param policyFile file containing the ToscaPolicy to be loaded
368      * @param onsetFile file containing the ONSET to be injected
369      * @param operation expected APPC operation request
370      */
371     protected void appcLcmSunnyDay(String policyFile, String onsetFile, String operation) {
372         appcLcmSunnyDay(policyFile, List.of(onsetFile), operation);
373     }
374
375     /**
376      * Sunny day scenario for use cases that use APPC-LCM.
377      *
378      * @param policyFile file containing the ToscaPolicy to be loaded
379      * @param onsetFiles list of files containing the ONSET to be injected
380      * @param operation expected APPC operation request
381      */
382     protected void appcLcmSunnyDay(String policyFile, List<String> onsetFiles, String operation) {
383         policyClMgt = createNoficationTopicListener();
384         appcLcmRead = topics.createListener(APPC_LCM_READ_TOPIC, AppcLcmDmaapWrapper.class, APPC_LCM_CODER);
385
386         policy = checkPolicy(policyFile);
387
388
389         // inject several ONSET events over the DCAE topic
390         for (String onsetFile : onsetFiles) {
391             topics.inject(DCAE_TOPIC, onsetFile);
392         }
393
394         /* Wait to acquire a LOCK and a PDP-X PERMIT */
395         waitForLockAndPermit(policy, policyClMgt);
396
397         /*
398          * Ensure that an APPC RESTART request was sent in response to the matching ONSET
399          */
400         AppcLcmDmaapWrapper appcreq = appcLcmRead.await(req -> operation.equals(req.getRpcName()));
401
402         /*
403          * Inject a 400 APPC Response Return over the APPC topic, with appropriate
404          * subRequestId
405          */
406         topics.inject(APPC_LCM_WRITE_TOPIC, VCPE_APPC_SUCCESS,
407                         appcreq.getBody().getInput().getCommonHeader().getSubRequestId());
408
409         /* --- Operation Completed --- */
410
411         waitForOperationSuccess();
412
413         /* --- Transaction Completed --- */
414         waitForFinalSuccess(policy, policyClMgt);
415
416         verifyUnlocked();
417     }
418
419     /**
420      * Sunny day scenario for use cases that use Legacy APPC.
421      *
422      * @param policyFile file containing the ToscaPolicy to be loaded
423      * @param onsetFile file containing the ONSET to be injected
424      * @param operation expected APPC operation request
425      */
426     protected void appcLegacySunnyDay(String policyFile, String onsetFile, String operation) {
427         policyClMgt = createNoficationTopicListener();
428         appcClSink = topics.createListener(APPC_CL_TOPIC, Request.class, APPC_LEGACY_CODER);
429
430         policy = checkPolicy(policyFile);
431
432         /* Inject an ONSET event over the DCAE topic */
433         topics.inject(DCAE_TOPIC, onsetFile);
434
435         /* Wait to acquire a LOCK and a PDP-X PERMIT */
436         waitForLockAndPermit(policy, policyClMgt);
437
438         /*
439          * Ensure that an APPC RESTART request was sent in response to the matching ONSET
440          */
441         Request appcreq = appcClSink.await(req -> operation.equals(req.getAction()));
442
443         /*
444          * Inject a 400 APPC Response Return over the APPC topic, with appropriate
445          * subRequestId
446          */
447         topics.inject(APPC_CL_TOPIC, VFW_APPC_SUCCESS, appcreq.getCommonHeader().getSubRequestId());
448
449         /* --- Operation Completed --- */
450
451         waitForOperationSuccess();
452
453         /* --- Transaction Completed --- */
454         waitForFinalSuccess(policy, policyClMgt);
455
456         verifyUnlocked();
457     }
458
459     /**
460      * Rainy day scenario for use cases that use Legacy APPC.
461      *
462      * @param policyFile file containing the ToscaPolicy to be loaded
463      * @param onsetFile file containing the ONSET to be injected
464      * @param operation expected APPC operation request
465      * @param checkOperation flag to determine whether or not to wait for operation
466      *        timeout
467      */
468     protected void appcLegacyRainyDay(String policyFile, String onsetFile, String operation) {
469         policyClMgt = createNoficationTopicListener();
470         appcClSink = topics.createListener(APPC_CL_TOPIC, Request.class, APPC_LEGACY_CODER);
471
472         policy = checkPolicy(policyFile);
473
474         /* Inject an ONSET event over the DCAE topic */
475         topics.inject(DCAE_TOPIC, onsetFile);
476
477         /* Wait to acquire a LOCK and a PDP-X PERMIT */
478         waitForLockAndPermit(policy, policyClMgt);
479
480         /*
481          * Ensure that an APPC RESTART request was sent in response to the matching ONSET
482          */
483         Request appcreq = appcClSink.await(req -> operation.equals(req.getAction()));
484
485         /*
486          * Inject a 401 APPC Response Return over the APPC topic, with appropriate
487          * subRequestId
488          */
489         topics.inject(APPC_CL_TOPIC, VFW_APPC_FAILURE, appcreq.getCommonHeader().getSubRequestId());
490
491         /* --- Operation Completed --- */
492         waitForOperationFailure();
493
494         /* --- Transaction Completed --- */
495         waitForFinalFailure(policy, policyClMgt);
496
497         verifyUnlocked();
498     }
499
500     /**
501      * Rainy day scenario for use cases that use Legacy APPC. Expected to fail due to
502      * timeout.
503      *
504      * @param policyFile file containing the ToscaPolicy to be loaded
505      * @param onsetFile file containing the ONSET to be injected
506      * @param operation expected APPC operation request
507      */
508     protected void appcLegacyRainyDayNoResponse(String policyFile, String onsetFile, String operation) {
509         policyClMgt = createNoficationTopicListener();
510         appcClSink = topics.createListener(APPC_CL_TOPIC, Request.class, APPC_LEGACY_CODER);
511
512         policy = checkPolicy(policyFile);
513
514         /* Inject an ONSET event over the DCAE topic */
515         topics.inject(DCAE_TOPIC, onsetFile);
516
517         /* Wait to acquire a LOCK and a PDP-X PERMIT */
518         waitForLockAndPermit(policy, policyClMgt);
519
520         /*
521          * Ensure that an APPC RESTART request was sent in response to the matching ONSET
522          */
523         appcClSink.await(req -> operation.equals(req.getAction()));
524
525         /*
526          * Do not inject an APPC Response.
527          */
528
529         /* --- Transaction Completed --- */
530         waitForFinalFailure(policy, policyClMgt);
531
532         verifyUnlocked();
533     }
534
535     /**
536      * Sunny day scenario for use cases that use SDNR.
537      *
538      * @param policyFile file containing the ToscaPolicy to be loaded
539      * @param onsetFile file containing the ONSET to be injected
540      * @param operation expected SDNR operation request
541      */
542     protected void sdnrSunnyDay(String policyFile, String onsetFile, String successFile, String operation) {
543         policyClMgt = createNoficationTopicListener();
544         sdnrClSink = topics.createListener(SDNR_CL_TOPIC, PciMessage.class, SDNR_CODER);
545
546         policy = checkPolicy(policyFile);
547
548         /* Inject an ONSET event over the DCAE topic */
549         topics.inject(DCAE_TOPIC, onsetFile);
550
551         /* Wait to acquire a LOCK and a PDP-X PERMIT */
552         waitForLockAndPermit(policy, policyClMgt);
553
554         /*
555          * Ensure that an SDNR RESTART request was sent in response to the matching ONSET
556          */
557         PciMessage pcireq = sdnrClSink.await(req -> operation.equals(req.getBody().getInput().getAction()));
558
559         /*
560          * Inject response.
561          */
562         topics.inject(SDNR_CL_RSP_TOPIC, successFile, pcireq.getBody().getInput().getCommonHeader().getSubRequestId());
563
564         /* --- Operation Completed --- */
565
566         waitForOperationSuccess();
567
568         /* --- Transaction Completed --- */
569         waitForFinalSuccess(policy, policyClMgt);
570
571         verifyUnlocked();
572     }
573
574     /**
575      * Sunny day scenario for use cases that use an HTTP simulator.
576      *
577      * @param policyFile file containing the ToscaPolicy to be loaded
578      * @param onsetFile file containing the ONSET to be injected
579      * @param operation expected APPC operation request
580      */
581     protected void httpSunnyDay(String policyFile, String onsetFile) {
582         policyClMgt = createNoficationTopicListener();
583
584         policy = checkPolicy(policyFile);
585
586         /* Inject an ONSET event over the DCAE topic */
587         topics.inject(DCAE_TOPIC, onsetFile);
588
589         /* Wait to acquire a LOCK and a PDP-X PERMIT */
590         waitForLockAndPermit(policy, policyClMgt);
591
592         /* --- Operation Completed --- */
593
594         waitForOperationSuccess();
595
596         /* --- Transaction Completed --- */
597         waitForFinalSuccess(policy, policyClMgt);
598
599         verifyUnlocked();
600     }
601
602     /**
603      * Rainy day scenario for use cases that use an HTTP simulator.
604      *
605      * @param policyFile file containing the ToscaPolicy to be loaded
606      * @param onsetFile file containing the ONSET to be injected
607      * @param operation expected APPC operation request
608      */
609     protected void httpRainyDay(String policyFile, String onsetFile) {
610         policyClMgt = createNoficationTopicListener();
611
612         policy = checkPolicy(policyFile);
613
614         /* Inject an ONSET event over the DCAE topic */
615         topics.inject(DCAE_TOPIC, onsetFile);
616
617         /* Wait to acquire a LOCK and a PDP-X PERMIT */
618         waitForLockAndPermit(policy, policyClMgt);
619
620         /* --- Operation Completed --- */
621         waitForOperationFailure();
622
623         /* --- Transaction Completed --- */
624         waitForFinalFailure(policy, policyClMgt);
625
626         verifyUnlocked();
627     }
628
629     protected long getCreateCount() {
630         return ControlLoopEventManager2.getCreateCount();
631     }
632
633     /**
634      * Waits for a OPERATION SUCCESS transaction notification.
635      */
636     protected void waitForOperationSuccess() {
637         policyClMgt.await(notif -> notif.getNotification() == ControlLoopNotificationType.OPERATION_SUCCESS);
638     }
639
640     /**
641      * Waits for a FINAL SUCCESS transaction notification.
642      *
643      * @return the FINAL SUCCESS notification
644      */
645     protected VirtualControlLoopNotification waitForFinalSuccess(ToscaPolicy policy,
646                     Listener<VirtualControlLoopNotification> policyClMgt) {
647
648         return this.waitForFinal(policy, policyClMgt, ControlLoopNotificationType.FINAL_SUCCESS);
649     }
650
651     /**
652      * Waits for a OPERATION FAILURE transaction notification.
653      */
654     protected void waitForOperationFailure() {
655         policyClMgt.await(notif -> notif.getNotification() == ControlLoopNotificationType.OPERATION_FAILURE);
656     }
657
658     /**
659      * Waits for a FINAL FAILURE transaction notification.
660      *
661      * @return the FINAL FAILURE notification
662      */
663     protected VirtualControlLoopNotification waitForFinalFailure(ToscaPolicy policy,
664                     Listener<VirtualControlLoopNotification> policyClMgt) {
665
666         return this.waitForFinal(policy, policyClMgt, ControlLoopNotificationType.FINAL_FAILURE);
667     }
668
669     /**
670      * Waits for notifications for LOCK acquisition and GUARD Permit so that event
671      * processing may proceed.
672      */
673     protected abstract void waitForLockAndPermit(ToscaPolicy policy,
674                     Listener<VirtualControlLoopNotification> policyClMgt);
675
676     /**
677      * Waits for a FINAL transaction notification.
678      *
679      * @param finalType FINAL_xxx type for which to wait
680      *
681      * @return the FINAL notification
682      */
683     protected abstract VirtualControlLoopNotification waitForFinal(ToscaPolicy policy,
684                     Listener<VirtualControlLoopNotification> policyClMgt, ControlLoopNotificationType finalType);
685
686     /**
687      * Returns ToscaPolicy from File.
688      *
689      * @param fileName a path name
690      * @return ToscaPolicy
691      */
692     protected ToscaPolicy checkPolicy(String fileName) {
693         try {
694             return Rules.getPolicyFromFile(fileName);
695         } catch (CoderException e) {
696             throw new IllegalArgumentException(fileName, e);
697         }
698     }
699
700     /**
701      * Creates a Coder for PolicyClMgt from StandardCoder.
702      *
703      */
704     public static class PolicyClMgtCoder extends StandardCoder {
705         public PolicyClMgtCoder() {
706             super(org.onap.policy.controlloop.util.Serialization.gson,
707                             org.onap.policy.controlloop.util.Serialization.gsonPretty);
708         }
709     }
710
711     /**
712      * Returns Listener from createListner based on Coder.
713      *
714      * @return the Listener
715      */
716     protected Listener<VirtualControlLoopNotification> createNoficationTopicListener() {
717         return topics.createListener(POLICY_CL_MGT_TOPIC, VirtualControlLoopNotification.class, POLICY_CL_MGT_CODER);
718     }
719
720     /**
721      * Verifies that all locks have been released, waiting a bit, if necessary.
722      */
723     private void verifyUnlocked() {
724         Map<String, SimpleLock> locks = getLockMap();
725         if (locks != null) {
726             Awaitility.await().atMost(5, TimeUnit.SECONDS).until(locks::isEmpty);
727         }
728     }
729
730     private Map<String, SimpleLock> getLockMap() {
731         Object lockMgr = Whitebox.getInternalState(PolicyEngineConstants.getManager(), "lockManager");
732         if (lockMgr instanceof SimpleLockManager) {
733             return Whitebox.getInternalState(lockMgr, "resource2lock");
734         }
735
736         return null;
737     }
738 }