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