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