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