631b3f6def0019e1e82957c5d00e038cf5ccf331
[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
33 import org.junit.Ignore;
34 import org.junit.Test;
35 import org.onap.policy.appc.Request;
36 import org.onap.policy.appclcm.AppcLcmDmaapWrapper;
37 import org.onap.policy.common.utils.coder.Coder;
38 import org.onap.policy.common.utils.coder.StandardCoder;
39 import org.onap.policy.common.utils.coder.StandardCoderInstantAsMillis;
40 import org.onap.policy.controlloop.ControlLoopNotificationType;
41 import org.onap.policy.controlloop.VirtualControlLoopNotification;
42 import org.onap.policy.drools.system.PolicyController;
43 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
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
61     /*
62      * Constants for each test case.
63      */
64
65     // service123 (i.e., multi-operation policy)
66     private static final String SERVICE123_TOSCA_COMPLIANT_POLICY = "service123/tosca-compliant-service123.json";
67     private static final String SERVICE123_ONSET = "service123/service123.onset.json";
68     private static final String SERVICE123_APPC_RESTART_FAILURE = "service123/service123.appc.restart.failure.json";
69     private static final String SERVICE123_APPC_REBUILD_FAILURE = "service123/service123.appc.rebuild.failure.json";
70     private static final String SERVICE123_APPC_MIGRATE_SUCCESS = "service123/service123.appc.migrate.success.json";
71
72     // duplicates (i.e., mutliple events in the engine at the same time)
73     private static final String DUPLICATES_TOSCA_COMPLIANT_POLICY = "duplicates/tosca-compliant-duplicates.json";
74     private static final String DUPLICATES_ONSET_1 = "duplicates/duplicates.onset.1.json";
75     private static final String DUPLICATES_ONSET_2 = "duplicates/duplicates.onset.2.json";
76     private static final String DUPLICATES_APPC_SUCCESS = "duplicates/duplicates.appc.success.json";
77
78     // VCPE
79     private static final String VCPE_TOSCA_LEGACY_POLICY = "vcpe/tosca-legacy-vcpe.json";
80     private static final String VCPE_TOSCA_COMPLIANT_POLICY = "vcpe/tosca-compliant-vcpe.json";
81     private static final String VCPE_ONSET_1 = "vcpe/vcpe.onset.1.json";
82     private static final String VCPE_ONSET_2 = "vcpe/vcpe.onset.2.json";
83     private static final String VCPE_ONSET_3 = "vcpe/vcpe.onset.3.json";
84     private static final String VCPE_APPC_SUCCESS = "vcpe/vcpe.appc.success.json";
85
86     // VDNS
87     private static final String VDNS_TOSCA_LEGACY_POLICY = "vdns/tosca-legacy-vdns.json";
88     private static final String VDNS_TOSCA_COMPLIANT_POLICY = "vdns/tosca-compliant-vdns.json";
89     private static final String VDNS_ONSET = "vdns/vdns.onset.json";
90
91     // VFW
92     private static final String VFW_TOSCA_LEGACY_POLICY = "vfw/tosca-vfw.json";
93     private static final String VFW_TOSCA_COMPLIANT_POLICY = "vfw/tosca-compliant-vfw.json";
94     private static final String VFW_TOSCA_COMPLIANT_TIME_OUT_POLICY = "vfw/tosca-compliant-timeout-vfw.json";
95     private static final String VFW_ONSET = "vfw/vfw.onset.json";
96     private static final String VFW_APPC_SUCCESS = "vfw/vfw.appc.success.json";
97     private static final String VFW_APPC_FAILURE = "vfw/vfw.appc.failure.json";
98
99     /*
100      * Coders used to decode requests and responses.
101      */
102     private static final Coder APPC_LEGACY_CODER = new StandardCoderInstantAsMillis();
103     private static final Coder APPC_LCM_CODER = new StandardCoder();
104
105     // these may be overridden by junit tests
106     private static Function<String, Rules> ruleMaker = Rules::new;
107     private static Supplier<HttpClients> httpClientMaker = HttpClients::new;
108     private static Supplier<Simulators> simMaker = Simulators::new;
109     private static Supplier<Topics> topicMaker = Topics::new;
110
111     protected static Rules rules;
112     protected static HttpClients httpClients;
113     protected static Simulators simulators;
114
115     // used to inject and wait for messages
116     @Getter(AccessLevel.PROTECTED)
117     private Topics topics;
118
119     // used to wait for messages on SINK topics
120     protected Listener<VirtualControlLoopNotification> policyClMgt;
121     protected Listener<Request> appcClSink;
122     protected Listener<AppcLcmDmaapWrapper> appcLcmRead;
123
124     protected PolicyController controller;
125
126     /*
127      * Tosca Policy that was loaded.
128      */
129     protected ToscaPolicy policy;
130
131
132     /**
133      * Initializes {@link #rules}, {@link #httpClients}, and {@link #simulators}.
134      *
135      * @param controllerName the rule controller name
136      */
137     public static void initStatics(String controllerName) {
138         rules = ruleMaker.apply(controllerName);
139         httpClients = httpClientMaker.get();
140         simulators = simMaker.get();
141     }
142
143     /**
144      * Destroys {@link #httpClients}, {@link #simulators}, and {@link #rules}.
145      */
146     public static void finishStatics() {
147         httpClients.destroy();
148         simulators.destroy();
149         rules.destroy();
150     }
151
152     /**
153      * Initializes {@link #topics} and {@link #controller}.
154      */
155     public void init() {
156         topics = topicMaker.get();
157         controller = rules.getController();
158     }
159
160     /**
161      * Destroys {@link #topics} and resets the rule facts.
162      */
163     public void finish() {
164         topics.destroy();
165         rules.resetFacts();
166     }
167
168     // Service123 (i.e., Policy with multiple operations)
169
170     /**
171      * Service123 with Tosca Compliant Policy.
172      */
173     @Test
174     public void testService123Compliant() {
175         policyClMgt = topics.createListener(POLICY_CL_MGT_TOPIC, VirtualControlLoopNotification.class, controller);
176         appcLcmRead = topics.createListener(APPC_LCM_READ_TOPIC, AppcLcmDmaapWrapper.class, APPC_LCM_CODER);
177
178         assertEquals(0, controller.getDrools().factCount(rules.getControllerName()));
179         policy = rules.setupPolicyFromFile(SERVICE123_TOSCA_COMPLIANT_POLICY);
180         assertEquals(2, controller.getDrools().factCount(rules.getControllerName()));
181
182         // inject an ONSET event over the DCAE topic
183         topics.inject(DCAE_TOPIC, SERVICE123_ONSET);
184
185         /* Wait to acquire a LOCK and a PDP-X PERMIT */
186         waitForLockAndPermit(policy, policyClMgt);
187
188         // restart request should be sent and fail four times (i.e., because retry=3)
189         for (int count = 0; count < 4; ++count) {
190             AppcLcmDmaapWrapper appcreq = appcLcmRead.await(req -> APPC_RESTART_OP.equals(req.getRpcName()));
191
192             topics.inject(APPC_LCM_WRITE_TOPIC, SERVICE123_APPC_RESTART_FAILURE,
193                             appcreq.getBody().getInput().getCommonHeader().getSubRequestId());
194         }
195
196         // rebuild request should be sent and fail once
197         AppcLcmDmaapWrapper appcreq = appcLcmRead.await(req -> "rebuild".equals(req.getRpcName()));
198
199         topics.inject(APPC_LCM_WRITE_TOPIC, SERVICE123_APPC_REBUILD_FAILURE,
200                         appcreq.getBody().getInput().getCommonHeader().getSubRequestId());
201
202         // migrate request should be sent and succeed
203         appcreq = appcLcmRead.await(req -> "migrate".equals(req.getRpcName()));
204
205         topics.inject(APPC_LCM_WRITE_TOPIC, SERVICE123_APPC_MIGRATE_SUCCESS,
206                         appcreq.getBody().getInput().getCommonHeader().getSubRequestId());
207
208         /* --- Operation Completed --- */
209
210         waitForOperationSuccess();
211
212         /* --- Transaction Completed --- */
213         waitForFinalSuccess(policy, policyClMgt);
214     }
215
216     // Duplicate events
217
218     /**
219      * This test case tests the scenario where 3 events occur and 2 of the requests refer
220      * to the same target entity while the 3rd is for another entity. The expected result
221      * is that the event with the duplicate target entity will have a final success result
222      * for one of the events, and a rejected message for the one that was unable to obtain
223      * the lock. The event that is referring to a different target entity should be able
224      * to obtain a lock since it is a different target. After processing of all events
225      * there should only be the policy and params objects left in memory.
226      */
227     // Ignoring test due to TimeoutException (for some reason this test fails only on docker build)
228     // https://jenkins.onap.org/job/policy-drools-applications-maven-docker-stage-master/294/
229     @Ignore
230     @Test
231     public void testDuplicatesEvents() {
232         policyClMgt = topics.createListener(POLICY_CL_MGT_TOPIC, VirtualControlLoopNotification.class, controller);
233         appcLcmRead = topics.createListener(APPC_LCM_READ_TOPIC, AppcLcmDmaapWrapper.class, APPC_LCM_CODER);
234
235         assertEquals(0, controller.getDrools().factCount(rules.getControllerName()));
236         policy = rules.setupPolicyFromFile(DUPLICATES_TOSCA_COMPLIANT_POLICY);
237         assertEquals(2, controller.getDrools().factCount(rules.getControllerName()));
238
239         /*
240          * Inject ONSET events over the DCAE topic. First and last have the same target
241          * entity, but different request IDs - only one should succeed. The middle one is
242          * for a different target entity, so it should succeed.
243          */
244         topics.inject(DCAE_TOPIC, DUPLICATES_ONSET_1, UUID.randomUUID().toString());
245         topics.inject(DCAE_TOPIC, DUPLICATES_ONSET_2);
246         topics.inject(DCAE_TOPIC, DUPLICATES_ONSET_1, UUID.randomUUID().toString());
247
248         // one should immediately generate a FINAL failure
249         waitForFinal(policy, policyClMgt, ControlLoopNotificationType.FINAL_FAILURE);
250
251         // should see two restarts
252         for (int count = 0; count < 2; ++count) {
253             AppcLcmDmaapWrapper appcreq = appcLcmRead.await(req -> APPC_RESTART_OP.equals(req.getRpcName()));
254
255             // indicate success
256             topics.inject(APPC_LCM_WRITE_TOPIC, DUPLICATES_APPC_SUCCESS,
257                             appcreq.getBody().getInput().getCommonHeader().getSubRequestId());
258         }
259
260         // should see two FINAL successes
261         VirtualControlLoopNotification notif1 = waitForFinalSuccess(policy, policyClMgt);
262         VirtualControlLoopNotification notif2 = waitForFinalSuccess(policy, policyClMgt);
263
264         // get the list of target names so we can ensure there's one of each
265         List<String> actual = List.of(notif1, notif2).stream().map(notif -> notif.getAai().get("generic-vnf.vnf-id"))
266                         .sorted().collect(Collectors.toList());
267
268         assertEquals(List.of("duplicate-VNF", "vCPE_Infrastructure_vGMUX_demo_app").toString(), actual.toString());
269     }
270
271     // VCPE
272
273     /**
274      * Sunny Day with Legacy Tosca Policy.
275      */
276     @Test
277     public void testVcpeSunnyDayLegacy() {
278         appcLcmSunnyDay(VCPE_TOSCA_LEGACY_POLICY, VCPE_ONSET_1, APPC_RESTART_OP);
279     }
280
281     /**
282      * Sunny Day with Tosca Compliant Policy.
283      */
284     @Test
285     public void testVcpeSunnyDayCompliant() {
286         appcLcmSunnyDay(VCPE_TOSCA_COMPLIANT_POLICY, VCPE_ONSET_1, APPC_RESTART_OP);
287     }
288
289     /**
290      * An ONSET flood prevention test that injects a few ONSETs at once. It attempts to
291      * simulate the flooding behavior of the DCAE TCA microservice. TCA could blast tens
292      * or hundreds of ONSETs within sub-second intervals.
293      */
294     @Test
295     public void testVcpeOnsetFloodPrevention() {
296         appcLcmSunnyDay(VCPE_TOSCA_COMPLIANT_POLICY, List.of(VCPE_ONSET_1, VCPE_ONSET_2, VCPE_ONSET_3),
297                         APPC_RESTART_OP);
298     }
299
300     // VDNS
301
302     /**
303      * Sunny Day with Legacy Tosca Policy.
304      */
305     @Test
306     public void testVdnsSunnyDayLegacy() {
307         httpSunnyDay(VDNS_TOSCA_LEGACY_POLICY, VDNS_ONSET);
308     }
309
310     /**
311      * Sunny Day with Tosca Compliant Policy.
312      */
313     @Test
314     public void testVdnsSunnyDayCompliant() {
315         httpSunnyDay(VDNS_TOSCA_COMPLIANT_POLICY, VDNS_ONSET);
316     }
317
318     // VFW
319
320     /**
321      * VFW Sunny Day with Legacy Tosca Policy.
322      */
323     @Test
324     public void testVfwSunnyDayLegacy() {
325         appcLegacySunnyDay(VFW_TOSCA_LEGACY_POLICY, VFW_ONSET, APPC_MODIFY_CONFIG_OP);
326     }
327
328     /**
329      * VFW Sunny Day with Tosca Compliant Policy.
330      */
331     @Test
332     public void testVfwSunnyDayCompliant() {
333         appcLegacySunnyDay(VFW_TOSCA_COMPLIANT_POLICY, VFW_ONSET, APPC_MODIFY_CONFIG_OP);
334     }
335
336     /**
337      * VFW Rainy Day using legacy tosca policy (operation and final failure).
338      */
339     @Test
340     public void testVfwRainyDayLegacyFailure() {
341         appcLegacyRainyDay(VFW_TOSCA_LEGACY_POLICY, VFW_ONSET, APPC_MODIFY_CONFIG_OP);
342     }
343
344     /**
345      * VFW Rainy Day using compliant tosca policy (final failure).
346      */
347     @Test
348     public void testVfwRainyDayOverallTimeout() {
349         appcLegacyRainyDayNoResponse(VFW_TOSCA_COMPLIANT_TIME_OUT_POLICY, VFW_ONSET, APPC_MODIFY_CONFIG_OP);
350     }
351
352     /**
353      * VFW Rainy day using compliant tosca policy (final failure due to timeout).
354      */
355     @Test
356     public void testVfwRainyDayCompliantTimeout() {
357         appcLegacyRainyDayNoResponse(VFW_TOSCA_COMPLIANT_POLICY, VFW_ONSET, APPC_MODIFY_CONFIG_OP);
358     }
359
360     /**
361      * Sunny day scenario for use cases that use APPC-LCM.
362      *
363      * @param policyFile file containing the ToscaPolicy to be loaded
364      * @param onsetFile file containing the ONSET to be injected
365      * @param operation expected APPC operation request
366      */
367     protected void appcLcmSunnyDay(String policyFile, String onsetFile, String operation) {
368         appcLcmSunnyDay(policyFile, List.of(onsetFile), operation);
369     }
370
371     /**
372      * Sunny day scenario for use cases that use APPC-LCM.
373      *
374      * @param policyFile file containing the ToscaPolicy to be loaded
375      * @param onsetFiles list of files containing the ONSET to be injected
376      * @param operation expected APPC operation request
377      */
378     protected void appcLcmSunnyDay(String policyFile, List<String> onsetFiles, String operation) {
379         policyClMgt = topics.createListener(POLICY_CL_MGT_TOPIC, VirtualControlLoopNotification.class, controller);
380         appcLcmRead = topics.createListener(APPC_LCM_READ_TOPIC, AppcLcmDmaapWrapper.class, APPC_LCM_CODER);
381
382         assertEquals(0, controller.getDrools().factCount(rules.getControllerName()));
383         policy = rules.setupPolicyFromFile(policyFile);
384         assertEquals(2, controller.getDrools().factCount(rules.getControllerName()));
385
386         // inject several ONSET events over the DCAE topic
387         for (String onsetFile : onsetFiles) {
388             topics.inject(DCAE_TOPIC, onsetFile);
389         }
390
391         /* Wait to acquire a LOCK and a PDP-X PERMIT */
392         waitForLockAndPermit(policy, policyClMgt);
393
394         /*
395          * Ensure that an APPC RESTART request was sent in response to the matching ONSET
396          */
397         AppcLcmDmaapWrapper appcreq = appcLcmRead.await(req -> operation.equals(req.getRpcName()));
398
399         /*
400          * Inject a 400 APPC Response Return over the APPC topic, with appropriate
401          * subRequestId
402          */
403         topics.inject(APPC_LCM_WRITE_TOPIC, VCPE_APPC_SUCCESS,
404                         appcreq.getBody().getInput().getCommonHeader().getSubRequestId());
405
406         /* --- Operation Completed --- */
407
408         waitForOperationSuccess();
409
410         /* --- Transaction Completed --- */
411         waitForFinalSuccess(policy, policyClMgt);
412     }
413
414     /**
415      * Sunny day scenario for use cases that use Legacy APPC.
416      *
417      * @param policyFile file containing the ToscaPolicy to be loaded
418      * @param onsetFile file containing the ONSET to be injected
419      * @param operation expected APPC operation request
420      */
421     protected void appcLegacySunnyDay(String policyFile, String onsetFile, String operation) {
422         policyClMgt = topics.createListener(POLICY_CL_MGT_TOPIC, VirtualControlLoopNotification.class, controller);
423         appcClSink = topics.createListener(APPC_CL_TOPIC, Request.class, APPC_LEGACY_CODER);
424
425         assertEquals(0, controller.getDrools().factCount(rules.getControllerName()));
426         policy = rules.setupPolicyFromFile(policyFile);
427         assertEquals(2, controller.getDrools().factCount(rules.getControllerName()));
428
429         /* Inject an ONSET event over the DCAE topic */
430         topics.inject(DCAE_TOPIC, onsetFile);
431
432         /* Wait to acquire a LOCK and a PDP-X PERMIT */
433         waitForLockAndPermit(policy, policyClMgt);
434
435         /*
436          * Ensure that an APPC RESTART request was sent in response to the matching ONSET
437          */
438         Request appcreq = appcClSink.await(req -> operation.equals(req.getAction()));
439
440         /*
441          * Inject a 400 APPC Response Return over the APPC topic, with appropriate
442          * subRequestId
443          */
444         topics.inject(APPC_CL_TOPIC, VFW_APPC_SUCCESS, appcreq.getCommonHeader().getSubRequestId());
445
446         /* --- Operation Completed --- */
447
448         waitForOperationSuccess();
449
450         /* --- Transaction Completed --- */
451         waitForFinalSuccess(policy, policyClMgt);
452     }
453
454     /**
455      * Rainy 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      * @param checkOperation flag to determine whether or not to wait for operation timeout
461      */
462     protected void appcLegacyRainyDay(String policyFile, String onsetFile, String operation) {
463         policyClMgt = topics.createListener(POLICY_CL_MGT_TOPIC, VirtualControlLoopNotification.class, controller);
464         appcClSink = topics.createListener(APPC_CL_TOPIC, Request.class, APPC_LEGACY_CODER);
465
466         assertEquals(0, controller.getDrools().factCount(rules.getControllerName()));
467         policy = rules.setupPolicyFromFile(policyFile);
468         assertEquals(2, controller.getDrools().factCount(rules.getControllerName()));
469
470         /* Inject an ONSET event over the DCAE topic */
471         topics.inject(DCAE_TOPIC, onsetFile);
472
473         /* Wait to acquire a LOCK and a PDP-X PERMIT */
474         waitForLockAndPermit(policy, policyClMgt);
475
476         /*
477          * Ensure that an APPC RESTART request was sent in response to the matching ONSET
478          */
479         Request appcreq = appcClSink.await(req -> operation.equals(req.getAction()));
480
481         /*
482          * Inject a 401 APPC Response Return over the APPC topic, with appropriate
483          * subRequestId
484          */
485         topics.inject(APPC_CL_TOPIC, VFW_APPC_FAILURE, appcreq.getCommonHeader().getSubRequestId());
486
487         /* --- Operation Completed --- */
488         waitForOperationFailure();
489
490         /* --- Transaction Completed --- */
491         waitForFinalFailure(policy, policyClMgt);
492     }
493
494     /**
495      * Rainy day scenario for use cases that use Legacy APPC.
496      * Expected to fail due to timeout.
497      *
498      * @param policyFile file containing the ToscaPolicy to be loaded
499      * @param onsetFile file containing the ONSET to be injected
500      * @param operation expected APPC operation request
501      */
502     protected void appcLegacyRainyDayNoResponse(String policyFile, String onsetFile, String operation) {
503         policyClMgt = topics.createListener(POLICY_CL_MGT_TOPIC, VirtualControlLoopNotification.class, controller);
504         appcClSink = topics.createListener(APPC_CL_TOPIC, Request.class, APPC_LEGACY_CODER);
505
506         assertEquals(0, controller.getDrools().factCount(rules.getControllerName()));
507         policy = rules.setupPolicyFromFile(policyFile);
508         assertEquals(2, controller.getDrools().factCount(rules.getControllerName()));
509
510         /* Inject an ONSET event over the DCAE topic */
511         topics.inject(DCAE_TOPIC, onsetFile);
512
513         /* Wait to acquire a LOCK and a PDP-X PERMIT */
514         waitForLockAndPermit(policy, policyClMgt);
515
516         /*
517          * Ensure that an APPC RESTART request was sent in response to the matching ONSET
518          */
519         appcClSink.await(req -> operation.equals(req.getAction()));
520
521         /*
522          * Do not inject an APPC Response.
523          */
524
525         /* --- Transaction Completed --- */
526         waitForFinalFailure(policy, policyClMgt);
527     }
528
529     /**
530      * Sunny day scenario for use cases that use an HTTP simulator.
531      *
532      * @param policyFile file containing the ToscaPolicy to be loaded
533      * @param onsetFile file containing the ONSET to be injected
534      * @param operation expected APPC operation request
535      */
536     protected void httpSunnyDay(String policyFile, String onsetFile) {
537         policyClMgt = topics.createListener(POLICY_CL_MGT_TOPIC, VirtualControlLoopNotification.class, controller);
538
539         assertEquals(0, controller.getDrools().factCount(rules.getControllerName()));
540         policy = rules.setupPolicyFromFile(policyFile);
541         assertEquals(2, controller.getDrools().factCount(rules.getControllerName()));
542
543         /* Inject an ONSET event over the DCAE topic */
544         topics.inject(DCAE_TOPIC, onsetFile);
545
546         /* Wait to acquire a LOCK and a PDP-X PERMIT */
547         waitForLockAndPermit(policy, policyClMgt);
548
549         /* --- Operation Completed --- */
550
551         waitForOperationSuccess();
552
553         /* --- Transaction Completed --- */
554         waitForFinalSuccess(policy, policyClMgt);
555     }
556
557     /**
558      * Waits for a OPERATION SUCCESS transaction notification.
559      */
560     protected void waitForOperationSuccess() {
561         policyClMgt.await(notif -> notif.getNotification() == ControlLoopNotificationType.OPERATION_SUCCESS);
562     }
563
564     /**
565      * Waits for a FINAL SUCCESS transaction notification.
566      *
567      * @return the FINAL SUCCESS notification
568      */
569     protected VirtualControlLoopNotification waitForFinalSuccess(ToscaPolicy policy,
570                     Listener<VirtualControlLoopNotification> policyClMgt) {
571
572         return this.waitForFinal(policy, policyClMgt, ControlLoopNotificationType.FINAL_SUCCESS);
573     }
574
575     /**
576      * Waits for a OPERATION FAILURE transaction notification.
577      */
578     protected void waitForOperationFailure() {
579         policyClMgt.await(notif -> notif.getNotification() == ControlLoopNotificationType.OPERATION_FAILURE);
580     }
581
582     /**
583      * Waits for a FINAL FAILURE transaction notification.
584      *
585      * @return the FINAL FAILURE notification
586      */
587     protected VirtualControlLoopNotification waitForFinalFailure(ToscaPolicy policy,
588                     Listener<VirtualControlLoopNotification> policyClMgt) {
589
590         return this.waitForFinal(policy, policyClMgt, ControlLoopNotificationType.FINAL_FAILURE);
591     }
592
593     /**
594      * Waits for notifications for LOCK acquisition and GUARD Permit so that event
595      * processing may proceed.
596      */
597     protected abstract void waitForLockAndPermit(ToscaPolicy policy,
598                     Listener<VirtualControlLoopNotification> policyClMgt);
599
600     /**
601      * Waits for a FINAL transaction notification.
602      *
603      * @param finalType FINAL_xxx type for which to wait
604      *
605      * @return the FINAL notification
606      */
607     protected abstract VirtualControlLoopNotification waitForFinal(ToscaPolicy policy,
608                     Listener<VirtualControlLoopNotification> policyClMgt, ControlLoopNotificationType finalType);
609 }