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