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"));
374 public void testDefaultTelemetryConfig() {
375 Properties config = mgr.defaultTelemetryConfig();
376 assertNotNull(config);
377 assertFalse(config.isEmpty());
381 public void testConfigureProperties() throws Exception {
382 // arrange for first provider to throw exceptions
383 when(prov1.beforeConfigure(mgr, properties)).thenThrow(new RuntimeException(EXPECTED));
384 when(prov1.afterConfigure(mgr)).thenThrow(new RuntimeException(EXPECTED));
386 mgr.configure(properties);
388 verify(prov1).beforeConfigure(mgr, properties);
389 verify(prov2).beforeConfigure(mgr, properties);
391 assertTrue(mgr.getProperties() == properties);
393 assertEquals(sources, mgr.getSources());
394 assertEquals(sinks, mgr.getSinks());
395 assertEquals(servers, mgr.getHttpServers());
397 verify(source1).register(mgr);
398 verify(source2).register(mgr);
400 verify(prov1).afterConfigure(mgr);
401 verify(prov2).afterConfigure(mgr);
403 // middle stuff throws exception - still calls afterXxx
405 when(endpoint.addTopicSources(properties)).thenThrow(new IllegalArgumentException(EXPECTED));
406 when(endpoint.addTopicSinks(properties)).thenThrow(new IllegalArgumentException(EXPECTED));
407 when(serverFactory.build(properties)).thenThrow(new IllegalArgumentException(EXPECTED));
408 mgr.configure(properties);
409 verify(prov2).afterConfigure(mgr);
411 // null properties - nothing should be invoked
413 Properties nullProps = null;
414 assertThatIllegalArgumentException().isThrownBy(() -> mgr.configure(nullProps));
415 verify(prov1, never()).beforeConfigure(mgr, properties);
416 verify(prov1, never()).afterConfigure(mgr);
420 (prov, flag) -> when(prov.beforeConfigure(mgr, properties)).thenReturn(flag),
421 (prov, flag) -> when(prov.afterConfigure(mgr)).thenReturn(flag),
422 () -> mgr.configure(properties),
423 prov -> verify(prov).beforeConfigure(mgr, properties),
424 () -> assertTrue(mgr.getProperties() == properties),
425 prov -> verify(prov).afterConfigure(mgr));
429 public void testConfigurePdpdConfiguration() throws Exception {
430 mgr.configure(properties);
431 assertTrue(mgr.configure(pdpConfig));
433 verify(controllerFactory).patch(controller3, drools3);
434 verify(controllerFactory).patch(controller4, drools4);
437 PdpdConfiguration nullConfig = null;
438 assertThatIllegalArgumentException().isThrownBy(() -> mgr.configure(nullConfig));
440 pdpConfig.setEntity("unknown-entity");
441 assertThatIllegalArgumentException().isThrownBy(() -> mgr.configure(pdpConfig));
443 // source list of size 1
445 when(endpoint.addTopicSources(any())).thenReturn(Arrays.asList(source1));
446 mgr.configure(properties);
447 assertTrue(mgr.configure(pdpConfig));
449 verify(controllerFactory).patch(controller3, drools3);
450 verify(controllerFactory).patch(controller4, drools4);
454 public void testCreatePolicyController() throws Exception {
455 assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
457 verify(contProv1).beforeCreate(MY_NAME, properties);
458 verify(contProv2).beforeCreate(MY_NAME, properties);
459 verify(controller, never()).lock();
460 verify(contProv1).afterCreate(controller);
461 verify(contProv2).afterCreate(controller);
463 // first provider throws exceptions - same result
465 when(contProv1.beforeCreate(MY_NAME, properties)).thenThrow(new RuntimeException(EXPECTED));
466 when(contProv1.afterCreate(controller)).thenThrow(new RuntimeException(EXPECTED));
467 assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
469 verify(contProv1).beforeCreate(MY_NAME, properties);
470 verify(contProv2).beforeCreate(MY_NAME, properties);
471 verify(controller, never()).lock();
472 verify(contProv1).afterCreate(controller);
473 verify(contProv2).afterCreate(controller);
475 // locked - same result, but engine locked
478 assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
479 verify(contProv1).beforeCreate(MY_NAME, properties);
480 verify(controller, times(2)).lock();
481 verify(contProv2).afterCreate(controller);
483 // empty name in properties - same result
485 properties.setProperty(DroolsProperties.PROPERTY_CONTROLLER_NAME, "");
486 assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
487 verify(contProv1).beforeCreate(MY_NAME, properties);
489 // matching name in properties - same result
491 properties.setProperty(DroolsProperties.PROPERTY_CONTROLLER_NAME, MY_NAME);
492 assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
493 verify(contProv1).beforeCreate(MY_NAME, properties);
495 // mismatching name in properties - nothing should happen besides exception
497 properties.setProperty(DroolsProperties.PROPERTY_CONTROLLER_NAME, "mistmatched-name");
498 assertThatIllegalStateException().isThrownBy(() -> mgr.createPolicyController(MY_NAME, properties));
499 verify(contProv1, never()).beforeCreate(MY_NAME, properties);
501 // first provider generates controller - stops after first provider
503 when(contProv1.beforeCreate(MY_NAME, properties)).thenReturn(controller2);
504 assertEquals(controller2, mgr.createPolicyController(MY_NAME, properties));
505 verify(contProv1).beforeCreate(MY_NAME, properties);
506 verify(contProv2, never()).beforeCreate(MY_NAME, properties);
507 verify(controller, never()).lock();
508 verify(contProv1, never()).afterCreate(controller);
509 verify(contProv2, never()).afterCreate(controller);
511 // first provider returns true - stops after first provider afterXxx
513 when(contProv1.afterCreate(controller)).thenReturn(true);
514 assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
515 verify(contProv1).beforeCreate(MY_NAME, properties);
516 verify(contProv2).beforeCreate(MY_NAME, properties);
517 verify(contProv1).afterCreate(controller);
518 verify(contProv2, never()).afterCreate(controller);
522 public void testUpdatePolicyControllers() throws Exception {
523 assertEquals(Arrays.asList(controller3, controller4), mgr.updatePolicyControllers(pdpConfig.getControllers()));
525 // controller3 was CREATE
526 verify(controllerFactory).patch(controller3, drools3);
527 verify(controller3, never()).lock();
528 verify(controller3, never()).unlock();
530 // controller4 was UPDATE
531 verify(controllerFactory).patch(controller4, drools4);
532 verify(controller4, never()).lock();
533 verify(controller4).unlock();
536 assertTrue(mgr.updatePolicyControllers(null).isEmpty());
537 assertTrue(mgr.updatePolicyControllers(Collections.emptyList()).isEmpty());
539 // force exception in the first controller with invalid operation
541 config3.setOperation("unknown-operation");
542 assertEquals(Arrays.asList(controller4), mgr.updatePolicyControllers(pdpConfig.getControllers()));
544 // controller3 should NOT have been done
545 verify(controllerFactory, never()).patch(controller3, drools3);
547 // controller4 should still be done
548 verify(controllerFactory).patch(controller4, drools4);
549 verify(controller4, never()).lock();
550 verify(controller4).unlock();
554 public void testUpdatePolicyController() throws Exception {
555 assertEquals(controller3, mgr.updatePolicyController(config3));
556 verify(engine).createPolicyController(CONTROLLER3, properties);
558 // invalid parameters
559 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(null));
563 config3.setName(null);
564 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
567 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
571 config3.setOperation(null);
572 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
574 config3.setOperation("");
575 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
577 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_LOCK);
578 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
580 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_UNLOCK);
581 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
583 // exception from get() - should create controller
585 when(controllerFactory.get(CONTROLLER3)).thenThrow(new IllegalArgumentException(EXPECTED));
586 assertEquals(controller3, mgr.updatePolicyController(config3));
587 verify(engine).createPolicyController(CONTROLLER3, properties);
591 when(persist.getControllerProperties(CONTROLLER3)).thenReturn(null);
592 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
594 // throw linkage error
596 when(persist.getControllerProperties(CONTROLLER3)).thenThrow(new LinkageError(EXPECTED));
597 assertThatIllegalStateException().isThrownBy(() -> mgr.updatePolicyController(config3));
600 * For remaining tests, the factory will return the controller instead of creating
604 when(controllerFactory.get(CONTROLLER3)).thenReturn(controller3);
606 assertEquals(controller3, mgr.updatePolicyController(config3));
608 // should NOT have created a new controller
609 verify(engine, never()).createPolicyController(any(), any());
615 // check different operations
617 // CREATE only invokes patch() (note: mgr.update() has already been called)
618 verify(controllerFactory, times(++countPatch)).patch(controller3, drools3);
619 verify(controller3, times(countLock)).lock();
620 verify(controller3, times(countUnlock)).unlock();
622 // UPDATE invokes unlock() and patch()
623 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_UPDATE);
624 assertEquals(controller3, mgr.updatePolicyController(config3));
625 verify(controllerFactory, times(++countPatch)).patch(controller3, drools3);
626 verify(controller3, times(countLock)).lock();
627 verify(controller3, times(++countUnlock)).unlock();
629 // LOCK invokes lock()
630 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_LOCK);
631 assertEquals(controller3, mgr.updatePolicyController(config3));
632 verify(controllerFactory, times(countPatch)).patch(controller3, drools3);
633 verify(controller3, times(++countLock)).lock();
634 verify(controller3, times(countUnlock)).unlock();
636 // UNLOCK invokes unlock()
637 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_UNLOCK);
638 assertEquals(controller3, mgr.updatePolicyController(config3));
639 verify(controllerFactory, times(countPatch)).patch(controller3, drools3);
640 verify(controller3, times(countLock)).lock();
641 verify(controller3, times(++countUnlock)).unlock();
644 config3.setOperation("invalid-operation");
645 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
649 public void testStart() throws Throwable {
650 // normal success case
651 testStart(true, () -> {
652 // arrange for first provider, server, source, and sink to throw exceptions
653 when(prov1.beforeStart(mgr)).thenThrow(new RuntimeException(EXPECTED));
654 when(prov1.afterStart(mgr)).thenThrow(new RuntimeException(EXPECTED));
655 when(server1.waitedStart(anyLong())).thenThrow(new RuntimeException(EXPECTED));
656 when(source1.start()).thenThrow(new RuntimeException(EXPECTED));
657 when(sink1.start()).thenThrow(new RuntimeException(EXPECTED));
660 // servlet wait fails - still does everything
661 testStart(false, () -> when(server1.waitedStart(anyLong())).thenReturn(false));
663 // topic source fails to start - still does everything
664 testStart(false, () -> when(source1.start()).thenReturn(false));
666 // topic sink fails to start - still does everything
667 testStart(false, () -> when(sink1.start()).thenReturn(false));
669 // controller fails to start - still does everything
670 testStart(false, () -> when(controller.start()).thenReturn(false));
672 // controller throws an exception - still does everything
673 testStart(false, () -> when(controller.start()).thenThrow(new RuntimeException(EXPECTED)));
675 // endpoint manager fails to start - still does everything
676 testStart(false, () -> when(endpoint.start()).thenReturn(false));
678 // endpoint manager throws an exception - still does everything AND succeeds
679 testStart(true, () -> when(endpoint.start()).thenThrow(new IllegalStateException(EXPECTED)));
681 // locked - nothing other than beforeXxx methods should be invoked
683 mgr.configure(properties);
685 assertThatIllegalStateException().isThrownBy(() -> mgr.start());
686 verify(prov2).beforeStart(mgr);
687 verify(server2, never()).waitedStart(anyLong());
688 verify(source2, never()).start();
689 verify(sink1, never()).start();
690 verify(controller, never()).start();
691 verify(endpoint, never()).start();
692 assertFalse(jmxStarted);
693 verify(prov1, never()).afterStart(mgr);
697 (prov, flag) -> when(prov.beforeStart(mgr)).thenReturn(flag),
698 (prov, flag) -> when(prov.afterStart(mgr)).thenReturn(flag),
700 mgr.configure(properties);
701 assertTrue(mgr.start());
703 prov -> verify(prov).beforeStart(mgr),
704 () -> assertTrue(jmxStarted),
705 prov -> verify(prov).afterStart(mgr));
709 * Tests the start() method, after setting some option.
711 * @param expectedResult what start() is expected to return
712 * @param setOption function that sets an option
713 * @throws Throwable if an error occurs during setup
715 private void testStart(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
719 mgr.configure(properties);
720 assertEquals(expectedResult, mgr.start());
722 verify(prov1).beforeStart(mgr);
723 verify(prov2).beforeStart(mgr);
725 verify(server1).waitedStart(anyLong());
726 verify(server2).waitedStart(anyLong());
728 verify(source1).start();
729 verify(source2).start();
731 verify(sink1).start();
732 verify(sink2).start();
734 verify(controller).start();
735 verify(controller2).start();
737 verify(endpoint).start();
739 assertTrue(jmxStarted);
741 verify(prov1).afterStart(mgr);
742 verify(prov2).afterStart(mgr);
746 public void testStop() throws Throwable {
747 // normal success case
748 testStop(true, () -> {
749 // arrange for first provider, server, source, and sink to throw exceptions
750 when(prov1.beforeStop(mgr)).thenThrow(new RuntimeException(EXPECTED));
751 when(prov1.afterStop(mgr)).thenThrow(new RuntimeException(EXPECTED));
752 when(server1.stop()).thenThrow(new RuntimeException(EXPECTED));
753 when(source1.stop()).thenThrow(new RuntimeException(EXPECTED));
754 when(sink1.stop()).thenThrow(new RuntimeException(EXPECTED));
757 // not alive - shouldn't run anything besides beforeStop()
759 mgr.configure(properties);
760 assertTrue(mgr.stop());
761 verify(prov1).beforeStop(mgr);
762 verify(prov2).beforeStop(mgr);
763 verify(controller, never()).stop();
764 verify(source1, never()).stop();
765 verify(sink1, never()).stop();
766 verify(endpoint, never()).stop();
767 verify(server1, never()).stop();
768 verify(prov1, never()).afterStop(mgr);
769 verify(prov2, never()).afterStop(mgr);
771 // controller fails to stop - still does everything
772 testStop(false, () -> when(controller.stop()).thenReturn(false));
774 // controller throws an exception - still does everything
775 testStop(false, () -> when(controller.stop()).thenThrow(new RuntimeException(EXPECTED)));
777 // topic source fails to stop - still does everything
778 testStop(false, () -> when(source1.stop()).thenReturn(false));
780 // topic sink fails to stop - still does everything
781 testStop(false, () -> when(sink1.stop()).thenReturn(false));
783 // endpoint manager fails to stop - still does everything
784 testStop(false, () -> when(endpoint.stop()).thenReturn(false));
786 // servlet fails to stop - still does everything
787 testStop(false, () -> when(server1.stop()).thenReturn(false));
791 (prov, flag) -> when(prov.beforeStop(mgr)).thenReturn(flag),
792 (prov, flag) -> when(prov.afterStop(mgr)).thenReturn(flag),
794 mgr.configure(properties);
796 assertTrue(mgr.stop());
798 prov -> verify(prov).beforeStop(mgr),
799 () -> verify(endpoint).stop(),
800 prov -> verify(prov).afterStop(mgr));
804 * Tests the stop() method, after setting some option.
806 * @param expectedResult what stop() is expected to return
807 * @param setOption function that sets an option
808 * @throws Throwable if an error occurs during setup
810 private void testStop(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
814 mgr.configure(properties);
816 assertEquals(expectedResult, mgr.stop());
818 verify(prov1).beforeStop(mgr);
819 verify(prov2).beforeStop(mgr);
821 verify(controller).stop();
822 verify(controller2).stop();
824 verify(source1).stop();
825 verify(source2).stop();
827 verify(sink1).stop();
828 verify(sink2).stop();
830 verify(endpoint).stop();
832 verify(server1).stop();
833 verify(server2).stop();
835 verify(prov1).afterStop(mgr);
836 verify(prov2).afterStop(mgr);
840 public void testShutdown() throws Throwable {
841 // normal success case
843 // arrange for first provider, source, and sink to throw exceptions
844 when(prov1.beforeShutdown(mgr)).thenThrow(new RuntimeException(EXPECTED));
845 when(prov1.afterShutdown(mgr)).thenThrow(new RuntimeException(EXPECTED));
846 doThrow(new RuntimeException(EXPECTED)).when(source1).shutdown();
847 doThrow(new RuntimeException(EXPECTED)).when(sink1).shutdown();
850 assertNotNull(shutdownThread);
851 assertTrue(threadStarted);
852 assertTrue(threadInterrupted);
856 (prov, flag) -> when(prov.beforeShutdown(mgr)).thenReturn(flag),
857 (prov, flag) -> when(prov.afterShutdown(mgr)).thenReturn(flag),
859 mgr.configure(properties);
863 prov -> verify(prov).beforeShutdown(mgr),
864 () -> assertTrue(jmxStopped),
865 prov -> verify(prov).afterShutdown(mgr));
869 * Tests the shutdown() method, after setting some option.
871 * @param setOption function that sets an option
872 * @throws Throwable if an error occurs during setup
874 private void testShutdown(RunnableWithEx setOption) throws Throwable {
878 mgr.configure(properties);
882 verify(prov1).beforeShutdown(mgr);
883 verify(prov2).beforeShutdown(mgr);
885 verify(source1).shutdown();
886 verify(source2).shutdown();
888 verify(sink1).shutdown();
889 verify(sink2).shutdown();
891 verify(controllerFactory).shutdown();
892 verify(endpoint).shutdown();
893 verify(serverFactory).destroy();
895 assertTrue(jmxStopped);
897 verify(prov1).afterShutdown(mgr);
898 verify(prov2).afterShutdown(mgr);
902 public void testShutdownThreadRun() throws Throwable {
903 // arrange for first server to throw exceptions
904 testShutdownThreadRun(() -> doThrow(new RuntimeException(EXPECTED)).when(server1).shutdown());
906 // sleep throws an exception
907 testShutdownThreadRun(() -> shouldInterrupt = true);
911 * Tests the ShutdownThread.run() method, after setting some option.
913 * @param setOption function that sets an option
914 * @throws Throwable if an error occurs during setup
916 private void testShutdownThreadRun(RunnableWithEx setOption) throws Throwable {
920 mgr.configure(properties);
924 assertNotNull(shutdownThread);
926 shutdownThread.run();
928 assertTrue(threadSleepMs >= 0);
929 assertEquals(0, threadExitCode);
931 verify(server1).shutdown();
932 verify(server2).shutdown();
936 public void testIsAlive() {
937 mgr.configure(properties);
938 assertFalse(mgr.isAlive());
941 assertTrue(mgr.isAlive());
944 assertFalse(mgr.isAlive());
948 public void testLock() throws Throwable {
949 // normal success case
950 testLock(true, () -> {
951 // arrange for first provider to throw exceptions
952 when(prov1.beforeLock(mgr)).thenThrow(new RuntimeException(EXPECTED));
953 when(prov1.afterLock(mgr)).thenThrow(new RuntimeException(EXPECTED));
956 // already locked - shouldn't run anything besides beforeLock()
958 mgr.configure(properties);
960 assertTrue(mgr.lock());
961 verify(prov1, times(2)).beforeLock(mgr);
962 verify(prov2, times(2)).beforeLock(mgr);
963 verify(controller).lock();
964 verify(controller2).lock();
965 verify(endpoint).lock();
966 verify(prov1).afterLock(mgr);
967 verify(prov2).afterLock(mgr);
969 // controller fails to lock - still does everything
970 testLock(false, () -> when(controller.lock()).thenReturn(false));
972 // controller throws an exception - still does everything
973 testLock(false, () -> when(controller.lock()).thenThrow(new RuntimeException(EXPECTED)));
975 // endpoint manager fails to lock - still does everything
976 testLock(false, () -> when(endpoint.lock()).thenReturn(false));
980 (prov, flag) -> when(prov.beforeLock(mgr)).thenReturn(flag),
981 (prov, flag) -> when(prov.afterLock(mgr)).thenReturn(flag),
983 mgr.configure(properties);
985 assertTrue(mgr.lock());
987 prov -> verify(prov).beforeLock(mgr),
988 () -> verify(endpoint).lock(),
989 prov -> verify(prov).afterLock(mgr));
993 * Tests the lock() method, after setting some option.
995 * @param expectedResult what lock() is expected to return
996 * @param setOption function that sets an option
997 * @throws Throwable if an error occurs during setup
999 private void testLock(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
1003 mgr.configure(properties);
1004 assertEquals(expectedResult, mgr.lock());
1006 verify(prov1).beforeLock(mgr);
1007 verify(prov2).beforeLock(mgr);
1009 verify(controller).lock();
1010 verify(controller2).lock();
1012 verify(endpoint).lock();
1014 verify(prov1).afterLock(mgr);
1015 verify(prov2).afterLock(mgr);
1019 public void testUnlock() throws Throwable {
1020 // normal success case
1021 testUnlock(true, () -> {
1022 // arrange for first provider to throw exceptions
1023 when(prov1.beforeUnlock(mgr)).thenThrow(new RuntimeException(EXPECTED));
1024 when(prov1.afterUnlock(mgr)).thenThrow(new RuntimeException(EXPECTED));
1027 // not locked - shouldn't run anything besides beforeUnlock()
1029 mgr.configure(properties);
1030 assertTrue(mgr.unlock());
1031 verify(prov1).beforeUnlock(mgr);
1032 verify(prov2).beforeUnlock(mgr);
1033 verify(controller, never()).unlock();
1034 verify(controller2, never()).unlock();
1035 verify(endpoint, never()).unlock();
1036 verify(prov1, never()).afterUnlock(mgr);
1037 verify(prov2, never()).afterUnlock(mgr);
1039 // controller fails to unlock - still does everything
1040 testUnlock(false, () -> when(controller.unlock()).thenReturn(false));
1042 // controller throws an exception - still does everything
1043 testUnlock(false, () -> when(controller.unlock()).thenThrow(new RuntimeException(EXPECTED)));
1045 // endpoint manager fails to unlock - still does everything
1046 testUnlock(false, () -> when(endpoint.unlock()).thenReturn(false));
1050 (prov, flag) -> when(prov.beforeUnlock(mgr)).thenReturn(flag),
1051 (prov, flag) -> when(prov.afterUnlock(mgr)).thenReturn(flag),
1053 mgr.configure(properties);
1055 assertTrue(mgr.unlock());
1057 prov -> verify(prov).beforeUnlock(mgr),
1058 () -> verify(endpoint).unlock(),
1059 prov -> verify(prov).afterUnlock(mgr));
1063 * Tests the unlock() method, after setting some option.
1065 * @param expectedResult what unlock() is expected to return
1066 * @param setOption function that sets an option
1067 * @throws Throwable if an error occurs during setup
1069 private void testUnlock(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
1073 mgr.configure(properties);
1075 assertEquals(expectedResult, mgr.unlock());
1077 verify(prov1).beforeUnlock(mgr);
1078 verify(prov2).beforeUnlock(mgr);
1080 verify(controller).unlock();
1081 verify(controller2).unlock();
1083 verify(endpoint).unlock();
1085 verify(prov1).afterUnlock(mgr);
1086 verify(prov2).afterUnlock(mgr);
1090 public void testIsLocked() {
1091 mgr.configure(properties);
1092 assertFalse(mgr.isLocked());
1095 assertTrue(mgr.isLocked());
1098 assertFalse(mgr.isLocked());
1102 public void testRemovePolicyControllerString() {
1103 mgr.removePolicyController(MY_NAME);
1105 verify(controllerFactory).destroy(MY_NAME);
1109 public void testRemovePolicyControllerPolicyController() {
1110 mgr.removePolicyController(controller);
1112 verify(controllerFactory).destroy(controller);
1116 public void testGetPolicyControllers() {
1117 assertEquals(controllers, mgr.getPolicyControllers());
1121 public void testGetPolicyControllerIds() {
1122 assertEquals(Arrays.asList(CONTROLLER1, CONTROLLER2), mgr.getPolicyControllerIds());
1126 public void testGetProperties() {
1127 properties.setProperty("prop-x", "value-x");
1128 properties.setProperty("prop-y", "value-y");
1130 mgr.configure(properties);
1131 assertEquals(properties, mgr.getProperties());
1135 public void testGetSources() {
1136 mgr.configure(properties);
1137 assertEquals(sources, mgr.getSources());
1141 public void testGetSinks() {
1142 mgr.configure(properties);
1143 assertEquals(sinks, mgr.getSinks());
1147 public void testGetHttpServers() {
1148 mgr.configure(properties);
1149 assertEquals(servers, mgr.getHttpServers());
1153 public void testGetFeatures() {
1154 assertEquals(Arrays.asList(FEATURE1, FEATURE2), mgr.getFeatures());
1158 public void testGetFeatureProviders() {
1159 assertEquals(providers, mgr.getFeatureProviders());
1163 public void testGetFeatureProvider() {
1164 assertEquals(prov1, mgr.getFeatureProvider(FEATURE1));
1165 assertEquals(prov2, mgr.getFeatureProvider(FEATURE2));
1168 assertThatIllegalArgumentException().isThrownBy(() -> mgr.getFeatureProvider(null));
1171 assertThatIllegalArgumentException().isThrownBy(() -> mgr.getFeatureProvider(""));
1174 assertThatIllegalArgumentException().isThrownBy(() -> mgr.getFeatureProvider("unknown-feature"));
1178 public void testOnTopicEvent() {
1179 mgr.onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, pdpConfigJson);
1181 verify(controllerFactory).patch(controller3, drools3);
1182 verify(controllerFactory).patch(controller4, drools4);
1184 // null json - no additional patches
1185 mgr.onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, null);
1187 verify(controllerFactory).patch(controller3, drools3);
1188 verify(controllerFactory).patch(controller4, drools4);
1192 public void testDeliverStringObject() throws Exception {
1193 mgr.configure(properties);
1196 assertTrue(mgr.deliver(MY_TOPIC, MY_EVENT));
1198 verify(sink1).send(MESSAGE);
1200 // invalid parameters
1201 String nullStr = null;
1202 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(nullStr, MY_EVENT));
1203 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver("", MY_EVENT));
1205 Object nullObj = null;
1206 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(MY_TOPIC, nullObj));
1210 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1215 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1217 // issues with topic
1219 mgr.configure(properties);
1223 when(endpoint.getTopicSinks(MY_TOPIC)).thenReturn(null);
1224 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1227 when(endpoint.getTopicSinks(MY_TOPIC)).thenReturn(Collections.emptyList());
1228 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1231 when(endpoint.getTopicSinks(MY_TOPIC)).thenReturn(sinks);
1232 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1236 public void testDeliverStringStringObject() {
1237 mgr.configure(properties);
1240 assertTrue(mgr.deliver(NOOP_STR, MY_TOPIC, MY_EVENT));
1242 verify(sink1).send(MESSAGE);
1244 // invalid parameters
1245 String nullStr = null;
1246 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(nullStr, MY_TOPIC, MY_EVENT));
1247 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver("", MY_TOPIC, MY_EVENT));
1248 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver("unknown-bus-type", MY_TOPIC, MY_EVENT));
1250 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(NOOP_STR, nullStr, MY_EVENT));
1251 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(NOOP_STR, "", MY_EVENT));
1253 Object nullObj = null;
1254 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(NOOP_STR, MY_TOPIC, nullObj));
1258 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(NOOP_STR, MY_TOPIC, MY_EVENT));
1263 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(NOOP_STR, MY_TOPIC, MY_EVENT));
1267 public void testDeliverCommInfrastructureStringObject() throws Exception {
1268 mgr.configure(properties);
1271 assertTrue(mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1273 verify(controller, never()).deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT);
1275 verify(coder).encode(MY_TOPIC, MY_EVENT);
1276 verify(sink1).send(MESSAGE);
1278 // invalid parameters
1279 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, null, MY_EVENT));
1280 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, "", MY_EVENT));
1282 Object nullObj = null;
1283 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, nullObj));
1287 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1292 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1294 // send() throws an exception
1296 mgr.configure(properties);
1298 when(sink1.send(any())).thenThrow(new ArithmeticException(EXPECTED));
1299 assertThatThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT))
1300 .isInstanceOf(ArithmeticException.class);
1303 * For remaining tests, have the controller handle delivery.
1306 mgr.configure(properties);
1308 DroolsController drools = mock(DroolsController.class);
1309 when(coder.getDroolsController(MY_TOPIC, MY_EVENT)).thenReturn(drools);
1310 when(controllerFactory.get(drools)).thenReturn(controller);
1311 when(controller.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT)).thenReturn(true);
1313 assertTrue(mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1315 verify(controller).deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT);
1317 verify(coder, never()).encode(MY_TOPIC, MY_EVENT);
1318 verify(sink1, never()).send(MESSAGE);
1320 // controller throws exception, so should drop into regular handling
1321 when(controller.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT)).thenThrow(new RuntimeException(EXPECTED));
1323 assertTrue(mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1325 // should have attempted this again
1326 verify(controller, times(2)).deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT);
1328 // now these should have been called
1329 verify(coder).encode(MY_TOPIC, MY_EVENT);
1330 verify(sink1).send(MESSAGE);
1334 public void testDeliverCommInfrastructureStringString() {
1335 mgr.configure(properties);
1338 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MESSAGE));
1343 assertTrue(mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MESSAGE));
1344 verify(sink1).send(MESSAGE);
1345 verify(sink2, never()).send(any());
1347 // invalid parameters
1348 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, null, MESSAGE));
1349 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, "", MESSAGE));
1351 String nullStr = null;
1352 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, nullStr));
1353 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, ""));
1356 assertThatIllegalStateException()
1357 .isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, "unknown-topic", MESSAGE));
1361 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MESSAGE));
1366 public void testActivate() throws Throwable {
1367 // normal success case
1368 testActivate(() -> {
1369 // arrange for first provider and controller to throw exceptions
1370 when(prov1.beforeActivate(mgr)).thenThrow(new RuntimeException(EXPECTED));
1371 when(prov1.afterActivate(mgr)).thenThrow(new RuntimeException(EXPECTED));
1372 when(controller.start()).thenThrow(new RuntimeException(EXPECTED));
1375 // controller generates linkage error
1376 testActivate(() -> when(controller.start()).thenThrow(new LinkageError(EXPECTED)));
1380 (prov, flag) -> when(prov.beforeActivate(mgr)).thenReturn(flag),
1381 (prov, flag) -> when(prov.afterActivate(mgr)).thenReturn(flag),
1383 mgr.configure(properties);
1387 prov -> verify(prov).beforeActivate(mgr),
1388 () -> assertFalse(mgr.isLocked()),
1389 prov -> verify(prov).afterActivate(mgr));
1393 * Tests the activate() method, after setting some option.
1395 * @param setOption function that sets an option
1396 * @throws Throwable if an error occurs during setup
1398 private void testActivate(RunnableWithEx setOption) throws Throwable {
1402 mgr.configure(properties);
1406 verify(prov1).beforeActivate(mgr);
1407 verify(prov2).beforeActivate(mgr);
1409 // unlocked by activate() AND by unlock() (which is invoked by activate())
1410 verify(controller, times(2)).unlock();
1411 verify(controller2, times(2)).unlock();
1413 verify(controller).start();
1414 verify(controller2).start();
1416 assertFalse(mgr.isLocked());
1418 verify(prov1).afterActivate(mgr);
1419 verify(prov2).afterActivate(mgr);
1423 public void testDeactivate() throws Throwable {
1424 // normal success case
1425 testDeactivate(() -> {
1426 // arrange for first provider and controller to throw exceptions
1427 when(prov1.beforeDeactivate(mgr)).thenThrow(new RuntimeException(EXPECTED));
1428 when(prov1.afterDeactivate(mgr)).thenThrow(new RuntimeException(EXPECTED));
1429 when(controller.stop()).thenThrow(new RuntimeException(EXPECTED));
1432 // controller generates linkage error
1433 testDeactivate(() -> when(controller.stop()).thenThrow(new LinkageError(EXPECTED)));
1437 (prov, flag) -> when(prov.beforeDeactivate(mgr)).thenReturn(flag),
1438 (prov, flag) -> when(prov.afterDeactivate(mgr)).thenReturn(flag),
1440 mgr.configure(properties);
1443 prov -> verify(prov).beforeDeactivate(mgr),
1444 () -> assertTrue(mgr.isLocked()),
1445 prov -> verify(prov).afterDeactivate(mgr));
1449 * Tests the deactivate() method, after setting some option.
1451 * @param setOption function that sets an option
1452 * @throws Throwable if an error occurs during setup
1454 private void testDeactivate(RunnableWithEx setOption) throws Throwable {
1458 mgr.configure(properties);
1461 verify(prov1).beforeDeactivate(mgr);
1462 verify(prov2).beforeDeactivate(mgr);
1464 verify(controller).lock();
1465 verify(controller2).lock();
1467 verify(controller).stop();
1468 verify(controller2).stop();
1470 assertTrue(mgr.isLocked());
1472 verify(prov1).afterDeactivate(mgr);
1473 verify(prov2).afterDeactivate(mgr);
1477 public void testControllerConfig() throws Exception {
1478 mgr.configure(properties);
1479 assertTrue(mgr.configure(pdpConfig));
1481 verify(controllerFactory).patch(controller3, drools3);
1482 verify(controllerFactory).patch(controller4, drools4);
1484 // empty controllers
1485 pdpConfig.getControllers().clear();
1486 assertFalse(mgr.configure(pdpConfig));
1489 pdpConfig.setControllers(null);
1490 assertFalse(mgr.configure(pdpConfig));
1492 // arrange for controller3 to fail
1494 config3.setOperation("fail-3");
1495 assertFalse(mgr.configure(pdpConfig));
1497 verify(controllerFactory, never()).patch(controller3, drools3);
1498 verify(controllerFactory).patch(controller4, drools4);
1500 // arrange for both controllers to fail
1502 config3.setOperation("fail-3");
1503 config4.setOperation("fail-4");
1504 assertFalse(mgr.configure(pdpConfig));
1508 public void testToString() {
1509 assertTrue(mgr.toString().startsWith("PolicyEngineManager ["));
1513 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries
1514 * combinations where beforeXxx and afterXxx return {@code true} and {@code false}.
1516 * @param setBefore function to set the return value of a provider's beforeXxx method
1517 * @param setAfter function to set the return value of a provider's afterXxx method
1518 * @param action invokes the operation
1519 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
1520 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
1521 * and the afterXxx loop was invoked
1522 * @param verifyAfter verifies that a provider's afterXxx method was invoked
1523 * @throws Exception if an error occurs while calling {@link #setUp()}
1525 private void checkBeforeAfter(BiConsumer<PolicyEngineFeatureAPI, Boolean> setBefore,
1526 BiConsumer<PolicyEngineFeatureAPI, Boolean> setAfter, Runnable action,
1527 Consumer<PolicyEngineFeatureAPI> verifyBefore, Runnable verifyMiddle,
1528 Consumer<PolicyEngineFeatureAPI> verifyAfter) throws Exception {
1530 checkBeforeAfter_FalseFalse(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
1531 checkBeforeAfter_FalseTrue(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
1532 checkBeforeAfter_TrueFalse(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
1534 // don't need to test true-true, as it's behavior is a subset of true-false
1538 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
1539 * case where both the beforeXxx and afterXxx methods return {@code false}.
1541 * @param setBefore function to set the return value of a provider's beforeXxx method
1542 * @param setAfter function to set the return value of a provider's afterXxx method
1543 * @param action invokes the operation
1544 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
1545 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
1546 * and the afterXxx loop was invoked
1547 * @param verifyAfter verifies that a provider's afterXxx method was invoked
1548 * @throws Exception if an error occurs while calling {@link #setUp()}
1550 private void checkBeforeAfter_FalseFalse(BiConsumer<PolicyEngineFeatureAPI, Boolean> setBefore,
1551 BiConsumer<PolicyEngineFeatureAPI, Boolean> setAfter, Runnable action,
1552 Consumer<PolicyEngineFeatureAPI> verifyBefore, Runnable verifyMiddle,
1553 Consumer<PolicyEngineFeatureAPI> verifyAfter) throws Exception {
1557 // configure for the test
1558 setBefore.accept(prov1, false);
1559 setBefore.accept(prov2, false);
1561 setAfter.accept(prov1, false);
1562 setAfter.accept(prov2, false);
1567 // verify that various methods were invoked
1568 verifyBefore.accept(prov1);
1569 verifyBefore.accept(prov2);
1573 verifyAfter.accept(prov1);
1574 verifyAfter.accept(prov2);
1578 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
1579 * case where the first provider's afterXxx returns {@code true}, while the others
1580 * return {@code false}.
1582 * @param setBefore function to set the return value of a provider's beforeXxx method
1583 * @param setAfter function to set the return value of a provider's afterXxx method
1584 * @param action invokes the operation
1585 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
1586 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
1587 * and the afterXxx loop was invoked
1588 * @param verifyAfter verifies that a provider's afterXxx method was invoked
1589 * @throws Exception if an error occurs while calling {@link #setUp()}
1591 private void checkBeforeAfter_FalseTrue(BiConsumer<PolicyEngineFeatureAPI, Boolean> setBefore,
1592 BiConsumer<PolicyEngineFeatureAPI, Boolean> setAfter, Runnable action,
1593 Consumer<PolicyEngineFeatureAPI> verifyBefore, Runnable verifyMiddle,
1594 Consumer<PolicyEngineFeatureAPI> verifyAfter) throws Exception {
1598 // configure for the test
1599 setBefore.accept(prov1, false);
1600 setBefore.accept(prov2, false);
1602 setAfter.accept(prov1, true);
1603 setAfter.accept(prov2, false);
1608 // verify that various methods were invoked
1609 verifyBefore.accept(prov1);
1610 verifyBefore.accept(prov2);
1614 verifyAfter.accept(prov1);
1615 assertThatThrownBy(() -> verifyAfter.accept(prov2)).isInstanceOf(AssertionError.class);
1619 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
1620 * case where the first provider's beforeXxx returns {@code true}, while the others
1621 * return {@code false}.
1623 * @param setBefore function to set the return value of a provider's beforeXxx method
1624 * @param setAfter function to set the return value of a provider's afterXxx method
1625 * @param action invokes the operation
1626 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
1627 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
1628 * and the afterXxx loop was invoked
1629 * @param verifyAfter verifies that a provider's afterXxx method was invoked
1630 * @throws Exception if an error occurs while calling {@link #setUp()}
1632 private void checkBeforeAfter_TrueFalse(BiConsumer<PolicyEngineFeatureAPI, Boolean> setBefore,
1633 BiConsumer<PolicyEngineFeatureAPI, Boolean> setAfter, Runnable action,
1634 Consumer<PolicyEngineFeatureAPI> verifyBefore, Runnable verifyMiddle,
1635 Consumer<PolicyEngineFeatureAPI> verifyAfter) throws Exception {
1639 // configure for the test
1640 setBefore.accept(prov1, true);
1641 setBefore.accept(prov2, false);
1643 setAfter.accept(prov1, false);
1644 setAfter.accept(prov2, false);
1649 // verify that various methods were invoked
1650 verifyBefore.accept(prov1);
1652 // remaining methods should not have been invoked
1653 assertThatThrownBy(() -> verifyBefore.accept(prov2)).isInstanceOf(AssertionError.class);
1655 assertThatThrownBy(() -> verifyMiddle.run()).isInstanceOf(AssertionError.class);
1657 assertThatThrownBy(() -> verifyAfter.accept(prov1)).isInstanceOf(AssertionError.class);
1658 assertThatThrownBy(() -> verifyAfter.accept(prov2)).isInstanceOf(AssertionError.class);
1662 * Manager with overrides.
1664 private class PolicyEngineManagerImpl extends PolicyEngineManager {
1667 protected List<PolicyEngineFeatureAPI> getEngineProviders() {
1672 protected List<PolicyControllerFeatureAPI> getControllerProviders() {
1673 return contProviders;
1677 protected void globalInitContainer(String[] cliArgs) {
1678 globalInitArgs = cliArgs;
1682 protected TopicEndpoint getTopicEndpointManager() {
1687 protected HttpServletServerFactory getServletFactory() {
1688 return serverFactory;
1692 protected PolicyControllerFactory getControllerFactory() {
1693 return controllerFactory;
1697 protected void startPdpJmxListener() {
1702 protected void stopPdpJmxListener() {
1707 protected Thread makeShutdownThread() {
1708 shutdownThread = new MyShutdown();
1709 return shutdownThread;
1713 protected EventProtocolCoder getProtocolCoder() {
1718 protected SystemPersistence getPersistenceManager() {
1723 protected PolicyEngine getPolicyEngine() {
1728 * Shutdown thread with overrides.
1730 private class MyShutdown extends ShutdownThread {
1733 protected void doSleep(long sleepMs) throws InterruptedException {
1734 threadSleepMs = sleepMs;
1736 if (shouldInterrupt) {
1737 throw new InterruptedException(EXPECTED);
1742 protected void doExit(int code) {
1743 threadExitCode = code;
1747 public synchronized void start() {
1748 threadStarted = true;
1752 public void interrupt() {
1753 threadInterrupted = true;
1758 @FunctionalInterface
1759 private static interface RunnableWithEx {
1760 void run() throws Exception;