2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2018-2019 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;
23 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
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.assertNull;
30 import static org.junit.Assert.assertTrue;
31 import static org.mockito.Matchers.any;
32 import static org.mockito.Matchers.anyLong;
33 import static org.mockito.Mockito.doThrow;
34 import static org.mockito.Mockito.mock;
35 import static org.mockito.Mockito.never;
36 import static org.mockito.Mockito.times;
37 import static org.mockito.Mockito.verify;
38 import static org.mockito.Mockito.when;
40 import java.util.Arrays;
41 import java.util.Collections;
42 import java.util.List;
43 import java.util.Properties;
44 import java.util.function.BiConsumer;
45 import java.util.function.Consumer;
46 import org.junit.Before;
47 import org.junit.Test;
48 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
49 import org.onap.policy.common.endpoints.event.comm.TopicEndpoint;
50 import org.onap.policy.common.endpoints.event.comm.TopicSink;
51 import org.onap.policy.common.endpoints.event.comm.TopicSource;
52 import org.onap.policy.common.endpoints.http.server.HttpServletServer;
53 import org.onap.policy.common.endpoints.http.server.HttpServletServerFactory;
54 import org.onap.policy.common.utils.gson.GsonTestUtils;
55 import org.onap.policy.drools.controller.DroolsController;
56 import org.onap.policy.drools.features.PolicyControllerFeatureAPI;
57 import org.onap.policy.drools.features.PolicyEngineFeatureAPI;
58 import org.onap.policy.drools.persistence.SystemPersistence;
59 import org.onap.policy.drools.properties.DroolsProperties;
60 import org.onap.policy.drools.protocol.coders.EventProtocolCoder;
61 import org.onap.policy.drools.protocol.configuration.ControllerConfiguration;
62 import org.onap.policy.drools.protocol.configuration.DroolsConfiguration;
63 import org.onap.policy.drools.protocol.configuration.PdpdConfiguration;
65 public class PolicyEngineManagerTest {
67 private static final String EXPECTED = "expected exception";
69 private static final String NOOP_STR = CommInfrastructure.NOOP.name();
70 private static final String MY_NAME = "my-name";
71 private static final String CONTROLLER1 = "controller-a";
72 private static final String CONTROLLER2 = "controller-b";
73 private static final String CONTROLLER3 = "controller-c";
74 private static final String CONTROLLER4 = "controller-d";
75 private static final String FEATURE1 = "feature-a";
76 private static final String FEATURE2 = "feature-b";
77 private static final String MY_TOPIC = "my-topic";
78 private static final String MESSAGE = "my-message";
80 private static final Object MY_EVENT = new Object();
82 private static final GsonTestUtils gson = new GsonMgmtTestBuilder().addTopicSourceMock().addTopicSinkMock()
83 .addHttpServletServerMock().build();
85 private Properties properties;
86 private PolicyEngineFeatureAPI prov1;
87 private PolicyEngineFeatureAPI prov2;
88 private List<PolicyEngineFeatureAPI> providers;
89 private PolicyControllerFeatureAPI contProv1;
90 private PolicyControllerFeatureAPI contProv2;
91 private List<PolicyControllerFeatureAPI> contProviders;
92 private String[] globalInitArgs;
93 private TopicSource source1;
94 private TopicSource source2;
95 private List<TopicSource> sources;
96 private TopicSink sink1;
97 private TopicSink sink2;
98 private List<TopicSink> sinks;
99 private HttpServletServer server1;
100 private HttpServletServer server2;
101 private List<HttpServletServer> servers;
102 private HttpServletServerFactory serverFactory;
103 private TopicEndpoint endpoint;
104 private PolicyController controller;
105 private PolicyController controller2;
106 private PolicyController controller3;
107 private PolicyController controller4;
108 private List<PolicyController> controllers;
109 private PolicyControllerFactory controllerFactory;
110 private boolean jmxStarted;
111 private boolean jmxStopped;
112 private long threadSleepMs;
113 private int threadExitCode;
114 private boolean threadStarted;
115 private boolean threadInterrupted;
116 private Thread shutdownThread;
117 private boolean shouldInterrupt;
118 private EventProtocolCoder coder;
119 private SystemPersistence persist;
120 private PolicyEngine engine;
121 private DroolsConfiguration drools3;
122 private DroolsConfiguration drools4;
123 private ControllerConfiguration config3;
124 private ControllerConfiguration config4;
125 private PdpdConfiguration pdpConfig;
126 private String pdpConfigJson;
127 private PolicyEngineManager mgr;
130 * Initializes the object to be tested.
132 * @throws Exception if an error occurs
135 public void setUp() throws Exception {
137 properties = new Properties();
138 prov1 = mock(PolicyEngineFeatureAPI.class);
139 prov2 = mock(PolicyEngineFeatureAPI.class);
140 providers = Arrays.asList(prov1, prov2);
141 contProv1 = mock(PolicyControllerFeatureAPI.class);
142 contProv2 = mock(PolicyControllerFeatureAPI.class);
143 contProviders = Arrays.asList(contProv1, contProv2);
144 globalInitArgs = null;
145 source1 = mock(TopicSource.class);
146 source2 = mock(TopicSource.class);
147 sources = Arrays.asList(source1, source2);
148 sink1 = mock(TopicSink.class);
149 sink2 = mock(TopicSink.class);
150 sinks = Arrays.asList(sink1, sink2);
151 server1 = mock(HttpServletServer.class);
152 server2 = mock(HttpServletServer.class);
153 servers = Arrays.asList(server1, server2);
154 serverFactory = mock(HttpServletServerFactory.class);
155 endpoint = mock(TopicEndpoint.class);
156 controller = mock(PolicyController.class);
157 controller2 = mock(PolicyController.class);
158 controller3 = mock(PolicyController.class);
159 controller4 = mock(PolicyController.class);
160 // do NOT include controller3 or controller4 in the list
161 controllers = Arrays.asList(controller, controller2);
162 controllerFactory = mock(PolicyControllerFactory.class);
167 threadStarted = false;
168 threadInterrupted = false;
169 shutdownThread = null;
170 shouldInterrupt = false;
171 coder = mock(EventProtocolCoder.class);
172 persist = mock(SystemPersistence.class);
173 engine = mock(PolicyEngine.class);
174 drools3 = new DroolsConfiguration();
175 drools4 = new DroolsConfiguration();
176 config3 = new ControllerConfiguration();
177 config4 = new ControllerConfiguration();
178 pdpConfig = new PdpdConfiguration();
180 when(prov1.getName()).thenReturn(FEATURE1);
181 when(prov2.getName()).thenReturn(FEATURE2);
183 when(controllerFactory.build(any(), any())).thenReturn(controller);
184 when(controllerFactory.inventory()).thenReturn(controllers);
185 when(controllerFactory.get(CONTROLLER1)).thenReturn(controller);
186 when(controllerFactory.get(CONTROLLER2)).thenReturn(controller2);
187 // do NOT return controller3 or controller4
189 when(server1.getPort()).thenReturn(1001);
190 when(server1.waitedStart(anyLong())).thenReturn(true);
191 when(server1.stop()).thenReturn(true);
193 when(server2.getPort()).thenReturn(1002);
194 when(server2.waitedStart(anyLong())).thenReturn(true);
195 when(server2.stop()).thenReturn(true);
197 when(serverFactory.build(any())).thenReturn(servers);
199 when(source1.getTopic()).thenReturn("source1-topic");
200 when(source1.start()).thenReturn(true);
201 when(source1.stop()).thenReturn(true);
203 when(source2.getTopic()).thenReturn("source2-topic");
204 when(source2.start()).thenReturn(true);
205 when(source2.stop()).thenReturn(true);
207 when(sink1.getTopic()).thenReturn("sink1-topic");
208 when(sink1.start()).thenReturn(true);
209 when(sink1.stop()).thenReturn(true);
210 when(sink1.send(any())).thenReturn(true);
211 when(sink1.getTopicCommInfrastructure()).thenReturn(CommInfrastructure.NOOP);
213 when(sink2.getTopic()).thenReturn("sink2-topic");
214 when(sink2.start()).thenReturn(true);
215 when(sink2.stop()).thenReturn(true);
217 when(controller.getName()).thenReturn(CONTROLLER1);
218 when(controller.start()).thenReturn(true);
219 when(controller.stop()).thenReturn(true);
220 when(controller.lock()).thenReturn(true);
221 when(controller.unlock()).thenReturn(true);
223 when(controller2.getName()).thenReturn(CONTROLLER2);
224 when(controller2.start()).thenReturn(true);
225 when(controller2.stop()).thenReturn(true);
226 when(controller2.lock()).thenReturn(true);
227 when(controller2.unlock()).thenReturn(true);
229 when(controller3.getName()).thenReturn(CONTROLLER3);
230 when(controller3.start()).thenReturn(true);
231 when(controller3.stop()).thenReturn(true);
232 when(controller3.lock()).thenReturn(true);
233 when(controller3.unlock()).thenReturn(true);
235 when(controller4.getName()).thenReturn(CONTROLLER4);
236 when(controller4.start()).thenReturn(true);
237 when(controller4.stop()).thenReturn(true);
238 when(controller4.lock()).thenReturn(true);
239 when(controller4.unlock()).thenReturn(true);
241 when(endpoint.addTopicSources(any())).thenReturn(sources);
242 when(endpoint.addTopicSinks(any())).thenReturn(sinks);
243 when(endpoint.start()).thenReturn(true);
244 when(endpoint.stop()).thenReturn(true);
245 when(endpoint.lock()).thenReturn(true);
246 when(endpoint.unlock()).thenReturn(true);
247 when(endpoint.getTopicSink(CommInfrastructure.NOOP, MY_TOPIC)).thenReturn(sink1);
248 when(endpoint.getTopicSinks(MY_TOPIC)).thenReturn(Arrays.asList(sink1));
250 when(coder.encode(any(), any())).thenReturn(MESSAGE);
252 when(persist.getControllerProperties(CONTROLLER3)).thenReturn(properties);
253 when(persist.getControllerProperties(CONTROLLER4)).thenReturn(properties);
255 when(engine.createPolicyController(CONTROLLER3, properties)).thenReturn(controller3);
256 when(engine.createPolicyController(CONTROLLER4, properties)).thenReturn(controller4);
258 config3.setName(CONTROLLER3);
259 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_CREATE);
260 config3.setDrools(drools3);
262 config4.setName(CONTROLLER4);
263 config4.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_UPDATE);
264 config4.setDrools(drools4);
266 pdpConfig.getControllers().add(config3);
267 pdpConfig.getControllers().add(config4);
268 pdpConfig.setEntity(PdpdConfiguration.CONFIG_ENTITY_CONTROLLER);
270 pdpConfigJson = gson.gsonEncode(pdpConfig);
272 mgr = new PolicyEngineManagerImpl();
276 public void testSerialize() {
277 mgr.configure(properties);
278 gson.compareGson(mgr, PolicyEngineManagerTest.class);
282 public void testFactory() {
283 mgr = new PolicyEngineManager();
285 assertNotNull(mgr.getEngineProviders());
286 assertNotNull(mgr.getControllerProviders());
287 assertNotNull(mgr.getTopicEndpointManager());
288 assertNotNull(mgr.getServletFactory());
289 assertNotNull(mgr.getControllerFactory());
290 assertNotNull(mgr.makeShutdownThread());
291 assertNotNull(mgr.getProtocolCoder());
292 assertNotNull(mgr.getPersistenceManager());
293 assertNotNull(mgr.getPolicyEngine());
297 public void testBoot() throws Exception {
298 String[] args = {"boot-a", "boot-b"};
300 // arrange for first provider to throw exceptions
301 when(prov1.beforeBoot(mgr, args)).thenThrow(new RuntimeException(EXPECTED));
302 when(prov1.afterBoot(mgr)).thenThrow(new RuntimeException(EXPECTED));
306 verify(prov1).beforeBoot(mgr, args);
307 verify(prov2).beforeBoot(mgr, args);
309 assertTrue(globalInitArgs == args);
311 verify(prov1).afterBoot(mgr);
312 verify(prov2).afterBoot(mgr);
314 // global init throws exception - still calls afterBoot
316 mgr = new PolicyEngineManagerImpl() {
318 protected void globalInitContainer(String[] cliArgs) {
319 throw new RuntimeException(EXPECTED);
323 verify(prov2).afterBoot(mgr);
327 (prov, flag) -> when(prov.beforeBoot(mgr, args)).thenReturn(flag),
328 (prov, flag) -> when(prov.afterBoot(mgr)).thenReturn(flag),
329 () -> mgr.boot(args),
330 prov -> verify(prov).beforeBoot(mgr, args),
331 () -> assertTrue(globalInitArgs == args),
332 prov -> verify(prov).afterBoot(mgr));
336 public void testSetEnvironment_testGetEnvironment_testGetEnvironmentProperty_setEnvironmentProperty() {
337 Properties props1 = new Properties();
338 props1.put("prop1-a", "value1-a");
339 props1.put("prop1-b", "value1-b");
341 mgr.setEnvironment(props1);
343 Properties env = mgr.getEnvironment();
344 assertEquals(props1, env);
346 // add more properties
347 Properties props2 = new Properties();
348 String propKey = "prop2-a";
349 props2.put(propKey, "value2-a");
350 props2.put("prop2-b", "value2-b");
352 mgr.setEnvironment(props2);
354 assertTrue(mgr.getEnvironment() == env);
356 // new env should have a union of the properties
357 props1.putAll(props2);
358 assertEquals(props1, env);
360 assertEquals("value2-a", mgr.getEnvironmentProperty(propKey));
362 String newValue = "new-value";
363 mgr.setEnvironmentProperty(propKey, newValue);
364 assertEquals(newValue, mgr.getEnvironmentProperty(propKey));
366 props1.setProperty(propKey, newValue);
367 assertEquals(props1, env);
369 assertNotNull(mgr.getEnvironmentProperty("PATH"));
370 assertNull(mgr.getEnvironmentProperty("unknown-env-property"));
372 System.setProperty("propS-a", "valueS-a");
373 assertEquals("valueS-a", mgr.getEnvironmentProperty("propS-a"));
375 Properties props3 = new Properties();
376 props3.put("prop3-a", "${env:HOME}");
377 mgr.setEnvironment(props3);
378 assertEquals(System.getenv("HOME"), mgr.getEnvironmentProperty("prop3-a"));
379 assertEquals("valueS-a", mgr.getEnvironmentProperty("propS-a"));
380 assertEquals(newValue, mgr.getEnvironmentProperty(propKey));
384 public void testDefaultTelemetryConfig() {
385 Properties config = mgr.defaultTelemetryConfig();
386 assertNotNull(config);
387 assertFalse(config.isEmpty());
391 public void testConfigureProperties() throws Exception {
392 // arrange for first provider to throw exceptions
393 when(prov1.beforeConfigure(mgr, properties)).thenThrow(new RuntimeException(EXPECTED));
394 when(prov1.afterConfigure(mgr)).thenThrow(new RuntimeException(EXPECTED));
396 mgr.configure(properties);
398 verify(prov1).beforeConfigure(mgr, properties);
399 verify(prov2).beforeConfigure(mgr, properties);
401 assertTrue(mgr.getProperties() == properties);
403 assertEquals(sources, mgr.getSources());
404 assertEquals(sinks, mgr.getSinks());
405 assertEquals(servers, mgr.getHttpServers());
407 verify(source1).register(mgr);
408 verify(source2).register(mgr);
410 verify(prov1).afterConfigure(mgr);
411 verify(prov2).afterConfigure(mgr);
413 // middle stuff throws exception - still calls afterXxx
415 when(endpoint.addTopicSources(properties)).thenThrow(new IllegalArgumentException(EXPECTED));
416 when(endpoint.addTopicSinks(properties)).thenThrow(new IllegalArgumentException(EXPECTED));
417 when(serverFactory.build(properties)).thenThrow(new IllegalArgumentException(EXPECTED));
418 mgr.configure(properties);
419 verify(prov2).afterConfigure(mgr);
421 // null properties - nothing should be invoked
423 Properties nullProps = null;
424 assertThatIllegalArgumentException().isThrownBy(() -> mgr.configure(nullProps));
425 verify(prov1, never()).beforeConfigure(mgr, properties);
426 verify(prov1, never()).afterConfigure(mgr);
430 (prov, flag) -> when(prov.beforeConfigure(mgr, properties)).thenReturn(flag),
431 (prov, flag) -> when(prov.afterConfigure(mgr)).thenReturn(flag),
432 () -> mgr.configure(properties),
433 prov -> verify(prov).beforeConfigure(mgr, properties),
434 () -> assertTrue(mgr.getProperties() == properties),
435 prov -> verify(prov).afterConfigure(mgr));
439 public void testConfigurePdpdConfiguration() throws Exception {
440 mgr.configure(properties);
441 assertTrue(mgr.configure(pdpConfig));
443 verify(controllerFactory).patch(controller3, drools3);
444 verify(controllerFactory).patch(controller4, drools4);
447 PdpdConfiguration nullConfig = null;
448 assertThatIllegalArgumentException().isThrownBy(() -> mgr.configure(nullConfig));
450 pdpConfig.setEntity("unknown-entity");
451 assertThatIllegalArgumentException().isThrownBy(() -> mgr.configure(pdpConfig));
453 // source list of size 1
455 when(endpoint.addTopicSources(any())).thenReturn(Arrays.asList(source1));
456 mgr.configure(properties);
457 assertTrue(mgr.configure(pdpConfig));
459 verify(controllerFactory).patch(controller3, drools3);
460 verify(controllerFactory).patch(controller4, drools4);
464 public void testCreatePolicyController() throws Exception {
465 assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
467 verify(contProv1).beforeCreate(MY_NAME, properties);
468 verify(contProv2).beforeCreate(MY_NAME, properties);
469 verify(controller, never()).lock();
470 verify(contProv1).afterCreate(controller);
471 verify(contProv2).afterCreate(controller);
473 // first provider throws exceptions - same result
475 when(contProv1.beforeCreate(MY_NAME, properties)).thenThrow(new RuntimeException(EXPECTED));
476 when(contProv1.afterCreate(controller)).thenThrow(new RuntimeException(EXPECTED));
477 assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
479 verify(contProv1).beforeCreate(MY_NAME, properties);
480 verify(contProv2).beforeCreate(MY_NAME, properties);
481 verify(controller, never()).lock();
482 verify(contProv1).afterCreate(controller);
483 verify(contProv2).afterCreate(controller);
485 // locked - same result, but engine locked
488 assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
489 verify(contProv1).beforeCreate(MY_NAME, properties);
490 verify(controller, times(2)).lock();
491 verify(contProv2).afterCreate(controller);
493 // empty name in properties - same result
495 properties.setProperty(DroolsProperties.PROPERTY_CONTROLLER_NAME, "");
496 assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
497 verify(contProv1).beforeCreate(MY_NAME, properties);
499 // matching name in properties - same result
501 properties.setProperty(DroolsProperties.PROPERTY_CONTROLLER_NAME, MY_NAME);
502 assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
503 verify(contProv1).beforeCreate(MY_NAME, properties);
505 // mismatching name in properties - nothing should happen besides exception
507 properties.setProperty(DroolsProperties.PROPERTY_CONTROLLER_NAME, "mistmatched-name");
508 assertThatIllegalStateException().isThrownBy(() -> mgr.createPolicyController(MY_NAME, properties));
509 verify(contProv1, never()).beforeCreate(MY_NAME, properties);
511 // first provider generates controller - stops after first provider
513 when(contProv1.beforeCreate(MY_NAME, properties)).thenReturn(controller2);
514 assertEquals(controller2, mgr.createPolicyController(MY_NAME, properties));
515 verify(contProv1).beforeCreate(MY_NAME, properties);
516 verify(contProv2, never()).beforeCreate(MY_NAME, properties);
517 verify(controller, never()).lock();
518 verify(contProv1, never()).afterCreate(controller);
519 verify(contProv2, never()).afterCreate(controller);
521 // first provider returns true - stops after first provider afterXxx
523 when(contProv1.afterCreate(controller)).thenReturn(true);
524 assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
525 verify(contProv1).beforeCreate(MY_NAME, properties);
526 verify(contProv2).beforeCreate(MY_NAME, properties);
527 verify(contProv1).afterCreate(controller);
528 verify(contProv2, never()).afterCreate(controller);
532 public void testUpdatePolicyControllers() throws Exception {
533 assertEquals(Arrays.asList(controller3, controller4), mgr.updatePolicyControllers(pdpConfig.getControllers()));
535 // controller3 was CREATE
536 verify(controllerFactory).patch(controller3, drools3);
537 verify(controller3, never()).lock();
538 verify(controller3, never()).unlock();
540 // controller4 was UPDATE
541 verify(controllerFactory).patch(controller4, drools4);
542 verify(controller4, never()).lock();
543 verify(controller4).unlock();
546 assertTrue(mgr.updatePolicyControllers(null).isEmpty());
547 assertTrue(mgr.updatePolicyControllers(Collections.emptyList()).isEmpty());
549 // force exception in the first controller with invalid operation
551 config3.setOperation("unknown-operation");
552 assertEquals(Arrays.asList(controller4), mgr.updatePolicyControllers(pdpConfig.getControllers()));
554 // controller3 should NOT have been done
555 verify(controllerFactory, never()).patch(controller3, drools3);
557 // controller4 should still be done
558 verify(controllerFactory).patch(controller4, drools4);
559 verify(controller4, never()).lock();
560 verify(controller4).unlock();
564 public void testUpdatePolicyController() throws Exception {
565 assertEquals(controller3, mgr.updatePolicyController(config3));
566 verify(engine).createPolicyController(CONTROLLER3, properties);
568 // invalid parameters
569 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(null));
573 config3.setName(null);
574 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
577 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
581 config3.setOperation(null);
582 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
584 config3.setOperation("");
585 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
587 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_LOCK);
588 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
590 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_UNLOCK);
591 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
593 // exception from get() - should create controller
595 when(controllerFactory.get(CONTROLLER3)).thenThrow(new IllegalArgumentException(EXPECTED));
596 assertEquals(controller3, mgr.updatePolicyController(config3));
597 verify(engine).createPolicyController(CONTROLLER3, properties);
601 when(persist.getControllerProperties(CONTROLLER3)).thenReturn(null);
602 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
604 // throw linkage error
606 when(persist.getControllerProperties(CONTROLLER3)).thenThrow(new LinkageError(EXPECTED));
607 assertThatIllegalStateException().isThrownBy(() -> mgr.updatePolicyController(config3));
610 * For remaining tests, the factory will return the controller instead of creating
614 when(controllerFactory.get(CONTROLLER3)).thenReturn(controller3);
616 assertEquals(controller3, mgr.updatePolicyController(config3));
618 // should NOT have created a new controller
619 verify(engine, never()).createPolicyController(any(), any());
625 // check different operations
627 // CREATE only invokes patch() (note: mgr.update() has already been called)
628 verify(controllerFactory, times(++countPatch)).patch(controller3, drools3);
629 verify(controller3, times(countLock)).lock();
630 verify(controller3, times(countUnlock)).unlock();
632 // UPDATE invokes unlock() and patch()
633 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_UPDATE);
634 assertEquals(controller3, mgr.updatePolicyController(config3));
635 verify(controllerFactory, times(++countPatch)).patch(controller3, drools3);
636 verify(controller3, times(countLock)).lock();
637 verify(controller3, times(++countUnlock)).unlock();
639 // LOCK invokes lock()
640 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_LOCK);
641 assertEquals(controller3, mgr.updatePolicyController(config3));
642 verify(controllerFactory, times(countPatch)).patch(controller3, drools3);
643 verify(controller3, times(++countLock)).lock();
644 verify(controller3, times(countUnlock)).unlock();
646 // UNLOCK invokes unlock()
647 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_UNLOCK);
648 assertEquals(controller3, mgr.updatePolicyController(config3));
649 verify(controllerFactory, times(countPatch)).patch(controller3, drools3);
650 verify(controller3, times(countLock)).lock();
651 verify(controller3, times(++countUnlock)).unlock();
654 config3.setOperation("invalid-operation");
655 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
659 public void testStart() throws Throwable {
660 // normal success case
661 testStart(true, () -> {
662 // arrange for first provider, server, source, and sink to throw exceptions
663 when(prov1.beforeStart(mgr)).thenThrow(new RuntimeException(EXPECTED));
664 when(prov1.afterStart(mgr)).thenThrow(new RuntimeException(EXPECTED));
665 when(server1.waitedStart(anyLong())).thenThrow(new RuntimeException(EXPECTED));
666 when(source1.start()).thenThrow(new RuntimeException(EXPECTED));
667 when(sink1.start()).thenThrow(new RuntimeException(EXPECTED));
670 // servlet wait fails - still does everything
671 testStart(false, () -> when(server1.waitedStart(anyLong())).thenReturn(false));
673 // topic source fails to start - still does everything
674 testStart(false, () -> when(source1.start()).thenReturn(false));
676 // topic sink fails to start - still does everything
677 testStart(false, () -> when(sink1.start()).thenReturn(false));
679 // controller fails to start - still does everything
680 testStart(false, () -> when(controller.start()).thenReturn(false));
682 // controller throws an exception - still does everything
683 testStart(false, () -> when(controller.start()).thenThrow(new RuntimeException(EXPECTED)));
685 // endpoint manager fails to start - still does everything
686 testStart(false, () -> when(endpoint.start()).thenReturn(false));
688 // endpoint manager throws an exception - still does everything AND succeeds
689 testStart(true, () -> when(endpoint.start()).thenThrow(new IllegalStateException(EXPECTED)));
691 // locked - nothing other than beforeXxx methods should be invoked
693 mgr.configure(properties);
695 assertThatIllegalStateException().isThrownBy(() -> mgr.start());
696 verify(prov2).beforeStart(mgr);
697 verify(server2, never()).waitedStart(anyLong());
698 verify(source2, never()).start();
699 verify(sink1, never()).start();
700 verify(controller, never()).start();
701 verify(endpoint, never()).start();
702 assertFalse(jmxStarted);
703 verify(prov1, never()).afterStart(mgr);
707 (prov, flag) -> when(prov.beforeStart(mgr)).thenReturn(flag),
708 (prov, flag) -> when(prov.afterStart(mgr)).thenReturn(flag),
710 mgr.configure(properties);
711 assertTrue(mgr.start());
713 prov -> verify(prov).beforeStart(mgr),
714 () -> assertTrue(jmxStarted),
715 prov -> verify(prov).afterStart(mgr));
719 * Tests the start() method, after setting some option.
721 * @param expectedResult what start() is expected to return
722 * @param setOption function that sets an option
723 * @throws Throwable if an error occurs during setup
725 private void testStart(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
729 mgr.configure(properties);
730 assertEquals(expectedResult, mgr.start());
732 verify(prov1).beforeStart(mgr);
733 verify(prov2).beforeStart(mgr);
735 verify(server1).waitedStart(anyLong());
736 verify(server2).waitedStart(anyLong());
738 verify(source1).start();
739 verify(source2).start();
741 verify(sink1).start();
742 verify(sink2).start();
744 verify(controller).start();
745 verify(controller2).start();
747 verify(endpoint).start();
749 assertTrue(jmxStarted);
751 verify(prov1).afterStart(mgr);
752 verify(prov2).afterStart(mgr);
756 public void testStop() throws Throwable {
757 // normal success case
758 testStop(true, () -> {
759 // arrange for first provider, server, source, and sink to throw exceptions
760 when(prov1.beforeStop(mgr)).thenThrow(new RuntimeException(EXPECTED));
761 when(prov1.afterStop(mgr)).thenThrow(new RuntimeException(EXPECTED));
762 when(server1.stop()).thenThrow(new RuntimeException(EXPECTED));
763 when(source1.stop()).thenThrow(new RuntimeException(EXPECTED));
764 when(sink1.stop()).thenThrow(new RuntimeException(EXPECTED));
767 // not alive - shouldn't run anything besides beforeStop()
769 mgr.configure(properties);
770 assertTrue(mgr.stop());
771 verify(prov1).beforeStop(mgr);
772 verify(prov2).beforeStop(mgr);
773 verify(controller, never()).stop();
774 verify(source1, never()).stop();
775 verify(sink1, never()).stop();
776 verify(endpoint, never()).stop();
777 verify(server1, never()).stop();
778 verify(prov1, never()).afterStop(mgr);
779 verify(prov2, never()).afterStop(mgr);
781 // controller fails to stop - still does everything
782 testStop(false, () -> when(controller.stop()).thenReturn(false));
784 // controller throws an exception - still does everything
785 testStop(false, () -> when(controller.stop()).thenThrow(new RuntimeException(EXPECTED)));
787 // topic source fails to stop - still does everything
788 testStop(false, () -> when(source1.stop()).thenReturn(false));
790 // topic sink fails to stop - still does everything
791 testStop(false, () -> when(sink1.stop()).thenReturn(false));
793 // endpoint manager fails to stop - still does everything
794 testStop(false, () -> when(endpoint.stop()).thenReturn(false));
796 // servlet fails to stop - still does everything
797 testStop(false, () -> when(server1.stop()).thenReturn(false));
801 (prov, flag) -> when(prov.beforeStop(mgr)).thenReturn(flag),
802 (prov, flag) -> when(prov.afterStop(mgr)).thenReturn(flag),
804 mgr.configure(properties);
806 assertTrue(mgr.stop());
808 prov -> verify(prov).beforeStop(mgr),
809 () -> verify(endpoint).stop(),
810 prov -> verify(prov).afterStop(mgr));
814 * Tests the stop() method, after setting some option.
816 * @param expectedResult what stop() is expected to return
817 * @param setOption function that sets an option
818 * @throws Throwable if an error occurs during setup
820 private void testStop(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
824 mgr.configure(properties);
826 assertEquals(expectedResult, mgr.stop());
828 verify(prov1).beforeStop(mgr);
829 verify(prov2).beforeStop(mgr);
831 verify(controller).stop();
832 verify(controller2).stop();
834 verify(source1).stop();
835 verify(source2).stop();
837 verify(sink1).stop();
838 verify(sink2).stop();
840 verify(endpoint).stop();
842 verify(server1).stop();
843 verify(server2).stop();
845 verify(prov1).afterStop(mgr);
846 verify(prov2).afterStop(mgr);
850 public void testShutdown() throws Throwable {
851 // normal success case
853 // arrange for first provider, source, and sink to throw exceptions
854 when(prov1.beforeShutdown(mgr)).thenThrow(new RuntimeException(EXPECTED));
855 when(prov1.afterShutdown(mgr)).thenThrow(new RuntimeException(EXPECTED));
856 doThrow(new RuntimeException(EXPECTED)).when(source1).shutdown();
857 doThrow(new RuntimeException(EXPECTED)).when(sink1).shutdown();
860 assertNotNull(shutdownThread);
861 assertTrue(threadStarted);
862 assertTrue(threadInterrupted);
866 (prov, flag) -> when(prov.beforeShutdown(mgr)).thenReturn(flag),
867 (prov, flag) -> when(prov.afterShutdown(mgr)).thenReturn(flag),
869 mgr.configure(properties);
873 prov -> verify(prov).beforeShutdown(mgr),
874 () -> assertTrue(jmxStopped),
875 prov -> verify(prov).afterShutdown(mgr));
879 * Tests the shutdown() method, after setting some option.
881 * @param setOption function that sets an option
882 * @throws Throwable if an error occurs during setup
884 private void testShutdown(RunnableWithEx setOption) throws Throwable {
888 mgr.configure(properties);
892 verify(prov1).beforeShutdown(mgr);
893 verify(prov2).beforeShutdown(mgr);
895 verify(source1).shutdown();
896 verify(source2).shutdown();
898 verify(sink1).shutdown();
899 verify(sink2).shutdown();
901 verify(controllerFactory).shutdown();
902 verify(endpoint).shutdown();
903 verify(serverFactory).destroy();
905 assertTrue(jmxStopped);
907 verify(prov1).afterShutdown(mgr);
908 verify(prov2).afterShutdown(mgr);
912 public void testShutdownThreadRun() throws Throwable {
913 // arrange for first server to throw exceptions
914 testShutdownThreadRun(() -> doThrow(new RuntimeException(EXPECTED)).when(server1).shutdown());
916 // sleep throws an exception
917 testShutdownThreadRun(() -> shouldInterrupt = true);
921 * Tests the ShutdownThread.run() method, after setting some option.
923 * @param setOption function that sets an option
924 * @throws Throwable if an error occurs during setup
926 private void testShutdownThreadRun(RunnableWithEx setOption) throws Throwable {
930 mgr.configure(properties);
934 assertNotNull(shutdownThread);
936 shutdownThread.run();
938 assertTrue(threadSleepMs >= 0);
939 assertEquals(0, threadExitCode);
941 verify(server1).shutdown();
942 verify(server2).shutdown();
946 public void testIsAlive() {
947 mgr.configure(properties);
948 assertFalse(mgr.isAlive());
951 assertTrue(mgr.isAlive());
954 assertFalse(mgr.isAlive());
958 public void testLock() throws Throwable {
959 // normal success case
960 testLock(true, () -> {
961 // arrange for first provider to throw exceptions
962 when(prov1.beforeLock(mgr)).thenThrow(new RuntimeException(EXPECTED));
963 when(prov1.afterLock(mgr)).thenThrow(new RuntimeException(EXPECTED));
966 // already locked - shouldn't run anything besides beforeLock()
968 mgr.configure(properties);
970 assertTrue(mgr.lock());
971 verify(prov1, times(2)).beforeLock(mgr);
972 verify(prov2, times(2)).beforeLock(mgr);
973 verify(controller).lock();
974 verify(controller2).lock();
975 verify(endpoint).lock();
976 verify(prov1).afterLock(mgr);
977 verify(prov2).afterLock(mgr);
979 // controller fails to lock - still does everything
980 testLock(false, () -> when(controller.lock()).thenReturn(false));
982 // controller throws an exception - still does everything
983 testLock(false, () -> when(controller.lock()).thenThrow(new RuntimeException(EXPECTED)));
985 // endpoint manager fails to lock - still does everything
986 testLock(false, () -> when(endpoint.lock()).thenReturn(false));
990 (prov, flag) -> when(prov.beforeLock(mgr)).thenReturn(flag),
991 (prov, flag) -> when(prov.afterLock(mgr)).thenReturn(flag),
993 mgr.configure(properties);
995 assertTrue(mgr.lock());
997 prov -> verify(prov).beforeLock(mgr),
998 () -> verify(endpoint).lock(),
999 prov -> verify(prov).afterLock(mgr));
1003 * Tests the lock() method, after setting some option.
1005 * @param expectedResult what lock() is expected to return
1006 * @param setOption function that sets an option
1007 * @throws Throwable if an error occurs during setup
1009 private void testLock(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
1013 mgr.configure(properties);
1014 assertEquals(expectedResult, mgr.lock());
1016 verify(prov1).beforeLock(mgr);
1017 verify(prov2).beforeLock(mgr);
1019 verify(controller).lock();
1020 verify(controller2).lock();
1022 verify(endpoint).lock();
1024 verify(prov1).afterLock(mgr);
1025 verify(prov2).afterLock(mgr);
1029 public void testUnlock() throws Throwable {
1030 // normal success case
1031 testUnlock(true, () -> {
1032 // arrange for first provider to throw exceptions
1033 when(prov1.beforeUnlock(mgr)).thenThrow(new RuntimeException(EXPECTED));
1034 when(prov1.afterUnlock(mgr)).thenThrow(new RuntimeException(EXPECTED));
1037 // not locked - shouldn't run anything besides beforeUnlock()
1039 mgr.configure(properties);
1040 assertTrue(mgr.unlock());
1041 verify(prov1).beforeUnlock(mgr);
1042 verify(prov2).beforeUnlock(mgr);
1043 verify(controller, never()).unlock();
1044 verify(controller2, never()).unlock();
1045 verify(endpoint, never()).unlock();
1046 verify(prov1, never()).afterUnlock(mgr);
1047 verify(prov2, never()).afterUnlock(mgr);
1049 // controller fails to unlock - still does everything
1050 testUnlock(false, () -> when(controller.unlock()).thenReturn(false));
1052 // controller throws an exception - still does everything
1053 testUnlock(false, () -> when(controller.unlock()).thenThrow(new RuntimeException(EXPECTED)));
1055 // endpoint manager fails to unlock - still does everything
1056 testUnlock(false, () -> when(endpoint.unlock()).thenReturn(false));
1060 (prov, flag) -> when(prov.beforeUnlock(mgr)).thenReturn(flag),
1061 (prov, flag) -> when(prov.afterUnlock(mgr)).thenReturn(flag),
1063 mgr.configure(properties);
1065 assertTrue(mgr.unlock());
1067 prov -> verify(prov).beforeUnlock(mgr),
1068 () -> verify(endpoint).unlock(),
1069 prov -> verify(prov).afterUnlock(mgr));
1073 * Tests the unlock() method, after setting some option.
1075 * @param expectedResult what unlock() is expected to return
1076 * @param setOption function that sets an option
1077 * @throws Throwable if an error occurs during setup
1079 private void testUnlock(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
1083 mgr.configure(properties);
1085 assertEquals(expectedResult, mgr.unlock());
1087 verify(prov1).beforeUnlock(mgr);
1088 verify(prov2).beforeUnlock(mgr);
1090 verify(controller).unlock();
1091 verify(controller2).unlock();
1093 verify(endpoint).unlock();
1095 verify(prov1).afterUnlock(mgr);
1096 verify(prov2).afterUnlock(mgr);
1100 public void testIsLocked() {
1101 mgr.configure(properties);
1102 assertFalse(mgr.isLocked());
1105 assertTrue(mgr.isLocked());
1108 assertFalse(mgr.isLocked());
1112 public void testRemovePolicyControllerString() {
1113 mgr.removePolicyController(MY_NAME);
1115 verify(controllerFactory).destroy(MY_NAME);
1119 public void testRemovePolicyControllerPolicyController() {
1120 mgr.removePolicyController(controller);
1122 verify(controllerFactory).destroy(controller);
1126 public void testGetPolicyControllers() {
1127 assertEquals(controllers, mgr.getPolicyControllers());
1131 public void testGetPolicyControllerIds() {
1132 assertEquals(Arrays.asList(CONTROLLER1, CONTROLLER2), mgr.getPolicyControllerIds());
1136 public void testGetProperties() {
1137 properties.setProperty("prop-x", "value-x");
1138 properties.setProperty("prop-y", "value-y");
1140 mgr.configure(properties);
1141 assertEquals(properties, mgr.getProperties());
1145 public void testGetSources() {
1146 mgr.configure(properties);
1147 assertEquals(sources, mgr.getSources());
1151 public void testGetSinks() {
1152 mgr.configure(properties);
1153 assertEquals(sinks, mgr.getSinks());
1157 public void testGetHttpServers() {
1158 mgr.configure(properties);
1159 assertEquals(servers, mgr.getHttpServers());
1163 public void testGetFeatures() {
1164 assertEquals(Arrays.asList(FEATURE1, FEATURE2), mgr.getFeatures());
1168 public void testGetFeatureProviders() {
1169 assertEquals(providers, mgr.getFeatureProviders());
1173 public void testGetFeatureProvider() {
1174 assertEquals(prov1, mgr.getFeatureProvider(FEATURE1));
1175 assertEquals(prov2, mgr.getFeatureProvider(FEATURE2));
1178 assertThatIllegalArgumentException().isThrownBy(() -> mgr.getFeatureProvider(null));
1181 assertThatIllegalArgumentException().isThrownBy(() -> mgr.getFeatureProvider(""));
1184 assertThatIllegalArgumentException().isThrownBy(() -> mgr.getFeatureProvider("unknown-feature"));
1188 public void testOnTopicEvent() {
1189 mgr.onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, pdpConfigJson);
1191 verify(controllerFactory).patch(controller3, drools3);
1192 verify(controllerFactory).patch(controller4, drools4);
1194 // null json - no additional patches
1195 mgr.onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, null);
1197 verify(controllerFactory).patch(controller3, drools3);
1198 verify(controllerFactory).patch(controller4, drools4);
1202 public void testDeliverStringObject() throws Exception {
1203 mgr.configure(properties);
1206 assertTrue(mgr.deliver(MY_TOPIC, MY_EVENT));
1208 verify(sink1).send(MESSAGE);
1210 // invalid parameters
1211 String nullStr = null;
1212 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(nullStr, MY_EVENT));
1213 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver("", MY_EVENT));
1215 Object nullObj = null;
1216 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(MY_TOPIC, nullObj));
1220 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1225 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1227 // issues with topic
1229 mgr.configure(properties);
1233 when(endpoint.getTopicSinks(MY_TOPIC)).thenReturn(null);
1234 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1237 when(endpoint.getTopicSinks(MY_TOPIC)).thenReturn(Collections.emptyList());
1238 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1241 when(endpoint.getTopicSinks(MY_TOPIC)).thenReturn(sinks);
1242 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1246 public void testDeliverStringStringObject() {
1247 mgr.configure(properties);
1250 assertTrue(mgr.deliver(NOOP_STR, MY_TOPIC, MY_EVENT));
1252 verify(sink1).send(MESSAGE);
1254 // invalid parameters
1255 String nullStr = null;
1256 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(nullStr, MY_TOPIC, MY_EVENT));
1257 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver("", MY_TOPIC, MY_EVENT));
1258 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver("unknown-bus-type", MY_TOPIC, MY_EVENT));
1260 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(NOOP_STR, nullStr, MY_EVENT));
1261 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(NOOP_STR, "", MY_EVENT));
1263 Object nullObj = null;
1264 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(NOOP_STR, MY_TOPIC, nullObj));
1268 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(NOOP_STR, MY_TOPIC, MY_EVENT));
1273 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(NOOP_STR, MY_TOPIC, MY_EVENT));
1277 public void testDeliverCommInfrastructureStringObject() throws Exception {
1278 mgr.configure(properties);
1281 assertTrue(mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1283 verify(controller, never()).deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT);
1285 verify(coder).encode(MY_TOPIC, MY_EVENT);
1286 verify(sink1).send(MESSAGE);
1288 // invalid parameters
1289 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, null, MY_EVENT));
1290 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, "", MY_EVENT));
1292 Object nullObj = null;
1293 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, nullObj));
1297 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1302 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1304 // send() throws an exception
1306 mgr.configure(properties);
1308 when(sink1.send(any())).thenThrow(new ArithmeticException(EXPECTED));
1309 assertThatThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT))
1310 .isInstanceOf(ArithmeticException.class);
1313 * For remaining tests, have the controller handle delivery.
1316 mgr.configure(properties);
1318 DroolsController drools = mock(DroolsController.class);
1319 when(coder.getDroolsController(MY_TOPIC, MY_EVENT)).thenReturn(drools);
1320 when(controllerFactory.get(drools)).thenReturn(controller);
1321 when(controller.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT)).thenReturn(true);
1323 assertTrue(mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1325 verify(controller).deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT);
1327 verify(coder, never()).encode(MY_TOPIC, MY_EVENT);
1328 verify(sink1, never()).send(MESSAGE);
1330 // controller throws exception, so should drop into regular handling
1331 when(controller.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT)).thenThrow(new RuntimeException(EXPECTED));
1333 assertTrue(mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1335 // should have attempted this again
1336 verify(controller, times(2)).deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT);
1338 // now these should have been called
1339 verify(coder).encode(MY_TOPIC, MY_EVENT);
1340 verify(sink1).send(MESSAGE);
1344 public void testDeliverCommInfrastructureStringString() {
1345 mgr.configure(properties);
1348 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MESSAGE));
1353 assertTrue(mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MESSAGE));
1354 verify(sink1).send(MESSAGE);
1355 verify(sink2, never()).send(any());
1357 // invalid parameters
1358 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, null, MESSAGE));
1359 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, "", MESSAGE));
1361 String nullStr = null;
1362 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, nullStr));
1363 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, ""));
1366 assertThatIllegalStateException()
1367 .isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, "unknown-topic", MESSAGE));
1371 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MESSAGE));
1376 public void testActivate() throws Throwable {
1377 // normal success case
1378 testActivate(() -> {
1379 // arrange for first provider and controller to throw exceptions
1380 when(prov1.beforeActivate(mgr)).thenThrow(new RuntimeException(EXPECTED));
1381 when(prov1.afterActivate(mgr)).thenThrow(new RuntimeException(EXPECTED));
1382 when(controller.start()).thenThrow(new RuntimeException(EXPECTED));
1385 // controller generates linkage error
1386 testActivate(() -> when(controller.start()).thenThrow(new LinkageError(EXPECTED)));
1390 (prov, flag) -> when(prov.beforeActivate(mgr)).thenReturn(flag),
1391 (prov, flag) -> when(prov.afterActivate(mgr)).thenReturn(flag),
1393 mgr.configure(properties);
1397 prov -> verify(prov).beforeActivate(mgr),
1398 () -> assertFalse(mgr.isLocked()),
1399 prov -> verify(prov).afterActivate(mgr));
1403 * Tests the activate() method, after setting some option.
1405 * @param setOption function that sets an option
1406 * @throws Throwable if an error occurs during setup
1408 private void testActivate(RunnableWithEx setOption) throws Throwable {
1412 mgr.configure(properties);
1416 verify(prov1).beforeActivate(mgr);
1417 verify(prov2).beforeActivate(mgr);
1419 // unlocked by activate() AND by unlock() (which is invoked by activate())
1420 verify(controller, times(2)).unlock();
1421 verify(controller2, times(2)).unlock();
1423 verify(controller).start();
1424 verify(controller2).start();
1426 assertFalse(mgr.isLocked());
1428 verify(prov1).afterActivate(mgr);
1429 verify(prov2).afterActivate(mgr);
1433 public void testDeactivate() throws Throwable {
1434 // normal success case
1435 testDeactivate(() -> {
1436 // arrange for first provider and controller to throw exceptions
1437 when(prov1.beforeDeactivate(mgr)).thenThrow(new RuntimeException(EXPECTED));
1438 when(prov1.afterDeactivate(mgr)).thenThrow(new RuntimeException(EXPECTED));
1439 when(controller.stop()).thenThrow(new RuntimeException(EXPECTED));
1442 // controller generates linkage error
1443 testDeactivate(() -> when(controller.stop()).thenThrow(new LinkageError(EXPECTED)));
1447 (prov, flag) -> when(prov.beforeDeactivate(mgr)).thenReturn(flag),
1448 (prov, flag) -> when(prov.afterDeactivate(mgr)).thenReturn(flag),
1450 mgr.configure(properties);
1453 prov -> verify(prov).beforeDeactivate(mgr),
1454 () -> assertTrue(mgr.isLocked()),
1455 prov -> verify(prov).afterDeactivate(mgr));
1459 * Tests the deactivate() method, after setting some option.
1461 * @param setOption function that sets an option
1462 * @throws Throwable if an error occurs during setup
1464 private void testDeactivate(RunnableWithEx setOption) throws Throwable {
1468 mgr.configure(properties);
1471 verify(prov1).beforeDeactivate(mgr);
1472 verify(prov2).beforeDeactivate(mgr);
1474 verify(controller).lock();
1475 verify(controller2).lock();
1477 verify(controller).stop();
1478 verify(controller2).stop();
1480 assertTrue(mgr.isLocked());
1482 verify(prov1).afterDeactivate(mgr);
1483 verify(prov2).afterDeactivate(mgr);
1487 public void testControllerConfig() throws Exception {
1488 mgr.configure(properties);
1489 assertTrue(mgr.configure(pdpConfig));
1491 verify(controllerFactory).patch(controller3, drools3);
1492 verify(controllerFactory).patch(controller4, drools4);
1494 // empty controllers
1495 pdpConfig.getControllers().clear();
1496 assertFalse(mgr.configure(pdpConfig));
1499 pdpConfig.setControllers(null);
1500 assertFalse(mgr.configure(pdpConfig));
1502 // arrange for controller3 to fail
1504 config3.setOperation("fail-3");
1505 assertFalse(mgr.configure(pdpConfig));
1507 verify(controllerFactory, never()).patch(controller3, drools3);
1508 verify(controllerFactory).patch(controller4, drools4);
1510 // arrange for both controllers to fail
1512 config3.setOperation("fail-3");
1513 config4.setOperation("fail-4");
1514 assertFalse(mgr.configure(pdpConfig));
1518 public void testToString() {
1519 assertTrue(mgr.toString().startsWith("PolicyEngineManager ["));
1523 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries
1524 * combinations where beforeXxx and afterXxx return {@code true} and {@code false}.
1526 * @param setBefore function to set the return value of a provider's beforeXxx method
1527 * @param setAfter function to set the return value of a provider's afterXxx method
1528 * @param action invokes the operation
1529 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
1530 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
1531 * and the afterXxx loop was invoked
1532 * @param verifyAfter verifies that a provider's afterXxx method was invoked
1533 * @throws Exception if an error occurs while calling {@link #setUp()}
1535 private void checkBeforeAfter(BiConsumer<PolicyEngineFeatureAPI, Boolean> setBefore,
1536 BiConsumer<PolicyEngineFeatureAPI, Boolean> setAfter, Runnable action,
1537 Consumer<PolicyEngineFeatureAPI> verifyBefore, Runnable verifyMiddle,
1538 Consumer<PolicyEngineFeatureAPI> verifyAfter) throws Exception {
1540 checkBeforeAfter_FalseFalse(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
1541 checkBeforeAfter_FalseTrue(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
1542 checkBeforeAfter_TrueFalse(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
1544 // don't need to test true-true, as it's behavior is a subset of true-false
1548 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
1549 * case where both the beforeXxx and afterXxx methods return {@code false}.
1551 * @param setBefore function to set the return value of a provider's beforeXxx method
1552 * @param setAfter function to set the return value of a provider's afterXxx method
1553 * @param action invokes the operation
1554 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
1555 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
1556 * and the afterXxx loop was invoked
1557 * @param verifyAfter verifies that a provider's afterXxx method was invoked
1558 * @throws Exception if an error occurs while calling {@link #setUp()}
1560 private void checkBeforeAfter_FalseFalse(BiConsumer<PolicyEngineFeatureAPI, Boolean> setBefore,
1561 BiConsumer<PolicyEngineFeatureAPI, Boolean> setAfter, Runnable action,
1562 Consumer<PolicyEngineFeatureAPI> verifyBefore, Runnable verifyMiddle,
1563 Consumer<PolicyEngineFeatureAPI> verifyAfter) throws Exception {
1567 // configure for the test
1568 setBefore.accept(prov1, false);
1569 setBefore.accept(prov2, false);
1571 setAfter.accept(prov1, false);
1572 setAfter.accept(prov2, false);
1577 // verify that various methods were invoked
1578 verifyBefore.accept(prov1);
1579 verifyBefore.accept(prov2);
1583 verifyAfter.accept(prov1);
1584 verifyAfter.accept(prov2);
1588 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
1589 * case where the first provider's afterXxx returns {@code true}, while the others
1590 * return {@code false}.
1592 * @param setBefore function to set the return value of a provider's beforeXxx method
1593 * @param setAfter function to set the return value of a provider's afterXxx method
1594 * @param action invokes the operation
1595 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
1596 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
1597 * and the afterXxx loop was invoked
1598 * @param verifyAfter verifies that a provider's afterXxx method was invoked
1599 * @throws Exception if an error occurs while calling {@link #setUp()}
1601 private void checkBeforeAfter_FalseTrue(BiConsumer<PolicyEngineFeatureAPI, Boolean> setBefore,
1602 BiConsumer<PolicyEngineFeatureAPI, Boolean> setAfter, Runnable action,
1603 Consumer<PolicyEngineFeatureAPI> verifyBefore, Runnable verifyMiddle,
1604 Consumer<PolicyEngineFeatureAPI> verifyAfter) throws Exception {
1608 // configure for the test
1609 setBefore.accept(prov1, false);
1610 setBefore.accept(prov2, false);
1612 setAfter.accept(prov1, true);
1613 setAfter.accept(prov2, false);
1618 // verify that various methods were invoked
1619 verifyBefore.accept(prov1);
1620 verifyBefore.accept(prov2);
1624 verifyAfter.accept(prov1);
1625 assertThatThrownBy(() -> verifyAfter.accept(prov2)).isInstanceOf(AssertionError.class);
1629 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
1630 * case where the first provider's beforeXxx returns {@code true}, while the others
1631 * return {@code false}.
1633 * @param setBefore function to set the return value of a provider's beforeXxx method
1634 * @param setAfter function to set the return value of a provider's afterXxx method
1635 * @param action invokes the operation
1636 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
1637 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
1638 * and the afterXxx loop was invoked
1639 * @param verifyAfter verifies that a provider's afterXxx method was invoked
1640 * @throws Exception if an error occurs while calling {@link #setUp()}
1642 private void checkBeforeAfter_TrueFalse(BiConsumer<PolicyEngineFeatureAPI, Boolean> setBefore,
1643 BiConsumer<PolicyEngineFeatureAPI, Boolean> setAfter, Runnable action,
1644 Consumer<PolicyEngineFeatureAPI> verifyBefore, Runnable verifyMiddle,
1645 Consumer<PolicyEngineFeatureAPI> verifyAfter) throws Exception {
1649 // configure for the test
1650 setBefore.accept(prov1, true);
1651 setBefore.accept(prov2, false);
1653 setAfter.accept(prov1, false);
1654 setAfter.accept(prov2, false);
1659 // verify that various methods were invoked
1660 verifyBefore.accept(prov1);
1662 // remaining methods should not have been invoked
1663 assertThatThrownBy(() -> verifyBefore.accept(prov2)).isInstanceOf(AssertionError.class);
1665 assertThatThrownBy(() -> verifyMiddle.run()).isInstanceOf(AssertionError.class);
1667 assertThatThrownBy(() -> verifyAfter.accept(prov1)).isInstanceOf(AssertionError.class);
1668 assertThatThrownBy(() -> verifyAfter.accept(prov2)).isInstanceOf(AssertionError.class);
1672 * Manager with overrides.
1674 private class PolicyEngineManagerImpl extends PolicyEngineManager {
1677 protected List<PolicyEngineFeatureAPI> getEngineProviders() {
1682 protected List<PolicyControllerFeatureAPI> getControllerProviders() {
1683 return contProviders;
1687 protected void globalInitContainer(String[] cliArgs) {
1688 globalInitArgs = cliArgs;
1692 protected TopicEndpoint getTopicEndpointManager() {
1697 protected HttpServletServerFactory getServletFactory() {
1698 return serverFactory;
1702 protected PolicyControllerFactory getControllerFactory() {
1703 return controllerFactory;
1707 protected void startPdpJmxListener() {
1712 protected void stopPdpJmxListener() {
1717 protected Thread makeShutdownThread() {
1718 shutdownThread = new MyShutdown();
1719 return shutdownThread;
1723 protected EventProtocolCoder getProtocolCoder() {
1728 protected SystemPersistence getPersistenceManager() {
1733 protected PolicyEngine getPolicyEngine() {
1738 * Shutdown thread with overrides.
1740 private class MyShutdown extends ShutdownThread {
1743 protected void doSleep(long sleepMs) throws InterruptedException {
1744 threadSleepMs = sleepMs;
1746 if (shouldInterrupt) {
1747 throw new InterruptedException(EXPECTED);
1752 protected void doExit(int code) {
1753 threadExitCode = code;
1757 public synchronized void start() {
1758 threadStarted = true;
1762 public void interrupt() {
1763 threadInterrupted = true;
1768 @FunctionalInterface
1769 private static interface RunnableWithEx {
1770 void run() throws Exception;