2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2018-2022 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2023-2024 Nordix Foundation.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.drools.system;
24 import static org.assertj.core.api.Assertions.assertThatCode;
25 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
26 import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
27 import static org.assertj.core.api.Assertions.assertThatThrownBy;
28 import static org.junit.jupiter.api.Assertions.assertEquals;
29 import static org.junit.jupiter.api.Assertions.assertFalse;
30 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
31 import static org.junit.jupiter.api.Assertions.assertNotNull;
32 import static org.junit.jupiter.api.Assertions.assertNull;
33 import static org.junit.jupiter.api.Assertions.assertSame;
34 import static org.junit.jupiter.api.Assertions.assertTrue;
35 import static org.mockito.ArgumentMatchers.any;
36 import static org.mockito.ArgumentMatchers.anyLong;
37 import static org.mockito.Mockito.doThrow;
38 import static org.mockito.Mockito.mock;
39 import static org.mockito.Mockito.never;
40 import static org.mockito.Mockito.spy;
41 import static org.mockito.Mockito.times;
42 import static org.mockito.Mockito.verify;
43 import static org.mockito.Mockito.when;
45 import io.prometheus.client.CollectorRegistry;
46 import io.prometheus.client.Summary;
47 import java.util.Arrays;
48 import java.util.Collections;
49 import java.util.List;
50 import java.util.Properties;
51 import java.util.concurrent.ScheduledExecutorService;
52 import java.util.function.BiConsumer;
53 import java.util.function.Consumer;
54 import org.junit.jupiter.api.AfterEach;
55 import org.junit.jupiter.api.BeforeEach;
56 import org.junit.jupiter.api.Test;
57 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
58 import org.onap.policy.common.endpoints.event.comm.TopicEndpoint;
59 import org.onap.policy.common.endpoints.event.comm.TopicSink;
60 import org.onap.policy.common.endpoints.event.comm.TopicSource;
61 import org.onap.policy.common.endpoints.http.client.HttpClient;
62 import org.onap.policy.common.endpoints.http.client.HttpClientFactory;
63 import org.onap.policy.common.endpoints.http.server.HttpServletServer;
64 import org.onap.policy.common.endpoints.http.server.HttpServletServerFactory;
65 import org.onap.policy.common.utils.gson.GsonTestUtils;
66 import org.onap.policy.drools.controller.DroolsController;
67 import org.onap.policy.drools.core.lock.Lock;
68 import org.onap.policy.drools.core.lock.LockCallback;
69 import org.onap.policy.drools.core.lock.PolicyResourceLockManager;
70 import org.onap.policy.drools.features.PolicyControllerFeatureApi;
71 import org.onap.policy.drools.features.PolicyEngineFeatureApi;
72 import org.onap.policy.drools.metrics.Metric;
73 import org.onap.policy.drools.persistence.SystemPersistence;
74 import org.onap.policy.drools.properties.DroolsPropertyConstants;
75 import org.onap.policy.drools.protocol.coders.EventProtocolCoder;
76 import org.onap.policy.drools.protocol.configuration.ControllerConfiguration;
77 import org.onap.policy.drools.protocol.configuration.DroolsConfiguration;
78 import org.onap.policy.drools.protocol.configuration.PdpdConfiguration;
79 import org.onap.policy.drools.stats.PolicyStatsManager;
80 import org.onap.policy.drools.system.internal.SimpleLockManager;
81 import org.onap.policy.drools.system.internal.SimpleLockProperties;
82 import org.onap.policy.models.pdp.enums.PdpResponseStatus;
84 class PolicyEngineManagerTest {
85 private static final String EXPECTED = "expected exception";
87 private static final String NOOP_STR = CommInfrastructure.NOOP.name();
88 private static final String MY_NAME = "my-name";
89 private static final String CONTROLLER1 = "controller-a";
90 private static final String CONTROLLER2 = "controller-b";
91 private static final String CONTROLLER3 = "controller-c";
92 private static final String CONTROLLER4 = "controller-d";
93 private static final String FEATURE1 = "feature-a";
94 private static final String FEATURE2 = "feature-b";
95 private static final String MY_TOPIC = "my-topic";
96 private static final String MESSAGE = "my-message";
97 private static final String MY_OWNER = "my-owner";
98 private static final String MY_RESOURCE = "my-resource";
99 private static final String POLICY = "policy";
100 private static final String CONTROLLOOP = "controlloop";
102 private static final Object MY_EVENT = new Object();
104 private static final GsonTestUtils gson = new GsonMgmtTestBuilder().addTopicSourceMock().addTopicSinkMock()
105 .addHttpServletServerMock().build();
107 private Properties properties;
108 private PolicyEngineFeatureApi prov1;
109 private PolicyEngineFeatureApi prov2;
110 private List<PolicyEngineFeatureApi> providers;
111 private PolicyControllerFeatureApi contProv1;
112 private PolicyControllerFeatureApi contProv2;
113 private List<PolicyControllerFeatureApi> contProviders;
114 private String[] globalInitArgs;
115 private TopicSource source1;
116 private TopicSource source2;
117 private List<TopicSource> sources;
118 private TopicSink sink1;
119 private TopicSink sink2;
120 private List<TopicSink> sinks;
121 private HttpServletServer server1;
122 private HttpServletServer server2;
123 private List<HttpServletServer> servers;
124 private HttpServletServerFactory serverFactory;
125 private HttpClientFactory clientFactory;
126 private HttpClient client1;
127 private HttpClient client2;
128 private TopicEndpoint endpoint;
129 private PolicyController controller;
130 private PolicyController controller2;
131 private PolicyController controller3;
132 private PolicyController controller4;
133 private List<PolicyController> controllers;
134 private PolicyControllerFactory controllerFactory;
135 private boolean jmxStarted;
136 private boolean jmxStopped;
137 private long threadSleepMs;
138 private int threadExitCode;
139 private boolean threadStarted;
140 private boolean threadInterrupted;
141 private Thread shutdownThread;
142 private boolean shouldInterrupt;
143 private EventProtocolCoder coder;
144 private SystemPersistence persist;
145 private PolicyEngine engine;
146 private DroolsConfiguration drools3;
147 private DroolsConfiguration drools4;
148 private ControllerConfiguration config3;
149 private ControllerConfiguration config4;
150 private PdpdConfiguration pdpConfig;
151 private String pdpConfigJson;
152 private PolicyEngineManager mgr;
153 private ScheduledExecutorService exsvc;
154 private PolicyResourceLockManager lockmgr;
155 private PolicyStatsManager statsManager;
158 * Initializes the object to be tested.
160 * @throws Exception if an error occurs
163 public void setUp() throws Exception {
164 CollectorRegistry.defaultRegistry.clear();
165 properties = new Properties();
166 prov1 = mock(PolicyEngineFeatureApi.class);
167 prov2 = mock(PolicyEngineFeatureApi.class);
168 providers = Arrays.asList(prov1, prov2);
169 contProv1 = mock(PolicyControllerFeatureApi.class);
170 contProv2 = mock(PolicyControllerFeatureApi.class);
171 contProviders = Arrays.asList(contProv1, contProv2);
172 globalInitArgs = null;
173 source1 = mock(TopicSource.class);
174 source2 = mock(TopicSource.class);
175 sources = Arrays.asList(source1, source2);
176 sink1 = mock(TopicSink.class);
177 sink2 = mock(TopicSink.class);
178 sinks = Arrays.asList(sink1, sink2);
179 server1 = mock(HttpServletServer.class);
180 server2 = mock(HttpServletServer.class);
181 servers = Arrays.asList(server1, server2);
182 serverFactory = mock(HttpServletServerFactory.class);
183 client1 = mock(HttpClient.class);
184 client2 = mock(HttpClient.class);
185 clientFactory = mock(HttpClientFactory.class);
186 endpoint = mock(TopicEndpoint.class);
187 controller = mock(PolicyController.class);
188 controller2 = mock(PolicyController.class);
189 controller3 = mock(PolicyController.class);
190 controller4 = mock(PolicyController.class);
191 // do NOT include controller3 or controller4 in the list
192 controllers = Arrays.asList(controller, controller2);
193 controllerFactory = mock(PolicyControllerFactory.class);
198 threadStarted = false;
199 threadInterrupted = false;
200 shutdownThread = null;
201 shouldInterrupt = false;
202 coder = mock(EventProtocolCoder.class);
203 persist = mock(SystemPersistence.class);
204 engine = mock(PolicyEngine.class);
205 drools3 = new DroolsConfiguration();
206 drools4 = new DroolsConfiguration();
207 config3 = new ControllerConfiguration();
208 config4 = new ControllerConfiguration();
209 pdpConfig = new PdpdConfiguration();
210 exsvc = mock(ScheduledExecutorService.class);
211 lockmgr = mock(PolicyResourceLockManager.class);
212 statsManager = new PolicyStatsManager();
213 statsManager.getGroupStat().setBirthTime(0L);
215 when(lockmgr.start()).thenReturn(true);
216 when(lockmgr.stop()).thenReturn(true);
217 when(lockmgr.lock()).thenReturn(true);
218 when(lockmgr.unlock()).thenReturn(true);
220 when(prov2.beforeCreateLockManager()).thenReturn(lockmgr);
222 when(prov1.getName()).thenReturn(FEATURE1);
223 when(prov2.getName()).thenReturn(FEATURE2);
225 when(controllerFactory.build(any(), any())).thenReturn(controller);
226 when(controllerFactory.inventory()).thenReturn(controllers);
227 when(controllerFactory.get(CONTROLLER1)).thenReturn(controller);
228 when(controllerFactory.get(CONTROLLER2)).thenReturn(controller2);
229 // do NOT return controller3 or controller4
231 when(server1.getPort()).thenReturn(1001);
232 when(server1.waitedStart(anyLong())).thenReturn(true);
233 when(server1.stop()).thenReturn(true);
235 when(server2.getPort()).thenReturn(1002);
236 when(server2.waitedStart(anyLong())).thenReturn(true);
237 when(server2.stop()).thenReturn(true);
239 when(serverFactory.build(any())).thenReturn(servers);
241 when(client1.getPort()).thenReturn(2001);
242 when(client1.start()).thenReturn(true);
243 when(client1.stop()).thenReturn(true);
245 when(client2.getPort()).thenReturn(2002);
246 when(client2.start()).thenReturn(true);
247 when(client2.stop()).thenReturn(true);
249 when(clientFactory.inventory()).thenReturn(List.of(client1, client2));
251 when(source1.getTopic()).thenReturn("source1-topic");
252 when(source1.start()).thenReturn(true);
253 when(source1.stop()).thenReturn(true);
255 when(source2.getTopic()).thenReturn("source2-topic");
256 when(source2.start()).thenReturn(true);
257 when(source2.stop()).thenReturn(true);
259 when(sink1.getTopic()).thenReturn("sink1-topic");
260 when(sink1.start()).thenReturn(true);
261 when(sink1.stop()).thenReturn(true);
262 when(sink1.send(any())).thenReturn(true);
263 when(sink1.getTopicCommInfrastructure()).thenReturn(CommInfrastructure.NOOP);
265 when(sink2.getTopic()).thenReturn("sink2-topic");
266 when(sink2.start()).thenReturn(true);
267 when(sink2.stop()).thenReturn(true);
269 when(controller.getName()).thenReturn(CONTROLLER1);
270 when(controller.start()).thenReturn(true);
271 when(controller.stop()).thenReturn(true);
272 when(controller.lock()).thenReturn(true);
273 when(controller.unlock()).thenReturn(true);
275 when(controller2.getName()).thenReturn(CONTROLLER2);
276 when(controller2.start()).thenReturn(true);
277 when(controller2.stop()).thenReturn(true);
278 when(controller2.lock()).thenReturn(true);
279 when(controller2.unlock()).thenReturn(true);
281 when(controller3.getName()).thenReturn(CONTROLLER3);
282 when(controller3.start()).thenReturn(true);
283 when(controller3.stop()).thenReturn(true);
284 when(controller3.lock()).thenReturn(true);
285 when(controller3.unlock()).thenReturn(true);
287 when(controller4.getName()).thenReturn(CONTROLLER4);
288 when(controller4.start()).thenReturn(true);
289 when(controller4.stop()).thenReturn(true);
290 when(controller4.lock()).thenReturn(true);
291 when(controller4.unlock()).thenReturn(true);
293 when(endpoint.addTopicSources(any(Properties.class))).thenReturn(sources);
294 when(endpoint.addTopicSinks(any(Properties.class))).thenReturn(sinks);
295 when(endpoint.start()).thenReturn(true);
296 when(endpoint.stop()).thenReturn(true);
297 when(endpoint.lock()).thenReturn(true);
298 when(endpoint.unlock()).thenReturn(true);
299 when(endpoint.getTopicSink(CommInfrastructure.NOOP, MY_TOPIC)).thenReturn(sink1);
300 when(endpoint.getTopicSinks(MY_TOPIC)).thenReturn(Collections.singletonList(sink1));
302 when(coder.encode(any(), any())).thenReturn(MESSAGE);
304 when(persist.getControllerProperties(CONTROLLER3)).thenReturn(properties);
305 when(persist.getControllerProperties(CONTROLLER4)).thenReturn(properties);
307 when(engine.createPolicyController(CONTROLLER3, properties)).thenReturn(controller3);
308 when(engine.createPolicyController(CONTROLLER4, properties)).thenReturn(controller4);
309 when(engine.getStats()).thenReturn(statsManager);
311 config3.setName(CONTROLLER3);
312 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_CREATE);
313 config3.setDrools(drools3);
315 config4.setName(CONTROLLER4);
316 config4.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_UPDATE);
317 config4.setDrools(drools4);
319 pdpConfig.getControllers().add(config3);
320 pdpConfig.getControllers().add(config4);
321 pdpConfig.setEntity(PdpdConfiguration.CONFIG_ENTITY_CONTROLLER);
323 pdpConfigJson = gson.gsonEncode(pdpConfig);
325 mgr = new PolicyEngineManagerImpl();
329 public void tearDown() {
330 CollectorRegistry.defaultRegistry.clear();
334 void testSerialize() {
335 mgr.setHostName("foo");
336 mgr.setClusterName("bar");
337 mgr.configure(properties);
338 assertThatCode(() -> gson.compareGson(mgr, PolicyEngineManagerTest.class)).doesNotThrowAnyException();
343 mgr = new PolicyEngineManager();
345 assertNotNull(mgr.getEngineProviders());
346 assertNotNull(mgr.getControllerProviders());
347 assertNotNull(mgr.getTopicEndpointManager());
348 assertNotNull(mgr.getServletFactory());
349 assertNotNull(mgr.getControllerFactory());
350 assertNotNull(mgr.makeShutdownThread());
351 assertNotNull(mgr.getProtocolCoder());
352 assertNotNull(mgr.getPersistenceManager());
353 assertNotNull(mgr.getPolicyEngine());
357 void testBoot() throws Exception {
358 String[] args = {"boot-a", "boot-b"};
360 // arrange for first provider to throw exceptions
361 when(prov1.beforeBoot(mgr, args)).thenThrow(new RuntimeException(EXPECTED));
362 when(prov1.afterBoot(mgr)).thenThrow(new RuntimeException(EXPECTED));
366 verify(prov1).beforeBoot(mgr, args);
367 verify(prov2).beforeBoot(mgr, args);
369 assertSame(globalInitArgs, args);
371 verify(prov1).afterBoot(mgr);
372 verify(prov2).afterBoot(mgr);
374 // global init throws exception - still calls afterBoot
376 mgr = new PolicyEngineManagerImpl() {
378 protected void globalInitContainer(String[] cliArgs) {
379 throw new RuntimeException(EXPECTED);
383 verify(prov2).afterBoot(mgr);
387 (prov, flag) -> when(prov.beforeBoot(mgr, args)).thenReturn(flag),
388 (prov, flag) -> when(prov.afterBoot(mgr)).thenReturn(flag),
389 () -> mgr.boot(args),
390 prov -> verify(prov).beforeBoot(mgr, args),
391 () -> assertSame(globalInitArgs, args),
392 prov -> verify(prov).afterBoot(mgr));
396 void testSetEnvironment_testGetEnvironment_testGetEnvironmentProperty_setEnvironmentProperty() {
397 Properties props1 = new Properties();
398 props1.put("prop1-a", "value1-a");
399 props1.put("prop1-b", "value1-b");
401 mgr.setEnvironment(props1);
403 Properties env = mgr.getEnvironment();
404 assertEquals(props1, env);
406 // add more properties
407 Properties props2 = new Properties();
408 String propKey = "prop2-a";
409 props2.put(propKey, "value2-a");
410 props2.put("prop2-b", "value2-b");
412 mgr.setEnvironment(props2);
414 assertSame(mgr.getEnvironment(), env);
416 // new env should have a union of the properties
417 props1.putAll(props2);
418 assertEquals(props1, env);
420 assertEquals("value2-a", mgr.getEnvironmentProperty(propKey));
422 String newValue = "new-value";
423 mgr.setEnvironmentProperty(propKey, newValue);
424 assertEquals(newValue, mgr.getEnvironmentProperty(propKey));
426 props1.setProperty(propKey, newValue);
427 assertEquals(props1, env);
429 assertNotNull(mgr.getEnvironmentProperty("PATH"));
430 assertNull(mgr.getEnvironmentProperty("unknown-env-property"));
432 System.setProperty("propS-a", "valueS-a");
433 assertEquals("valueS-a", mgr.getEnvironmentProperty("propS-a"));
435 Properties props3 = new Properties();
436 props3.put("prop3-a", "${env:HOME}");
437 mgr.setEnvironment(props3);
438 assertEquals(System.getenv("HOME"), mgr.getEnvironmentProperty("prop3-a"));
439 assertEquals("valueS-a", mgr.getEnvironmentProperty("propS-a"));
440 assertEquals(newValue, mgr.getEnvironmentProperty(propKey));
444 void testDefaultTelemetryConfig() {
445 Properties config = mgr.defaultTelemetryConfig();
446 assertNotNull(config);
447 assertFalse(config.isEmpty());
451 void testGetPdpName() {
452 properties.setProperty(PolicyEngineManager.CLUSTER_NAME_PROP, "east1");
453 mgr.configure(properties);
455 var pdpName = mgr.getPdpName();
456 assertEquals("east1", extractCluster(pdpName));
457 assertEquals(mgr.getClusterName(), extractCluster(pdpName));
458 assertEquals(mgr.getHostName(), extractHostname(pdpName));
460 mgr.setHostName("foo");
461 mgr.setClusterName("bar");
462 mgr.setPdpName("foo.bar");
464 pdpName = mgr.getPdpName();
465 assertEquals("bar", extractCluster(pdpName));
466 assertEquals(mgr.getClusterName(), extractCluster(pdpName));
467 assertEquals("foo", extractHostname(pdpName));
468 assertEquals(mgr.getHostName(), extractHostname(pdpName));
471 private String extractCluster(String name) {
472 return name.substring(name.lastIndexOf(".") + 1);
475 private String extractHostname(String name) {
476 return name.substring(0, name.lastIndexOf("."));
480 * Tests that makeExecutorService() uses the value from the thread
484 void testMakeExecutorServicePropertyProvided() {
485 PolicyEngineManager mgrspy = spy(mgr);
487 properties.setProperty(PolicyEngineManager.EXECUTOR_THREAD_PROP, "3");
488 mgrspy.configure(properties);
489 assertSame(exsvc, mgrspy.getExecutorService());
490 verify(mgrspy).makeScheduledExecutor(3);
494 * Tests that makeExecutorService() uses the default thread count when no thread
495 * property is provided.
498 void testMakeExecutorServiceNoProperty() {
499 PolicyEngineManager mgrspy = spy(mgr);
501 mgrspy.configure(properties);
502 assertSame(exsvc, mgrspy.getExecutorService());
503 verify(mgrspy).makeScheduledExecutor(PolicyEngineManager.DEFAULT_EXECUTOR_THREADS);
507 * Tests that makeExecutorService() uses the default thread count when the thread
508 * property is invalid.
511 void testMakeExecutorServiceInvalidProperty() {
512 PolicyEngineManager mgrspy = spy(mgr);
514 properties.setProperty(PolicyEngineManager.EXECUTOR_THREAD_PROP, "abc");
515 mgrspy.configure(properties);
516 assertSame(exsvc, mgrspy.getExecutorService());
517 verify(mgrspy).makeScheduledExecutor(PolicyEngineManager.DEFAULT_EXECUTOR_THREADS);
521 * Tests createLockManager() when beforeCreateLock throws an exception and returns a
525 void testCreateLockManagerHaveProvider() {
526 // first provider throws an exception
527 when(prov1.beforeCreateLockManager()).thenThrow(new RuntimeException(EXPECTED));
529 mgr.configure(properties);
530 assertSame(lockmgr, mgr.getLockManager());
534 * Tests createLockManager() when SimpleLockManager throws an exception.
537 void testCreateLockManagerSimpleEx() {
538 when(prov2.beforeCreateLockManager()).thenReturn(null);
540 // invalid property for SimpleLockManager
541 properties.setProperty(SimpleLockProperties.EXPIRE_CHECK_SEC, "abc");
542 mgr.configure(properties);
544 // should create a manager using default properties
545 assertInstanceOf(SimpleLockManager.class, mgr.getLockManager());
549 * Tests createLockManager() when SimpleLockManager is returned.
552 void testCreateLockManagerSimple() {
553 when(prov2.beforeCreateLockManager()).thenReturn(null);
555 mgr.configure(properties);
556 assertInstanceOf(SimpleLockManager.class, mgr.getLockManager());
560 void testConfigureProperties() throws Exception {
561 // arrange for first provider to throw exceptions
562 when(prov1.beforeConfigure(mgr, properties)).thenThrow(new RuntimeException(EXPECTED));
563 when(prov1.afterConfigure(mgr)).thenThrow(new RuntimeException(EXPECTED));
565 mgr.configure(properties);
567 verify(prov1).beforeConfigure(mgr, properties);
568 verify(prov2).beforeConfigure(mgr, properties);
570 assertSame(properties, mgr.getProperties());
572 assertEquals(sources, mgr.getSources());
573 assertEquals(sinks, mgr.getSinks());
574 assertEquals(servers, mgr.getHttpServers());
576 verify(source1).register(mgr);
577 verify(source2).register(mgr);
579 verify(prov1).afterConfigure(mgr);
580 verify(prov2).afterConfigure(mgr);
582 // middle stuff throws exception - still calls afterXxx
584 when(endpoint.addTopicSources(properties)).thenThrow(new IllegalArgumentException(EXPECTED));
585 when(endpoint.addTopicSinks(properties)).thenThrow(new IllegalArgumentException(EXPECTED));
586 when(serverFactory.build(properties)).thenThrow(new IllegalArgumentException(EXPECTED));
587 when(clientFactory.build(properties)).thenThrow(new IllegalArgumentException(EXPECTED));
588 mgr.configure(properties);
589 verify(prov2).afterConfigure(mgr);
591 // null properties - nothing should be invoked
593 Properties nullProps = null;
594 assertThatIllegalArgumentException().isThrownBy(() -> mgr.configure(nullProps));
595 verify(prov1, never()).beforeConfigure(mgr, properties);
596 verify(prov1, never()).afterConfigure(mgr);
600 (prov, flag) -> when(prov.beforeConfigure(mgr, properties)).thenReturn(flag),
601 (prov, flag) -> when(prov.afterConfigure(mgr)).thenReturn(flag),
602 () -> mgr.configure(properties),
603 prov -> verify(prov).beforeConfigure(mgr, properties),
604 () -> assertSame(properties, mgr.getProperties()),
605 prov -> verify(prov).afterConfigure(mgr));
609 void testConfigurePdpdConfiguration() throws Exception {
610 mgr.configure(properties);
611 assertTrue(mgr.configure(pdpConfig));
613 verify(controllerFactory).patch(controller3, drools3);
614 verify(controllerFactory).patch(controller4, drools4);
617 PdpdConfiguration nullConfig = null;
618 assertThatIllegalArgumentException().isThrownBy(() -> mgr.configure(nullConfig));
620 pdpConfig.setEntity("unknown-entity");
621 assertThatIllegalArgumentException().isThrownBy(() -> mgr.configure(pdpConfig));
623 // source list of size 1
625 when(endpoint.addTopicSources(any(Properties.class))).thenReturn(Collections.singletonList(source1));
626 mgr.configure(properties);
627 assertTrue(mgr.configure(pdpConfig));
629 verify(controllerFactory).patch(controller3, drools3);
630 verify(controllerFactory).patch(controller4, drools4);
634 void testCreatePolicyController() throws Exception {
635 assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
637 verify(contProv1).beforeCreate(MY_NAME, properties);
638 verify(contProv2).beforeCreate(MY_NAME, properties);
639 verify(controller, never()).lock();
640 verify(contProv1).afterCreate(controller);
641 verify(contProv2).afterCreate(controller);
643 // first provider throws exceptions - same result
645 when(contProv1.beforeCreate(MY_NAME, properties)).thenThrow(new RuntimeException(EXPECTED));
646 when(contProv1.afterCreate(controller)).thenThrow(new RuntimeException(EXPECTED));
647 assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
649 verify(contProv1).beforeCreate(MY_NAME, properties);
650 verify(contProv2).beforeCreate(MY_NAME, properties);
651 verify(controller, never()).lock();
652 verify(contProv1).afterCreate(controller);
653 verify(contProv2).afterCreate(controller);
655 // locked - same result, but engine locked
658 assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
659 verify(contProv1).beforeCreate(MY_NAME, properties);
660 verify(controller, times(2)).lock();
661 verify(contProv2).afterCreate(controller);
663 // empty name in properties - same result
665 properties.setProperty(DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME, "");
666 assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
667 verify(contProv1).beforeCreate(MY_NAME, properties);
669 // matching name in properties - same result
671 properties.setProperty(DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME, MY_NAME);
672 assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
673 verify(contProv1).beforeCreate(MY_NAME, properties);
675 // mismatching name in properties - nothing should happen besides exception
677 properties.setProperty(DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME, "mistmatched-name");
678 assertThatIllegalStateException().isThrownBy(() -> mgr.createPolicyController(MY_NAME, properties));
679 verify(contProv1, never()).beforeCreate(MY_NAME, properties);
681 // first provider generates controller - stops after first provider
683 when(contProv1.beforeCreate(MY_NAME, properties)).thenReturn(controller2);
684 assertEquals(controller2, mgr.createPolicyController(MY_NAME, properties));
685 verify(contProv1).beforeCreate(MY_NAME, properties);
686 verify(contProv2, never()).beforeCreate(MY_NAME, properties);
687 verify(controller, never()).lock();
688 verify(contProv1, never()).afterCreate(controller);
689 verify(contProv2, never()).afterCreate(controller);
691 // first provider returns true - stops after first provider afterXxx
693 when(contProv1.afterCreate(controller)).thenReturn(true);
694 assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
695 verify(contProv1).beforeCreate(MY_NAME, properties);
696 verify(contProv2).beforeCreate(MY_NAME, properties);
697 verify(contProv1).afterCreate(controller);
698 verify(contProv2, never()).afterCreate(controller);
702 void testUpdatePolicyControllers() throws Exception {
703 assertEquals(Arrays.asList(controller3, controller4), mgr.updatePolicyControllers(pdpConfig.getControllers()));
705 // controller3 was CREATE
706 verify(controllerFactory).patch(controller3, drools3);
707 verify(controller3, never()).lock();
708 verify(controller3, never()).unlock();
710 // controller4 was UPDATE
711 verify(controllerFactory).patch(controller4, drools4);
712 verify(controller4, never()).lock();
713 verify(controller4).unlock();
716 assertTrue(mgr.updatePolicyControllers(null).isEmpty());
717 assertTrue(mgr.updatePolicyControllers(Collections.emptyList()).isEmpty());
719 // force exception in the first controller with invalid operation
721 config3.setOperation("unknown-operation");
722 assertEquals(Collections.singletonList(controller4), mgr.updatePolicyControllers(pdpConfig.getControllers()));
724 // controller3 should NOT have been done
725 verify(controllerFactory, never()).patch(controller3, drools3);
727 // controller4 should still be done
728 verify(controllerFactory).patch(controller4, drools4);
729 verify(controller4, never()).lock();
730 verify(controller4).unlock();
734 void testUpdatePolicyController_Exceptions() throws Exception {
735 assertEquals(controller3, mgr.updatePolicyController(config3));
736 verify(engine).createPolicyController(CONTROLLER3, properties);
738 // invalid parameters
739 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(null));
743 config3.setName(null);
744 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
747 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
751 config3.setOperation(null);
752 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
754 config3.setOperation("");
755 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
757 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_LOCK);
758 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
760 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_UNLOCK);
761 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
763 // exception from get() - should create controller
765 when(controllerFactory.get(CONTROLLER3)).thenThrow(new IllegalArgumentException(EXPECTED));
766 assertEquals(controller3, mgr.updatePolicyController(config3));
767 verify(engine).createPolicyController(CONTROLLER3, properties);
771 when(persist.getControllerProperties(CONTROLLER3)).thenReturn(null);
772 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
774 // throw linkage error
776 when(persist.getControllerProperties(CONTROLLER3)).thenThrow(new LinkageError(EXPECTED));
777 assertThatIllegalStateException().isThrownBy(() -> mgr.updatePolicyController(config3));
781 void testUpdatePolicyController() throws Exception {
783 * For remaining tests, the factory will return the controller instead of creating
787 when(controllerFactory.get(CONTROLLER3)).thenReturn(controller3);
789 assertEquals(controller3, mgr.updatePolicyController(config3));
791 // should NOT have created a new controller
792 verify(engine, never()).createPolicyController(any(), any());
798 // check different operations
800 // CREATE only invokes patch() (note: mgr.update() has already been called)
801 verify(controllerFactory, times(++countPatch)).patch(controller3, drools3);
802 verify(controller3, times(countLock)).lock();
803 verify(controller3, times(countUnlock)).unlock();
805 // UPDATE invokes unlock() and patch()
806 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_UPDATE);
807 assertEquals(controller3, mgr.updatePolicyController(config3));
808 verify(controllerFactory, times(++countPatch)).patch(controller3, drools3);
809 verify(controller3, times(countLock)).lock();
810 verify(controller3, times(++countUnlock)).unlock();
812 // LOCK invokes lock()
813 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_LOCK);
814 assertEquals(controller3, mgr.updatePolicyController(config3));
815 verify(controllerFactory, times(countPatch)).patch(controller3, drools3);
816 verify(controller3, times(++countLock)).lock();
817 verify(controller3, times(countUnlock)).unlock();
819 // UNLOCK invokes unlock()
820 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_UNLOCK);
821 assertEquals(controller3, mgr.updatePolicyController(config3));
822 verify(controllerFactory, times(countPatch)).patch(controller3, drools3);
823 verify(controller3, times(countLock)).lock();
824 verify(controller3, times(++countUnlock)).unlock();
827 config3.setOperation("invalid-operation");
828 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
832 void testStart() throws Throwable {
833 // normal success case
834 testStart(true, () -> {
835 // arrange for first provider, server, source, and sink to throw exceptions
836 when(prov1.beforeStart(mgr)).thenThrow(new RuntimeException(EXPECTED));
837 when(prov1.afterStart(mgr)).thenThrow(new RuntimeException(EXPECTED));
838 when(server1.waitedStart(anyLong())).thenThrow(new RuntimeException(EXPECTED));
839 when(client1.start()).thenThrow(new RuntimeException(EXPECTED));
840 when(source1.start()).thenThrow(new RuntimeException(EXPECTED));
841 when(sink1.start()).thenThrow(new RuntimeException(EXPECTED));
844 // lock manager fails to start - still does everything
845 testStart(false, () -> when(lockmgr.start()).thenReturn(false));
847 // lock manager throws an exception - still does everything
848 testStart(false, () -> when(lockmgr.start()).thenThrow(new RuntimeException(EXPECTED)));
850 // servlet wait fails - still does everything
851 testStart(false, () -> when(server1.waitedStart(anyLong())).thenReturn(false));
853 // client fails - still does everything
854 testStart(false, () -> when(client1.start()).thenReturn(false));
856 // topic source is not started with start
857 testStart(true, () -> when(source1.start()).thenReturn(false));
859 // topic sink is not started with start
860 testStart(true, () -> when(sink1.start()).thenReturn(false));
862 // controller fails to start - still does everything
863 testStart(false, () -> when(controller.start()).thenReturn(false));
865 // controller throws an exception - still does everything
866 testStart(false, () -> when(controller.start()).thenThrow(new RuntimeException(EXPECTED)));
868 // endpoint manager fails to start - still does everything
869 testStart(false, () -> when(endpoint.start()).thenReturn(false));
871 // endpoint manager throws an exception - still does everything AND succeeds
872 testStart(true, () -> when(endpoint.start()).thenThrow(new IllegalStateException(EXPECTED)));
874 // locked - nothing other than beforeXxx methods should be invoked
876 mgr.configure(properties);
878 assertThatIllegalStateException().isThrownBy(() -> mgr.start());
879 verify(prov2).beforeStart(mgr);
880 verify(server2, never()).waitedStart(anyLong());
881 verify(source2, never()).start();
882 verify(sink1, never()).start();
883 verify(controller, never()).start();
884 verify(endpoint, never()).start();
885 assertFalse(jmxStarted);
886 verify(prov1, never()).afterStart(mgr);
890 (prov, flag) -> when(prov.beforeStart(mgr)).thenReturn(flag),
891 (prov, flag) -> when(prov.afterStart(mgr)).thenReturn(flag),
893 mgr.configure(properties);
894 assertTrue(mgr.start());
896 prov -> verify(prov).beforeStart(mgr),
897 () -> assertTrue(jmxStarted),
898 prov -> verify(prov).afterStart(mgr));
902 * Tests the start() method, after setting some option.
904 * @param expectedResult what start() is expected to return
905 * @param setOption function that sets an option
906 * @throws Throwable if an error occurs during setup
908 private void testStart(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
912 mgr.configure(properties);
913 assertEquals(expectedResult, mgr.start());
915 verify(prov1).beforeStart(mgr);
916 verify(prov2).beforeStart(mgr);
918 verify(server1).waitedStart(anyLong());
919 verify(server2).waitedStart(anyLong());
921 verify(client1).start();
922 verify(client2).start();
924 verify(source1, never()).start();
925 verify(source2, never()).start();
927 verify(sink1, never()).start();
928 verify(sink2, never()).start();
930 verify(controller).start();
931 verify(controller2).start();
933 verify(endpoint).start();
935 assertTrue(jmxStarted);
937 verify(prov1).afterStart(mgr);
938 verify(prov2).afterStart(mgr);
942 void testStop() throws Throwable {
943 // normal success case
944 testStop(true, () -> {
945 // arrange for first provider, server, source, and sink to throw exceptions
946 when(prov1.beforeStop(mgr)).thenThrow(new RuntimeException(EXPECTED));
947 when(prov1.afterStop(mgr)).thenThrow(new RuntimeException(EXPECTED));
948 when(server1.stop()).thenThrow(new RuntimeException(EXPECTED));
949 when(client1.stop()).thenThrow(new RuntimeException(EXPECTED));
950 when(source1.stop()).thenThrow(new RuntimeException(EXPECTED));
951 when(sink1.stop()).thenThrow(new RuntimeException(EXPECTED));
954 // not alive - shouldn't run anything besides beforeStop()
956 mgr.configure(properties);
957 assertTrue(mgr.stop());
958 verify(prov1).beforeStop(mgr);
959 verify(prov2).beforeStop(mgr);
962 // controller fails to stop - still does everything
963 testStop(false, () -> when(controller.stop()).thenReturn(false));
965 // controller throws an exception - still does everything
966 testStop(false, () -> when(controller.stop()).thenThrow(new RuntimeException(EXPECTED)));
968 // topic source fails to stop - still does everything
969 testStop(false, () -> when(source1.stop()).thenReturn(false));
971 // topic sink fails to stop - still does everything
972 testStop(false, () -> when(sink1.stop()).thenReturn(false));
974 // endpoint manager fails to stop - still does everything
975 testStop(false, () -> when(endpoint.stop()).thenReturn(false));
977 // servlet fails to stop - still does everything
978 testStop(false, () -> when(server1.stop()).thenReturn(false));
980 // client fails to stop - still does everything
981 testStop(false, () -> when(client1.stop()).thenReturn(false));
983 // lock manager fails to stop - still does everything
984 testStop(false, () -> when(lockmgr.stop()).thenReturn(false));
986 // lock manager throws an exception - still does everything
987 testStop(false, () -> when(lockmgr.stop()).thenThrow(new RuntimeException(EXPECTED)));
991 (prov, flag) -> when(prov.beforeStop(mgr)).thenReturn(flag),
992 (prov, flag) -> when(prov.afterStop(mgr)).thenReturn(flag),
994 mgr.configure(properties);
996 assertTrue(mgr.stop());
998 prov -> verify(prov).beforeStop(mgr),
999 () -> verify(endpoint).stop(),
1000 prov -> verify(prov).afterStop(mgr));
1004 * Tests the stop() method, after setting some option.
1006 * @param expectedResult what stop() is expected to return
1007 * @param setOption function that sets an option
1008 * @throws Throwable if an error occurs during setup
1010 private void testStop(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
1014 mgr.configure(properties);
1016 assertEquals(expectedResult, mgr.stop());
1018 verify(prov1).beforeStop(mgr);
1019 verify(prov2).beforeStop(mgr);
1021 verify(controller).stop();
1022 verify(controller2).stop();
1024 verify(source1).stop();
1025 verify(source2).stop();
1027 verify(sink1).stop();
1028 verify(sink2).stop();
1030 verify(endpoint).stop();
1032 verify(server1).stop();
1033 verify(server2).stop();
1035 verify(client1).stop();
1036 verify(client2).stop();
1038 verify(prov1).afterStop(mgr);
1039 verify(prov2).afterStop(mgr);
1043 void testShutdown() throws Throwable {
1044 // normal success case
1045 testShutdown(() -> {
1046 // arrange for first provider, source, and sink to throw exceptions
1047 when(prov1.beforeShutdown(mgr)).thenThrow(new RuntimeException(EXPECTED));
1048 when(prov1.afterShutdown(mgr)).thenThrow(new RuntimeException(EXPECTED));
1049 doThrow(new RuntimeException(EXPECTED)).when(source1).shutdown();
1050 doThrow(new RuntimeException(EXPECTED)).when(sink1).shutdown();
1053 assertNotNull(shutdownThread);
1054 assertTrue(threadStarted);
1055 assertTrue(threadInterrupted);
1058 // lock manager throws an exception - still does everything
1059 testShutdown(() -> doThrow(new RuntimeException(EXPECTED)).when(lockmgr).shutdown());
1063 (prov, flag) -> when(prov.beforeShutdown(mgr)).thenReturn(flag),
1064 (prov, flag) -> when(prov.afterShutdown(mgr)).thenReturn(flag),
1066 mgr.configure(properties);
1070 prov -> verify(prov).beforeShutdown(mgr),
1071 () -> assertTrue(jmxStopped),
1072 prov -> verify(prov).afterShutdown(mgr));
1076 * Tests the shutdown() method, after setting some option.
1078 * @param setOption function that sets an option
1079 * @throws Throwable if an error occurs during setup
1081 private void testShutdown(RunnableWithEx setOption) throws Throwable {
1085 mgr.configure(properties);
1089 verify(prov1).beforeShutdown(mgr);
1090 verify(prov2).beforeShutdown(mgr);
1092 verify(source1).shutdown();
1093 verify(source2).shutdown();
1095 verify(sink1).shutdown();
1096 verify(sink2).shutdown();
1098 verify(controllerFactory).shutdown();
1099 verify(endpoint).shutdown();
1100 verify(serverFactory).destroy();
1101 verify(clientFactory).destroy();
1103 assertTrue(jmxStopped);
1105 verify(prov1).afterShutdown(mgr);
1106 verify(prov2).afterShutdown(mgr);
1108 verify(exsvc).shutdownNow();
1112 void testShutdownThreadRun() throws Throwable {
1113 // arrange for first server to throw exceptions
1114 testShutdownThreadRun(() -> doThrow(new RuntimeException(EXPECTED)).when(server1).shutdown());
1116 // sleep throws an exception
1117 testShutdownThreadRun(() -> shouldInterrupt = true);
1121 * Tests the ShutdownThread.run() method, after setting some option.
1123 * @param setOption function that sets an option
1124 * @throws Throwable if an error occurs during setup
1126 private void testShutdownThreadRun(RunnableWithEx setOption) throws Throwable {
1130 mgr.configure(properties);
1134 assertNotNull(shutdownThread);
1136 shutdownThread.run();
1138 assertTrue(threadSleepMs >= 0);
1139 assertEquals(0, threadExitCode);
1141 verify(server1).shutdown();
1142 verify(server2).shutdown();
1144 verify(clientFactory).destroy();
1148 void testIsAlive() {
1149 mgr.configure(properties);
1150 assertFalse(mgr.isAlive());
1153 assertTrue(mgr.isAlive());
1156 assertFalse(mgr.isAlive());
1160 void testLock() throws Throwable {
1161 // normal success case
1162 testLock(true, () -> {
1163 // arrange for first provider to throw exceptions
1164 when(prov1.beforeLock(mgr)).thenThrow(new RuntimeException(EXPECTED));
1165 when(prov1.afterLock(mgr)).thenThrow(new RuntimeException(EXPECTED));
1168 // already locked - shouldn't run anything besides beforeLock()
1170 mgr.configure(properties);
1172 assertTrue(mgr.lock());
1173 verify(prov1, times(2)).beforeLock(mgr);
1174 verify(prov2, times(2)).beforeLock(mgr);
1175 verify(controller).lock();
1176 verify(controller2).lock();
1177 verify(endpoint).lock();
1178 verify(prov1).afterLock(mgr);
1179 verify(prov2).afterLock(mgr);
1181 // controller fails to lock - still does everything
1182 testLock(false, () -> when(controller.lock()).thenReturn(false));
1184 // controller throws an exception - still does everything
1185 testLock(false, () -> when(controller.lock()).thenThrow(new RuntimeException(EXPECTED)));
1187 // endpoint manager fails to lock - still does everything
1188 testLock(false, () -> when(endpoint.lock()).thenReturn(false));
1190 // lock manager fails to lock - still does everything
1191 testLock(false, () -> when(lockmgr.lock()).thenReturn(false));
1193 // lock manager throws an exception - still does everything
1194 testLock(false, () -> when(lockmgr.lock()).thenThrow(new RuntimeException(EXPECTED)));
1198 (prov, flag) -> when(prov.beforeLock(mgr)).thenReturn(flag),
1199 (prov, flag) -> when(prov.afterLock(mgr)).thenReturn(flag),
1201 mgr.configure(properties);
1203 assertTrue(mgr.lock());
1205 prov -> verify(prov).beforeLock(mgr),
1206 () -> verify(endpoint).lock(),
1207 prov -> verify(prov).afterLock(mgr));
1211 * Tests the lock() method, after setting some option.
1213 * @param expectedResult what lock() is expected to return
1214 * @param setOption function that sets an option
1215 * @throws Throwable if an error occurs during setup
1217 private void testLock(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
1221 mgr.configure(properties);
1222 assertEquals(expectedResult, mgr.lock());
1224 verify(prov1).beforeLock(mgr);
1225 verify(prov2).beforeLock(mgr);
1227 verify(controller).lock();
1228 verify(controller2).lock();
1230 verify(endpoint).lock();
1232 verify(prov1).afterLock(mgr);
1233 verify(prov2).afterLock(mgr);
1237 void testUnlock() throws Throwable {
1238 // normal success case
1239 testUnlock(true, () -> {
1240 // arrange for first provider to throw exceptions
1241 when(prov1.beforeUnlock(mgr)).thenThrow(new RuntimeException(EXPECTED));
1242 when(prov1.afterUnlock(mgr)).thenThrow(new RuntimeException(EXPECTED));
1245 // not locked - shouldn't run anything besides beforeUnlock()
1247 mgr.configure(properties);
1248 assertTrue(mgr.unlock());
1249 verify(prov1).beforeUnlock(mgr);
1250 verify(prov2).beforeUnlock(mgr);
1251 verify(controller, never()).unlock();
1252 verify(controller2, never()).unlock();
1253 verify(endpoint, never()).unlock();
1254 verify(prov1, never()).afterUnlock(mgr);
1255 verify(prov2, never()).afterUnlock(mgr);
1257 // controller fails to unlock - still does everything
1258 testUnlock(false, () -> when(controller.unlock()).thenReturn(false));
1260 // controller throws an exception - still does everything
1261 testUnlock(false, () -> when(controller.unlock()).thenThrow(new RuntimeException(EXPECTED)));
1263 // endpoint manager fails to unlock - still does everything
1264 testUnlock(false, () -> when(endpoint.unlock()).thenReturn(false));
1266 // lock manager fails to lock - still does everything
1267 testUnlock(false, () -> when(lockmgr.unlock()).thenReturn(false));
1269 // lock manager throws an exception - still does everything
1270 testUnlock(false, () -> when(lockmgr.unlock()).thenThrow(new RuntimeException(EXPECTED)));
1274 (prov, flag) -> when(prov.beforeUnlock(mgr)).thenReturn(flag),
1275 (prov, flag) -> when(prov.afterUnlock(mgr)).thenReturn(flag),
1277 mgr.configure(properties);
1279 assertTrue(mgr.unlock());
1281 prov -> verify(prov).beforeUnlock(mgr),
1282 () -> verify(endpoint).unlock(),
1283 prov -> verify(prov).afterUnlock(mgr));
1287 * Tests the unlock() method, after setting some option.
1289 * @param expectedResult what unlock() is expected to return
1290 * @param setOption function that sets an option
1291 * @throws Throwable if an error occurs during setup
1293 private void testUnlock(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
1297 mgr.configure(properties);
1299 assertEquals(expectedResult, mgr.unlock());
1301 verify(prov1).beforeUnlock(mgr);
1302 verify(prov2).beforeUnlock(mgr);
1304 verify(controller).unlock();
1305 verify(controller2).unlock();
1307 verify(endpoint).unlock();
1309 verify(prov1).afterUnlock(mgr);
1310 verify(prov2).afterUnlock(mgr);
1314 void testIsLocked() {
1315 mgr.configure(properties);
1316 assertFalse(mgr.isLocked());
1319 assertTrue(mgr.isLocked());
1322 assertFalse(mgr.isLocked());
1326 void testRemovePolicyControllerString() {
1327 mgr.removePolicyController(MY_NAME);
1329 verify(controllerFactory).destroy(MY_NAME);
1333 void testRemovePolicyControllerPolicyController() {
1334 mgr.removePolicyController(controller);
1336 verify(controllerFactory).destroy(controller);
1340 void testGetPolicyControllers() {
1341 assertEquals(controllers, mgr.getPolicyControllers());
1345 void testGetPolicyControllerIds() {
1346 assertEquals(Arrays.asList(CONTROLLER1, CONTROLLER2), mgr.getPolicyControllerIds());
1350 void testGetProperties() {
1351 properties.setProperty("prop-x", "value-x");
1352 properties.setProperty("prop-y", "value-y");
1354 mgr.configure(properties);
1355 assertEquals(properties, mgr.getProperties());
1359 void testGetSources() {
1360 mgr.configure(properties);
1361 assertEquals(sources, mgr.getSources());
1365 void testGetSinks() {
1366 mgr.configure(properties);
1367 assertEquals(sinks, mgr.getSinks());
1371 void testGetHttpServers() {
1372 mgr.configure(properties);
1373 assertEquals(servers, mgr.getHttpServers());
1377 void testGetFeatures() {
1378 assertEquals(Arrays.asList(FEATURE1, FEATURE2), mgr.getFeatures());
1382 void testGetFeatureProviders() {
1383 assertEquals(providers, mgr.getFeatureProviders());
1387 void testGetFeatureProvider() {
1388 assertEquals(prov1, mgr.getFeatureProvider(FEATURE1));
1389 assertEquals(prov2, mgr.getFeatureProvider(FEATURE2));
1392 assertThatIllegalArgumentException().isThrownBy(() -> mgr.getFeatureProvider(null));
1395 assertThatIllegalArgumentException().isThrownBy(() -> mgr.getFeatureProvider(""));
1398 assertThatIllegalArgumentException().isThrownBy(() -> mgr.getFeatureProvider("unknown-feature"));
1402 void testTransaction() {
1403 mgr.metric(CONTROLLER1, POLICY, new Metric());
1404 assertEquals(0, mgr.getStats().getGroupStat().getPolicyExecutedCount());
1405 assertEquals(0, mgr.getStats().getSubgroupStats().size());
1407 Metric metric = new Metric();
1408 mgr.transaction(CONTROLLER1, CONTROLLOOP, metric);
1409 assertEquals(1, mgr.getStats().getGroupStat().getPolicyExecutedCount());
1410 assertEquals(1, mgr.getStats().getSubgroupStats().size());
1411 assertEquals(1, mgr.getStats().getSubgroupStats().get(CONTROLLOOP).getPolicyExecutedFailCount());
1413 Summary.Child.Value summary =
1414 PolicyEngineManagerImpl.transLatencySecsSummary
1415 .labels(CONTROLLER1, CONTROLLOOP, POLICY, PdpResponseStatus.FAIL.name()).get();
1417 assertEquals(0, summary.count, 0.0);
1418 assertEquals(0, summary.sum, 0.0);
1420 metric.setServiceInstanceId(POLICY);
1421 metric.setElapsedTime(5000L);
1422 metric.setSuccess(false);
1423 mgr.transaction(CONTROLLER1, CONTROLLOOP, metric);
1426 PolicyEngineManagerImpl.transLatencySecsSummary
1427 .labels(CONTROLLER1, CONTROLLOOP, POLICY, PdpResponseStatus.FAIL.name()).get();
1429 assertEquals(1, summary.count, 0.0);
1430 assertEquals(5, summary.sum, 0.0);
1434 void testOnTopicEvent() {
1435 mgr.onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, pdpConfigJson);
1437 verify(controllerFactory).patch(controller3, drools3);
1438 verify(controllerFactory).patch(controller4, drools4);
1440 // null json - no additional patches
1441 mgr.onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, null);
1443 verify(controllerFactory).patch(controller3, drools3);
1444 verify(controllerFactory).patch(controller4, drools4);
1448 void testDeliverStringObject() throws Exception {
1449 mgr.configure(properties);
1452 assertTrue(mgr.deliver(MY_TOPIC, MY_EVENT));
1454 verify(sink1).send(MESSAGE);
1456 // invalid parameters
1457 String nullStr = null;
1458 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(nullStr, MY_EVENT));
1459 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver("", MY_EVENT));
1461 Object nullObj = null;
1462 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(MY_TOPIC, nullObj));
1466 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1471 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1473 // issues with topic
1475 mgr.configure(properties);
1479 when(endpoint.getTopicSinks(MY_TOPIC)).thenReturn(null);
1480 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1483 when(endpoint.getTopicSinks(MY_TOPIC)).thenReturn(Collections.emptyList());
1484 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1487 when(endpoint.getTopicSinks(MY_TOPIC)).thenReturn(sinks);
1488 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1492 void testDeliverStringStringObject() {
1493 mgr.configure(properties);
1496 assertTrue(mgr.deliver(NOOP_STR, MY_TOPIC, MY_EVENT));
1498 verify(sink1).send(MESSAGE);
1500 // invalid parameters
1501 String nullStr = null;
1502 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(nullStr, MY_TOPIC, MY_EVENT));
1503 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver("", MY_TOPIC, MY_EVENT));
1504 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver("unknown-bus-type", MY_TOPIC, MY_EVENT));
1506 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(NOOP_STR, nullStr, MY_EVENT));
1507 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(NOOP_STR, "", MY_EVENT));
1509 Object nullObj = null;
1510 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(NOOP_STR, MY_TOPIC, nullObj));
1514 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(NOOP_STR, MY_TOPIC, MY_EVENT));
1519 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(NOOP_STR, MY_TOPIC, MY_EVENT));
1523 void testDeliverCommInfrastructureStringObject() throws Exception {
1524 mgr.configure(properties);
1527 assertTrue(mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1529 verify(controller, never()).deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT);
1531 verify(coder).encode(MY_TOPIC, MY_EVENT);
1532 verify(sink1).send(MESSAGE);
1534 // invalid parameters
1535 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, null, MY_EVENT));
1536 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, "", MY_EVENT));
1538 Object nullObj = null;
1539 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, nullObj));
1543 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1548 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1550 // send() throws an exception
1552 mgr.configure(properties);
1554 when(sink1.send(any())).thenThrow(new ArithmeticException(EXPECTED));
1555 assertThatThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT))
1556 .isInstanceOf(ArithmeticException.class);
1559 * For remaining tests, have the controller handle delivery.
1562 mgr.configure(properties);
1564 DroolsController drools = mock(DroolsController.class);
1565 when(coder.getDroolsController(MY_TOPIC, MY_EVENT)).thenReturn(drools);
1566 when(controllerFactory.get(drools)).thenReturn(controller);
1567 when(controller.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT)).thenReturn(true);
1569 assertTrue(mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1571 verify(controller).deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT);
1573 verify(coder, never()).encode(MY_TOPIC, MY_EVENT);
1574 verify(sink1, never()).send(MESSAGE);
1576 // controller throws exception, so should drop into regular handling
1577 when(controller.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT)).thenThrow(new RuntimeException(EXPECTED));
1579 assertTrue(mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1581 // should have attempted this again
1582 verify(controller, times(2)).deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT);
1584 // now these should have been called
1585 verify(coder).encode(MY_TOPIC, MY_EVENT);
1586 verify(sink1).send(MESSAGE);
1590 void testDeliverCommInfrastructureStringString() {
1591 mgr.configure(properties);
1594 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MESSAGE));
1599 assertTrue(mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MESSAGE));
1600 verify(sink1).send(MESSAGE);
1601 verify(sink2, never()).send(any());
1603 // invalid parameters
1604 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, null, MESSAGE));
1605 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, "", MESSAGE));
1607 String nullStr = null;
1608 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, nullStr));
1609 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, ""));
1612 assertThatIllegalStateException()
1613 .isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, "unknown-topic", MESSAGE));
1617 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MESSAGE));
1622 void testActivate() throws Throwable {
1623 // normal success case
1624 testActivate(() -> {
1625 // arrange for first provider and controller to throw exceptions
1626 when(prov1.beforeActivate(mgr)).thenThrow(new RuntimeException(EXPECTED));
1627 when(prov1.afterActivate(mgr)).thenThrow(new RuntimeException(EXPECTED));
1628 when(controller.start()).thenThrow(new RuntimeException(EXPECTED));
1631 // controller generates linkage error
1632 testActivate(() -> when(controller.start()).thenThrow(new LinkageError(EXPECTED)));
1636 (prov, flag) -> when(prov.beforeActivate(mgr)).thenReturn(flag),
1637 (prov, flag) -> when(prov.afterActivate(mgr)).thenReturn(flag),
1639 mgr.configure(properties);
1643 prov -> verify(prov).beforeActivate(mgr),
1644 () -> assertFalse(mgr.isLocked()),
1645 prov -> verify(prov).afterActivate(mgr));
1649 * Tests the activate() method, after setting some option.
1651 * @param setOption function that sets an option
1652 * @throws Throwable if an error occurs during setup
1654 private void testActivate(RunnableWithEx setOption) throws Throwable {
1658 mgr.configure(properties);
1662 verify(prov1).beforeActivate(mgr);
1663 verify(prov2).beforeActivate(mgr);
1665 // unlocked by activate() AND by unlock() (which is invoked by activate())
1666 verify(controller, times(2)).unlock();
1667 verify(controller2, times(2)).unlock();
1669 verify(controller).start();
1670 verify(controller2).start();
1672 assertFalse(mgr.isLocked());
1674 verify(prov1).afterActivate(mgr);
1675 verify(prov2).afterActivate(mgr);
1679 void testDeactivate() throws Throwable {
1680 // normal success case
1681 testDeactivate(() -> {
1682 // arrange for first provider and controller to throw exceptions
1683 when(prov1.beforeDeactivate(mgr)).thenThrow(new RuntimeException(EXPECTED));
1684 when(prov1.afterDeactivate(mgr)).thenThrow(new RuntimeException(EXPECTED));
1685 when(controller.stop()).thenThrow(new RuntimeException(EXPECTED));
1688 // controller generates linkage error
1689 testDeactivate(() -> when(controller.stop()).thenThrow(new LinkageError(EXPECTED)));
1693 (prov, flag) -> when(prov.beforeDeactivate(mgr)).thenReturn(flag),
1694 (prov, flag) -> when(prov.afterDeactivate(mgr)).thenReturn(flag),
1696 mgr.configure(properties);
1699 prov -> verify(prov).beforeDeactivate(mgr),
1700 () -> assertTrue(mgr.isLocked()),
1701 prov -> verify(prov).afterDeactivate(mgr));
1705 * Tests the deactivate() method, after setting some option.
1707 * @param setOption function that sets an option
1708 * @throws Throwable if an error occurs during setup
1710 private void testDeactivate(RunnableWithEx setOption) throws Throwable {
1714 mgr.configure(properties);
1717 verify(prov1).beforeDeactivate(mgr);
1718 verify(prov2).beforeDeactivate(mgr);
1720 verify(controller).lock();
1721 verify(controller2).lock();
1723 verify(controller).stop();
1724 verify(controller2).stop();
1726 assertTrue(mgr.isLocked());
1728 verify(prov1).afterDeactivate(mgr);
1729 verify(prov2).afterDeactivate(mgr);
1733 void testCreateLock() {
1734 Lock lock = mock(Lock.class);
1735 LockCallback callback = mock(LockCallback.class);
1736 when(lockmgr.createLock(MY_RESOURCE, MY_OWNER, 10, callback, false)).thenReturn(lock);
1738 // not configured yet, thus no lock manager
1739 assertThatIllegalStateException()
1740 .isThrownBy(() -> mgr.createLock(MY_RESOURCE, MY_OWNER, 10, callback, false));
1742 // now configure it and try again
1743 mgr.configure(properties);
1744 assertSame(lock, mgr.createLock(MY_RESOURCE, MY_OWNER, 10, callback, false));
1746 // test illegal args
1747 assertThatThrownBy(() -> mgr.createLock(null, MY_OWNER, 10, callback, false))
1748 .hasMessageContaining("resourceId");
1749 assertThatThrownBy(() -> mgr.createLock(MY_RESOURCE, null, 10, callback, false))
1750 .hasMessageContaining("ownerKey");
1751 assertThatIllegalArgumentException()
1752 .isThrownBy(() -> mgr.createLock(MY_RESOURCE, MY_OWNER, -1, callback, false))
1753 .withMessageContaining("holdSec");
1754 assertThatThrownBy(() -> mgr.createLock(MY_RESOURCE, MY_OWNER, 10, null, false))
1755 .hasMessageContaining("callback");
1759 void testOpen() throws Throwable {
1760 when(prov1.beforeOpen(mgr)).thenThrow(new RuntimeException(EXPECTED));
1761 when(prov1.afterOpen(mgr)).thenThrow(new RuntimeException(EXPECTED));
1763 assertTrue(mgr.lock());
1764 assertThatIllegalStateException().isThrownBy(() -> mgr.open());
1767 assertTrue(mgr.unlock());
1771 mgr.configure(properties);
1772 assertTrue(mgr.start());
1774 verify(source1, never()).start();
1775 verify(source2, never()).start();
1777 assertTrue(mgr.open());
1779 verify(prov1).beforeOpen(mgr);
1780 verify(prov2).beforeOpen(mgr);
1782 verify(source1).start();
1783 verify(source2).start();
1785 verify(prov1).afterOpen(mgr);
1786 verify(prov2).afterOpen(mgr);
1788 when(source1.start()).thenReturn(false);
1789 assertFalse(mgr.open());
1790 when(source1.start()).thenReturn(true);
1792 when(sink1.start()).thenReturn(false);
1793 assertFalse(mgr.open());
1794 when(sink1.start()).thenReturn(true);
1796 assertTrue(mgr.open());
1799 private void unsuccessfulOpen() {
1800 verify(prov1).beforeOpen(mgr);
1801 verify(prov2).beforeOpen(mgr);
1803 verify(prov1, never()).afterOpen(mgr);
1804 verify(prov2, never()).afterOpen(mgr);
1806 verify(source1, never()).start();
1807 verify(source2, never()).start();
1809 verify(sink1, never()).start();
1810 verify(sink2, never()).start();
1814 void testControllerConfig() throws Exception {
1815 mgr.configure(properties);
1816 assertTrue(mgr.configure(pdpConfig));
1818 verify(controllerFactory).patch(controller3, drools3);
1819 verify(controllerFactory).patch(controller4, drools4);
1821 // empty controllers
1822 pdpConfig.getControllers().clear();
1823 assertFalse(mgr.configure(pdpConfig));
1826 pdpConfig.setControllers(null);
1827 assertFalse(mgr.configure(pdpConfig));
1829 // arrange for controller3 to fail
1831 config3.setOperation("fail-3");
1832 assertFalse(mgr.configure(pdpConfig));
1834 verify(controllerFactory, never()).patch(controller3, drools3);
1835 verify(controllerFactory).patch(controller4, drools4);
1837 // arrange for both controllers to fail
1839 config3.setOperation("fail-3");
1840 config4.setOperation("fail-4");
1841 assertFalse(mgr.configure(pdpConfig));
1845 void testToString() {
1846 assertTrue(mgr.toString().startsWith("PolicyEngineManager("));
1850 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries
1851 * combinations where beforeXxx and afterXxx return {@code true} and {@code false}.
1853 * @param setBefore function to set the return value of a provider's beforeXxx method
1854 * @param setAfter function to set the return value of a provider's afterXxx method
1855 * @param action invokes the operation
1856 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
1857 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
1858 * and the afterXxx loop was invoked
1859 * @param verifyAfter verifies that a provider's afterXxx method was invoked
1860 * @throws Exception if an error occurs while calling {@link #setUp()}
1862 private void checkBeforeAfter(BiConsumer<PolicyEngineFeatureApi, Boolean> setBefore,
1863 BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
1864 Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
1865 Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
1867 checkBeforeAfter_FalseFalse(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
1868 checkBeforeAfter_FalseTrue(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
1869 checkBeforeAfter_TrueFalse(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
1871 // don't need to test true-true, as it's behavior is a subset of true-false
1875 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
1876 * case where both the beforeXxx and afterXxx methods return {@code false}.
1878 * @param setBefore function to set the return value of a provider's beforeXxx method
1879 * @param setAfter function to set the return value of a provider's afterXxx method
1880 * @param action invokes the operation
1881 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
1882 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
1883 * and the afterXxx loop was invoked
1884 * @param verifyAfter verifies that a provider's afterXxx method was invoked
1885 * @throws Exception if an error occurs while calling {@link #setUp()}
1887 private void checkBeforeAfter_FalseFalse(BiConsumer<PolicyEngineFeatureApi, Boolean> setBefore,
1888 BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
1889 Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
1890 Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
1894 // configure for the test
1895 setBefore.accept(prov1, false);
1896 setBefore.accept(prov2, false);
1898 setAfter.accept(prov1, false);
1899 setAfter.accept(prov2, false);
1904 // verify that various methods were invoked
1905 verifyBefore.accept(prov1);
1906 verifyBefore.accept(prov2);
1910 verifyAfter.accept(prov1);
1911 verifyAfter.accept(prov2);
1915 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
1916 * case where the first provider's afterXxx returns {@code true}, while the others
1917 * return {@code false}.
1919 * @param setBefore function to set the return value of a provider's beforeXxx method
1920 * @param setAfter function to set the return value of a provider's afterXxx method
1921 * @param action invokes the operation
1922 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
1923 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
1924 * and the afterXxx loop was invoked
1925 * @param verifyAfter verifies that a provider's afterXxx method was invoked
1926 * @throws Exception if an error occurs while calling {@link #setUp()}
1928 private void checkBeforeAfter_FalseTrue(BiConsumer<PolicyEngineFeatureApi, Boolean> setBefore,
1929 BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
1930 Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
1931 Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
1935 // configure for the test
1936 setBefore.accept(prov1, false);
1937 setBefore.accept(prov2, false);
1939 setAfter.accept(prov1, true);
1940 setAfter.accept(prov2, false);
1945 // verify that various methods were invoked
1946 verifyBefore.accept(prov1);
1947 verifyBefore.accept(prov2);
1951 verifyAfter.accept(prov1);
1952 assertThatThrownBy(() -> verifyAfter.accept(prov2)).isInstanceOf(AssertionError.class);
1956 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
1957 * case where the first provider's beforeXxx returns {@code true}, while the others
1958 * return {@code false}.
1960 * @param setBefore function to set the return value of a provider's beforeXxx method
1961 * @param setAfter function to set the return value of a provider's afterXxx method
1962 * @param action invokes the operation
1963 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
1964 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
1965 * and the afterXxx loop was invoked
1966 * @param verifyAfter verifies that a provider's afterXxx method was invoked
1967 * @throws Exception if an error occurs while calling {@link #setUp()}
1969 private void checkBeforeAfter_TrueFalse(BiConsumer<PolicyEngineFeatureApi, Boolean> setBefore,
1970 BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
1971 Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
1972 Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
1976 // configure for the test
1977 setBefore.accept(prov1, true);
1978 setBefore.accept(prov2, false);
1980 setAfter.accept(prov1, false);
1981 setAfter.accept(prov2, false);
1986 // verify that various methods were invoked
1987 verifyBefore.accept(prov1);
1989 // remaining methods should not have been invoked
1990 assertThatThrownBy(() -> verifyBefore.accept(prov2)).isInstanceOf(AssertionError.class);
1992 assertThatThrownBy(verifyMiddle::run).isInstanceOf(AssertionError.class);
1994 assertThatThrownBy(() -> verifyAfter.accept(prov1)).isInstanceOf(AssertionError.class);
1995 assertThatThrownBy(() -> verifyAfter.accept(prov2)).isInstanceOf(AssertionError.class);
1998 private void verifyNeverCalled() {
1999 verify(controller, never()).stop();
2000 verify(source1, never()).stop();
2001 verify(sink1, never()).stop();
2002 verify(endpoint, never()).stop();
2003 verify(server1, never()).stop();
2004 verify(client1, never()).stop();
2005 verify(prov1, never()).afterStop(mgr);
2006 verify(prov2, never()).afterStop(mgr);
2010 * Manager with overrides.
2012 private class PolicyEngineManagerImpl extends PolicyEngineManager {
2015 protected List<PolicyEngineFeatureApi> getEngineProviders() {
2020 protected List<PolicyControllerFeatureApi> getControllerProviders() {
2021 return contProviders;
2025 protected void globalInitContainer(String[] cliArgs) {
2026 globalInitArgs = cliArgs;
2030 protected TopicEndpoint getTopicEndpointManager() {
2035 protected HttpServletServerFactory getServletFactory() {
2036 return serverFactory;
2040 protected HttpClientFactory getHttpClientFactory() {
2041 return clientFactory;
2045 protected PolicyControllerFactory getControllerFactory() {
2046 return controllerFactory;
2050 protected void startPdpJmxListener() {
2055 protected void stopPdpJmxListener() {
2060 protected Thread makeShutdownThread() {
2061 shutdownThread = new MyShutdown();
2062 return shutdownThread;
2066 protected EventProtocolCoder getProtocolCoder() {
2071 protected SystemPersistence getPersistenceManager() {
2076 protected PolicyEngine getPolicyEngine() {
2081 protected ScheduledExecutorService makeScheduledExecutor(int nthreads) {
2086 public PolicyStatsManager getStats() {
2087 return statsManager;
2091 * Shutdown thread with overrides.
2093 private class MyShutdown extends ShutdownThread {
2096 protected void doSleep() throws InterruptedException {
2097 threadSleepMs = 300L;
2099 if (shouldInterrupt) {
2100 throw new InterruptedException(EXPECTED);
2105 protected void doExit() {
2110 public synchronized void start() {
2111 threadStarted = true;
2115 public void interrupt() {
2116 threadInterrupted = true;
2121 @FunctionalInterface
2122 private interface RunnableWithEx {
2123 void run() throws Exception;