2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2018-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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.policy.drools.system.internal;
23 import static org.assertj.core.api.Assertions.assertThatCode;
24 import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
25 import static org.assertj.core.api.Assertions.assertThatThrownBy;
26 import static org.junit.Assert.assertEquals;
27 import static org.junit.Assert.assertFalse;
28 import static org.junit.Assert.assertNotNull;
29 import static org.junit.Assert.assertTrue;
30 import static org.mockito.ArgumentMatchers.any;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.never;
33 import static org.mockito.Mockito.times;
34 import static org.mockito.Mockito.verify;
35 import static org.mockito.Mockito.when;
37 import java.util.Arrays;
38 import java.util.List;
39 import java.util.Properties;
40 import java.util.function.BiConsumer;
41 import java.util.function.Consumer;
42 import org.junit.Before;
43 import org.junit.Test;
44 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
45 import org.onap.policy.common.endpoints.event.comm.TopicEndpoint;
46 import org.onap.policy.common.endpoints.event.comm.TopicSink;
47 import org.onap.policy.common.endpoints.event.comm.TopicSource;
48 import org.onap.policy.common.utils.gson.GsonTestUtils;
49 import org.onap.policy.drools.controller.DroolsController;
50 import org.onap.policy.drools.controller.DroolsControllerFactory;
51 import org.onap.policy.drools.features.PolicyControllerFeatureApi;
52 import org.onap.policy.drools.persistence.SystemPersistence;
53 import org.onap.policy.drools.protocol.configuration.DroolsConfiguration;
54 import org.onap.policy.drools.system.GsonMgmtTestBuilder;
56 public class AggregatedPolicyControllerTest {
58 private static final String AGG_NAME = "agg-name";
59 private static final String SINK_TOPIC1 = "sink-a";
60 private static final String SINK_TOPIC2 = "sink-b";
61 private static final String SOURCE_TOPIC1 = "source-a";
62 private static final String SOURCE_TOPIC2 = "source-b";
64 private static final String EXPECTED = "expected exception";
66 private static final String MY_EVENT = "my-event";
68 private static final String ARTIFACT1 = "artifact-a";
69 private static final String GROUP1 = "group-a";
70 private static final String VERSION1 = "version-a";
72 private static final String ARTIFACT2 = "artifact-b";
73 private static final String GROUP2 = "group-b";
74 private static final String VERSION2 = "version-b";
76 private Properties properties;
77 private TopicEndpoint endpointMgr;
78 private List<TopicSource> sources;
79 private TopicSource source1;
80 private TopicSource source2;
81 private List<TopicSink> sinks;
82 private TopicSink sink1;
83 private TopicSink sink2;
84 private SystemPersistence persist;
85 private DroolsControllerFactory droolsFactory;
86 private DroolsController drools;
87 private DroolsConfiguration config;
88 private List<PolicyControllerFeatureApi> providers;
89 private PolicyControllerFeatureApi prov1;
90 private PolicyControllerFeatureApi prov2;
91 private AggregatedPolicyController apc;
94 * Initializes the object to be tested.
98 properties = new Properties();
100 source1 = mock(TopicSource.class);
101 source2 = mock(TopicSource.class);
102 when(source1.getTopic()).thenReturn(SOURCE_TOPIC1);
103 when(source2.getTopic()).thenReturn(SOURCE_TOPIC2);
105 sink1 = mock(TopicSink.class);
106 sink2 = mock(TopicSink.class);
107 when(sink1.getTopic()).thenReturn(SINK_TOPIC1);
108 when(sink2.getTopic()).thenReturn(SINK_TOPIC2);
110 sources = Arrays.asList(source1, source2);
111 sinks = Arrays.asList(sink1, sink2);
113 endpointMgr = mock(TopicEndpoint.class);
114 when(endpointMgr.addTopicSources(any(Properties.class))).thenReturn(sources);
115 when(endpointMgr.addTopicSinks(any(Properties.class))).thenReturn(sinks);
117 persist = mock(SystemPersistence.class);
119 drools = mock(DroolsController.class);
120 when(drools.start()).thenReturn(true);
121 when(drools.stop()).thenReturn(true);
122 when(drools.offer(any(), any())).thenReturn(true);
123 when(drools.deliver(any(), any())).thenReturn(true);
124 when(drools.lock()).thenReturn(true);
125 when(drools.unlock()).thenReturn(true);
126 when(drools.getArtifactId()).thenReturn(ARTIFACT1);
127 when(drools.getGroupId()).thenReturn(GROUP1);
128 when(drools.getVersion()).thenReturn(VERSION1);
130 config = mock(DroolsConfiguration.class);
131 when(config.getArtifactId()).thenReturn(ARTIFACT2);
132 when(config.getGroupId()).thenReturn(GROUP2);
133 when(config.getVersion()).thenReturn(VERSION2);
135 droolsFactory = mock(DroolsControllerFactory.class);
136 when(droolsFactory.build(any(), any(), any())).thenReturn(drools);
138 prov1 = mock(PolicyControllerFeatureApi.class);
139 prov2 = mock(PolicyControllerFeatureApi.class);
141 providers = Arrays.asList(prov1, prov2);
143 apc = new AggregatedPolicyControllerImpl(AGG_NAME, properties);
147 public void testFactory() {
148 apc = new AggregatedPolicyController(AGG_NAME, properties);
149 assertNotNull(apc.getDroolsFactory());
150 assertNotNull(apc.getEndpointManager());
151 assertNotNull(apc.getProviders());
152 assertNotNull(apc.getPersistenceManager());
156 public void testAggregatedPolicyController_() {
157 verify(persist).storeController(AGG_NAME, properties);
160 @Test(expected = IllegalArgumentException.class)
161 public void testInitDrools_Ex() {
162 new AggregatedPolicyControllerImpl(AGG_NAME, properties) {
164 protected DroolsControllerFactory getDroolsFactory() {
165 throw new RuntimeException(EXPECTED);
170 @Test(expected = IllegalArgumentException.class)
171 public void testInitDrools_Error() {
172 new AggregatedPolicyControllerImpl(AGG_NAME, properties) {
174 protected DroolsControllerFactory getDroolsFactory() {
175 throw new LinkageError(EXPECTED);
181 public void testUpdateDrools_ConfigVariations() {
183 // config should return same values as current controller
184 when(config.getArtifactId()).thenReturn(ARTIFACT1.toUpperCase());
185 when(config.getGroupId()).thenReturn(GROUP1.toUpperCase());
186 when(config.getVersion()).thenReturn(VERSION1.toUpperCase());
188 assertTrue(apc.updateDrools(config));
190 // number of times store should have been called
193 // invoked once during construction, but shouldn't be invoked during update
194 verify(persist, times(++count)).storeController(any(), any());
197 // different artifact
198 when(config.getArtifactId()).thenReturn(ARTIFACT2);
200 assertTrue(apc.updateDrools(config));
202 // should be invoked during update
203 verify(persist, times(++count)).storeController(any(), any());
207 when(config.getArtifactId()).thenReturn(ARTIFACT1);
208 when(config.getGroupId()).thenReturn(GROUP2);
210 assertTrue(apc.updateDrools(config));
212 // should be invoked during update
213 verify(persist, times(++count)).storeController(any(), any());
217 when(config.getGroupId()).thenReturn(GROUP1);
218 when(config.getVersion()).thenReturn(VERSION2);
220 assertTrue(apc.updateDrools(config));
222 // should be invoked during update
223 verify(persist, times(++count)).storeController(any(), any());
229 when(drools.lock()).thenThrow(new IllegalArgumentException(EXPECTED));
230 when(drools.unlock()).thenThrow(new IllegalArgumentException(EXPECTED));
232 assertFalse(apc.updateDrools(config));
236 public void testUpdateDrools_LockVariations() {
238 apc.updateDrools(config);
239 verify(drools, never()).lock();
240 verify(drools).unlock();
245 apc.updateDrools(config);
246 verify(drools, times(2)).lock();
247 verify(drools, never()).unlock();
251 public void testUpdateDrools_AliveVariations() {
253 apc.updateDrools(config);
254 verify(drools, never()).start();
255 verify(drools).stop();
260 apc.updateDrools(config);
261 verify(drools, times(2)).start();
262 verify(drools, never()).stop();
266 public void testSerialize() {
267 GsonTestUtils gson = new GsonMgmtTestBuilder().addDroolsControllerMock().addTopicSinkMock().addTopicSourceMock()
269 assertThatCode(() -> gson.compareGson(apc, AggregatedPolicyControllerTest.class)).doesNotThrowAnyException();
273 public void testGetName() {
274 assertEquals(AGG_NAME, apc.getName());
278 public void testStart() {
279 // arrange for first provider to throw exceptions
280 when(prov1.beforeStart(any())).thenThrow(new RuntimeException(EXPECTED));
281 when(prov1.afterStart(any())).thenThrow(new RuntimeException(EXPECTED));
283 // arrange for first sink to throw exception
284 when(sink1.start()).thenThrow(new RuntimeException(EXPECTED));
287 assertTrue(apc.start());
289 assertTrue(apc.isAlive());
291 verify(prov1).beforeStart(apc);
292 verify(prov2).beforeStart(apc);
294 verify(source1).register(apc);
295 verify(source2).register(apc);
297 verify(sink1).start();
298 verify(sink2).start();
300 verify(prov1).afterStart(apc);
301 verify(prov2).afterStart(apc);
304 (prov, flag) -> when(prov.beforeStart(apc)).thenReturn(flag),
305 (prov, flag) -> when(prov.afterStart(apc)).thenReturn(flag),
307 prov -> verify(prov).beforeStart(apc),
308 () -> verify(source1).register(apc),
309 prov -> verify(prov).afterStart(apc));
313 public void testStart_AlreadyStarted() {
317 assertTrue(apc.start());
319 assertTrue(apc.isAlive());
321 // these should now have been called twice
322 verify(prov1, times(2)).beforeStart(apc);
323 verify(prov2, times(2)).beforeStart(apc);
325 // these should still only have been called once
326 verify(source1).register(apc);
327 verify(sink1).start();
328 verify(prov1).afterStart(apc);
332 public void testStart_Locked() {
336 assertThatIllegalStateException().isThrownBy(() -> apc.start());
338 assertFalse(apc.isAlive());
340 // should call beforeStart(), but stop after that
341 verify(prov1).beforeStart(apc);
342 verify(prov2).beforeStart(apc);
344 verify(source1, never()).register(apc);
345 verify(sink1, never()).start();
346 verify(prov1, never()).afterStart(apc);
350 public void testStop() {
351 // arrange for first provider to throw exceptions
352 when(prov1.beforeStop(any())).thenThrow(new RuntimeException(EXPECTED));
353 when(prov1.afterStop(any())).thenThrow(new RuntimeException(EXPECTED));
359 assertTrue(apc.stop());
361 assertFalse(apc.isAlive());
363 verify(prov1).beforeStop(apc);
364 verify(prov2).beforeStop(apc);
366 verify(source1).unregister(apc);
367 verify(source2).unregister(apc);
369 verify(prov1).afterStop(apc);
370 verify(prov2).afterStop(apc);
372 // ensure no shutdown operations were called
373 verify(prov1, never()).beforeShutdown(apc);
374 verify(droolsFactory, never()).shutdown(drools);
375 verify(prov2, never()).afterShutdown(apc);
378 (prov, flag) -> when(prov.beforeStop(apc)).thenReturn(flag),
379 (prov, flag) -> when(prov.afterStop(apc)).thenReturn(flag),
384 prov -> verify(prov).beforeStop(apc),
385 () -> verify(source1).unregister(apc),
386 prov -> verify(prov).afterStop(apc));
390 public void testStop_AlreadyStopped() {
395 assertTrue(apc.stop());
398 verify(prov1, times(2)).beforeStop(apc);
399 verify(prov2, times(2)).beforeStop(apc);
401 // should NOT be called again
402 verify(source1).unregister(apc);
403 verify(prov1).afterStop(apc);
407 public void testShutdown() {
408 // arrange for first provider to throw exceptions
409 when(prov1.beforeShutdown(any())).thenThrow(new RuntimeException(EXPECTED));
410 when(prov1.afterShutdown(any())).thenThrow(new RuntimeException(EXPECTED));
418 verify(prov1).beforeShutdown(apc);
419 verify(prov2).beforeShutdown(apc);
421 assertFalse(apc.isAlive());
423 verify(prov1).afterStop(apc);
424 verify(prov2).afterStop(apc);
426 verify(droolsFactory).shutdown(drools);
428 verify(prov1).afterShutdown(apc);
429 verify(prov2).afterShutdown(apc);
431 // ensure no halt operation was called
432 verify(prov1, never()).beforeHalt(apc);
435 (prov, flag) -> when(prov.beforeShutdown(apc)).thenReturn(flag),
436 (prov, flag) -> when(prov.afterShutdown(apc)).thenReturn(flag),
441 prov -> verify(prov).beforeShutdown(apc),
442 () -> verify(source1).unregister(apc),
443 prov -> verify(prov).afterShutdown(apc));
447 public void testHalt() {
448 // arrange for first provider to throw exceptions
449 when(prov1.beforeHalt(any())).thenThrow(new RuntimeException(EXPECTED));
450 when(prov1.afterHalt(any())).thenThrow(new RuntimeException(EXPECTED));
458 verify(prov1).beforeHalt(apc);
459 verify(prov2).beforeHalt(apc);
461 assertFalse(apc.isAlive());
463 verify(prov1).beforeStop(apc);
464 verify(prov2).beforeStop(apc);
466 verify(droolsFactory).destroy(drools);
467 verify(persist).deleteController(AGG_NAME);
469 verify(prov1).afterHalt(apc);
470 verify(prov2).afterHalt(apc);
472 // ensure no shutdown operation was called
473 verify(prov1, never()).beforeShutdown(apc);
476 (prov, flag) -> when(prov.beforeHalt(apc)).thenReturn(flag),
477 (prov, flag) -> when(prov.afterHalt(apc)).thenReturn(flag),
482 prov -> verify(prov).beforeHalt(apc),
483 () -> verify(source1).unregister(apc),
484 prov -> verify(prov).afterHalt(apc));
488 public void testOnTopicEvent() {
489 // arrange for first provider to throw exceptions
490 when(prov1.beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT))
491 .thenThrow(new RuntimeException(EXPECTED));
492 when(prov1.afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true))
493 .thenThrow(new RuntimeException(EXPECTED));
499 apc.onTopicEvent(CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
501 verify(prov1).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
502 verify(prov2).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
504 verify(drools).offer(SOURCE_TOPIC1, MY_EVENT);
506 verify(prov1).afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true);
507 verify(prov2).afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true);
510 (prov, flag) -> when(prov.beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT))
512 (prov, flag) -> when(
513 prov.afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true))
517 apc.onTopicEvent(CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
519 prov -> verify(prov).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT),
520 () -> verify(drools).offer(SOURCE_TOPIC1, MY_EVENT),
521 prov -> verify(prov).afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true));
525 public void testOnTopicEvent_Locked() {
532 apc.onTopicEvent(CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
534 verify(prov1, never()).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
535 verify(prov2, never()).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
537 // never gets this far
538 verify(drools, never()).offer(SOURCE_TOPIC1, MY_EVENT);
539 verify(prov1, never()).afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true);
543 public void testOnTopicEvent_NotStarted() {
546 apc.onTopicEvent(CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
548 verify(prov1, never()).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
549 verify(prov2, never()).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
551 // never gets this far
552 verify(drools, never()).offer(SOURCE_TOPIC1, MY_EVENT);
553 verify(prov1, never()).afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true);
557 public void testDeliver_testInitSinks() {
558 // arrange for first provider to throw exceptions
559 when(prov1.beforeDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT))
560 .thenThrow(new RuntimeException(EXPECTED));
561 when(prov1.afterDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT, true))
562 .thenThrow(new RuntimeException(EXPECTED));
568 assertTrue(apc.deliver(CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT));
570 verify(prov1).beforeDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT);
571 verify(prov2).beforeDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT);
573 verify(drools).deliver(sink1, MY_EVENT);
574 verify(drools, never()).deliver(sink2, MY_EVENT);
576 verify(prov1).afterDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT, true);
577 verify(prov2).afterDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT, true);
579 // offer to the other topic
580 assertTrue(apc.deliver(CommInfrastructure.NOOP, SINK_TOPIC2, MY_EVENT));
582 // now both topics should show one message delivered
583 verify(drools).deliver(sink1, MY_EVENT);
584 verify(drools).deliver(sink2, MY_EVENT);
587 (prov, flag) -> when(prov.beforeDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT))
589 (prov, flag) -> when(
590 prov.afterDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT, true))
594 apc.deliver(CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT);
596 prov -> verify(prov).beforeDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT),
597 () -> verify(drools).deliver(sink1, MY_EVENT),
598 prov -> verify(prov).afterDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT, true));
601 @Test(expected = IllegalArgumentException.class)
602 public void testDeliver_NullTopic() {
604 apc.deliver(CommInfrastructure.NOOP, null, MY_EVENT);
607 @Test(expected = IllegalArgumentException.class)
608 public void testDeliver_EmptyTopic() {
610 apc.deliver(CommInfrastructure.NOOP, "", MY_EVENT);
613 @Test(expected = IllegalArgumentException.class)
614 public void testDeliver_NullEvent() {
616 apc.deliver(CommInfrastructure.NOOP, SINK_TOPIC1, null);
619 @Test(expected = IllegalStateException.class)
620 public void testDeliver_NotStarted() {
622 apc.deliver(CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT);
625 @Test(expected = IllegalStateException.class)
626 public void testDeliver_Locked() {
629 apc.deliver(CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT);
632 @Test(expected = IllegalArgumentException.class)
633 public void testDeliver_UnknownTopic() {
635 apc.deliver(CommInfrastructure.NOOP, "unknown-topic", MY_EVENT);
639 public void testIsAlive() {
640 assertFalse(apc.isAlive());
643 assertTrue(apc.isAlive());
646 assertFalse(apc.isAlive());
650 public void testLock() {
651 // arrange for first provider to throw exceptions
652 when(prov1.beforeLock(any())).thenThrow(new RuntimeException(EXPECTED));
653 when(prov1.afterLock(any())).thenThrow(new RuntimeException(EXPECTED));
659 assertTrue(apc.lock());
661 verify(prov1).beforeLock(apc);
662 verify(prov2).beforeLock(apc);
664 assertTrue(apc.isLocked());
666 verify(drools).lock();
668 verify(prov1).afterLock(apc);
669 verify(prov2).afterLock(apc);
672 (prov, flag) -> when(prov.beforeLock(apc)).thenReturn(flag),
673 (prov, flag) -> when(prov.afterLock(apc)).thenReturn(flag),
678 prov -> verify(prov).beforeLock(apc),
679 () -> verify(drools).lock(),
680 prov -> verify(prov).afterLock(apc));
684 public void testLock_AlreadyLocked() {
689 assertTrue(apc.lock());
691 // these should be invoked a second time
692 verify(prov1, times(2)).beforeLock(apc);
693 verify(prov2, times(2)).beforeLock(apc);
695 assertTrue(apc.isLocked());
697 // these shouldn't be invoked a second time
698 verify(drools).lock();
699 verify(prov1).afterLock(apc);
703 public void testUnlock() {
704 // arrange for first provider to throw exceptions
705 when(prov1.beforeUnlock(any())).thenThrow(new RuntimeException(EXPECTED));
706 when(prov1.afterUnlock(any())).thenThrow(new RuntimeException(EXPECTED));
713 assertTrue(apc.unlock());
715 verify(prov1).beforeUnlock(apc);
716 verify(prov2).beforeUnlock(apc);
718 assertFalse(apc.isLocked());
720 verify(drools).unlock();
722 verify(prov1).afterUnlock(apc);
723 verify(prov2).afterUnlock(apc);
726 (prov, flag) -> when(prov.beforeUnlock(apc)).thenReturn(flag),
727 (prov, flag) -> when(prov.afterUnlock(apc)).thenReturn(flag),
733 prov -> verify(prov).beforeUnlock(apc),
734 () -> verify(drools).unlock(),
735 prov -> verify(prov).afterUnlock(apc));
739 public void testUnlock_NotLocked() {
743 assertTrue(apc.unlock());
745 verify(prov1).beforeUnlock(apc);
746 verify(prov2).beforeUnlock(apc);
748 assertFalse(apc.isLocked());
750 // these shouldn't be invoked
751 verify(drools, never()).unlock();
752 verify(prov1, never()).afterLock(apc);
756 public void testIsLocked() {
757 assertFalse(apc.isLocked());
760 assertTrue(apc.isLocked());
763 assertFalse(apc.isLocked());
767 public void testGetTopicSources() {
768 assertEquals(sources, apc.getTopicSources());
772 public void testGetTopicSinks() {
773 assertEquals(sinks, apc.getTopicSinks());
777 public void testGetDrools() {
778 assertEquals(drools, apc.getDrools());
782 public void testGetProperties() {
783 assertEquals(properties, apc.getProperties());
787 public void testToString() {
788 assertTrue(apc.toString().startsWith("AggregatedPolicyController ["));
792 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries
793 * combinations where beforeXxx and afterXxx return {@code true} and {@code false}.
795 * @param setBefore function to set the return value of a provider's beforeXxx method
796 * @param setAfter function to set the return value of a provider's afterXxx method
797 * @param action invokes the operation
798 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
799 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
800 * and the afterXxx loop was invoked
801 * @param verifyAfter verifies that a provider's afterXxx method was invoked
803 private void checkBeforeAfter(BiConsumer<PolicyControllerFeatureApi, Boolean> setBefore,
804 BiConsumer<PolicyControllerFeatureApi, Boolean> setAfter, Runnable action,
805 Consumer<PolicyControllerFeatureApi> verifyBefore, Runnable verifyMiddle,
806 Consumer<PolicyControllerFeatureApi> verifyAfter) {
808 checkBeforeAfter_FalseFalse(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
809 checkBeforeAfter_FalseTrue(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
810 checkBeforeAfter_TrueFalse(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
812 // don't need to test true-true, as it's behavior is a subset of true-false
816 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
817 * case where both the beforeXxx and afterXxx methods return {@code false}.
819 * @param setBefore function to set the return value of a provider's beforeXxx method
820 * @param setAfter function to set the return value of a provider's afterXxx method
821 * @param action invokes the operation
822 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
823 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
824 * and the afterXxx loop was invoked
825 * @param verifyAfter verifies that a provider's afterXxx method was invoked
827 private void checkBeforeAfter_FalseFalse(BiConsumer<PolicyControllerFeatureApi, Boolean> setBefore,
828 BiConsumer<PolicyControllerFeatureApi, Boolean> setAfter, Runnable action,
829 Consumer<PolicyControllerFeatureApi> verifyBefore, Runnable verifyMiddle,
830 Consumer<PolicyControllerFeatureApi> verifyAfter) {
834 // configure for the test
835 setBefore.accept(prov1, false);
836 setBefore.accept(prov2, false);
838 setAfter.accept(prov1, false);
839 setAfter.accept(prov2, false);
844 // verify that various methods were invoked
845 verifyBefore.accept(prov1);
846 verifyBefore.accept(prov2);
850 verifyAfter.accept(prov1);
851 verifyAfter.accept(prov2);
855 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
856 * case where the first provider's afterXxx returns {@code true}, while the others
857 * return {@code false}.
859 * @param setBefore function to set the return value of a provider's beforeXxx method
860 * @param setAfter function to set the return value of a provider's afterXxx method
861 * @param action invokes the operation
862 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
863 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
864 * and the afterXxx loop was invoked
865 * @param verifyAfter verifies that a provider's afterXxx method was invoked
867 private void checkBeforeAfter_FalseTrue(BiConsumer<PolicyControllerFeatureApi, Boolean> setBefore,
868 BiConsumer<PolicyControllerFeatureApi, Boolean> setAfter, Runnable action,
869 Consumer<PolicyControllerFeatureApi> verifyBefore, Runnable verifyMiddle,
870 Consumer<PolicyControllerFeatureApi> verifyAfter) {
874 // configure for the test
875 setBefore.accept(prov1, false);
876 setBefore.accept(prov2, false);
878 setAfter.accept(prov1, true);
879 setAfter.accept(prov2, false);
884 // verify that various methods were invoked
885 verifyBefore.accept(prov1);
886 verifyBefore.accept(prov2);
890 verifyAfter.accept(prov1);
891 assertThatThrownBy(() -> verifyAfter.accept(prov2)).isInstanceOf(AssertionError.class);
895 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
896 * case where the first provider's beforeXxx returns {@code true}, while the others
897 * return {@code false}.
899 * @param setBefore function to set the return value of a provider's beforeXxx method
900 * @param setAfter function to set the return value of a provider's afterXxx method
901 * @param action invokes the operation
902 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
903 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
904 * and the afterXxx loop was invoked
905 * @param verifyAfter verifies that a provider's afterXxx method was invoked
907 private void checkBeforeAfter_TrueFalse(BiConsumer<PolicyControllerFeatureApi, Boolean> setBefore,
908 BiConsumer<PolicyControllerFeatureApi, Boolean> setAfter, Runnable action,
909 Consumer<PolicyControllerFeatureApi> verifyBefore, Runnable verifyMiddle,
910 Consumer<PolicyControllerFeatureApi> verifyAfter) {
914 // configure for the test
915 setBefore.accept(prov1, true);
916 setBefore.accept(prov2, false);
918 setAfter.accept(prov1, false);
919 setAfter.accept(prov2, false);
924 // verify that various methods were invoked
925 verifyBefore.accept(prov1);
927 // remaining methods should not have been invoked
928 assertThatThrownBy(() -> verifyBefore.accept(prov2)).isInstanceOf(AssertionError.class);
930 assertThatThrownBy(verifyMiddle::run).isInstanceOf(AssertionError.class);
932 assertThatThrownBy(() -> verifyAfter.accept(prov1)).isInstanceOf(AssertionError.class);
933 assertThatThrownBy(() -> verifyAfter.accept(prov2)).isInstanceOf(AssertionError.class);
937 * Controller with overrides.
939 private class AggregatedPolicyControllerImpl extends AggregatedPolicyController {
941 public AggregatedPolicyControllerImpl(String name, Properties properties) {
942 super(name, properties);
946 protected SystemPersistence getPersistenceManager() {
951 protected TopicEndpoint getEndpointManager() {
956 protected DroolsControllerFactory getDroolsFactory() {
957 return droolsFactory;
961 protected List<PolicyControllerFeatureApi> getProviders() {