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(any(), any())).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(any(), any())).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(any(), any())).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(any(), any())).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() 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));
780 * For remaining tests, the factory will return the controller instead of creating
784 when(controllerFactory.get(CONTROLLER3)).thenReturn(controller3);
786 assertEquals(controller3, mgr.updatePolicyController(config3));
788 // should NOT have created a new controller
789 verify(engine, never()).createPolicyController(any(), any());
795 // check different operations
797 // CREATE only invokes patch() (note: mgr.update() has already been called)
798 verify(controllerFactory, times(++countPatch)).patch(controller3, drools3);
799 verify(controller3, times(countLock)).lock();
800 verify(controller3, times(countUnlock)).unlock();
802 // UPDATE invokes unlock() and patch()
803 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_UPDATE);
804 assertEquals(controller3, mgr.updatePolicyController(config3));
805 verify(controllerFactory, times(++countPatch)).patch(controller3, drools3);
806 verify(controller3, times(countLock)).lock();
807 verify(controller3, times(++countUnlock)).unlock();
809 // LOCK invokes lock()
810 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_LOCK);
811 assertEquals(controller3, mgr.updatePolicyController(config3));
812 verify(controllerFactory, times(countPatch)).patch(controller3, drools3);
813 verify(controller3, times(++countLock)).lock();
814 verify(controller3, times(countUnlock)).unlock();
816 // UNLOCK invokes unlock()
817 config3.setOperation(ControllerConfiguration.CONFIG_CONTROLLER_OPERATION_UNLOCK);
818 assertEquals(controller3, mgr.updatePolicyController(config3));
819 verify(controllerFactory, times(countPatch)).patch(controller3, drools3);
820 verify(controller3, times(countLock)).lock();
821 verify(controller3, times(++countUnlock)).unlock();
824 config3.setOperation("invalid-operation");
825 assertThatIllegalArgumentException().isThrownBy(() -> mgr.updatePolicyController(config3));
829 void testStart() throws Throwable {
830 // normal success case
831 testStart(true, () -> {
832 // arrange for first provider, server, source, and sink to throw exceptions
833 when(prov1.beforeStart(mgr)).thenThrow(new RuntimeException(EXPECTED));
834 when(prov1.afterStart(mgr)).thenThrow(new RuntimeException(EXPECTED));
835 when(server1.waitedStart(anyLong())).thenThrow(new RuntimeException(EXPECTED));
836 when(client1.start()).thenThrow(new RuntimeException(EXPECTED));
837 when(source1.start()).thenThrow(new RuntimeException(EXPECTED));
838 when(sink1.start()).thenThrow(new RuntimeException(EXPECTED));
841 // lock manager fails to start - still does everything
842 testStart(false, () -> when(lockmgr.start()).thenReturn(false));
844 // lock manager throws an exception - still does everything
845 testStart(false, () -> when(lockmgr.start()).thenThrow(new RuntimeException(EXPECTED)));
847 // servlet wait fails - still does everything
848 testStart(false, () -> when(server1.waitedStart(anyLong())).thenReturn(false));
850 // client fails - still does everything
851 testStart(false, () -> when(client1.start()).thenReturn(false));
853 // topic source is not started with start
854 testStart(true, () -> when(source1.start()).thenReturn(false));
856 // topic sink is not started with start
857 testStart(true, () -> when(sink1.start()).thenReturn(false));
859 // controller fails to start - still does everything
860 testStart(false, () -> when(controller.start()).thenReturn(false));
862 // controller throws an exception - still does everything
863 testStart(false, () -> when(controller.start()).thenThrow(new RuntimeException(EXPECTED)));
865 // endpoint manager fails to start - still does everything
866 testStart(false, () -> when(endpoint.start()).thenReturn(false));
868 // endpoint manager throws an exception - still does everything AND succeeds
869 testStart(true, () -> when(endpoint.start()).thenThrow(new IllegalStateException(EXPECTED)));
871 // locked - nothing other than beforeXxx methods should be invoked
873 mgr.configure(properties);
875 assertThatIllegalStateException().isThrownBy(() -> mgr.start());
876 verify(prov2).beforeStart(mgr);
877 verify(server2, never()).waitedStart(anyLong());
878 verify(source2, never()).start();
879 verify(sink1, never()).start();
880 verify(controller, never()).start();
881 verify(endpoint, never()).start();
882 assertFalse(jmxStarted);
883 verify(prov1, never()).afterStart(mgr);
887 (prov, flag) -> when(prov.beforeStart(mgr)).thenReturn(flag),
888 (prov, flag) -> when(prov.afterStart(mgr)).thenReturn(flag),
890 mgr.configure(properties);
891 assertTrue(mgr.start());
893 prov -> verify(prov).beforeStart(mgr),
894 () -> assertTrue(jmxStarted),
895 prov -> verify(prov).afterStart(mgr));
899 * Tests the start() method, after setting some option.
901 * @param expectedResult what start() is expected to return
902 * @param setOption function that sets an option
903 * @throws Throwable if an error occurs during setup
905 private void testStart(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
909 mgr.configure(properties);
910 assertEquals(expectedResult, mgr.start());
912 verify(prov1).beforeStart(mgr);
913 verify(prov2).beforeStart(mgr);
915 verify(server1).waitedStart(anyLong());
916 verify(server2).waitedStart(anyLong());
918 verify(client1).start();
919 verify(client2).start();
921 verify(source1, never()).start();
922 verify(source2, never()).start();
924 verify(sink1, never()).start();
925 verify(sink2, never()).start();
927 verify(controller).start();
928 verify(controller2).start();
930 verify(endpoint).start();
932 assertTrue(jmxStarted);
934 verify(prov1).afterStart(mgr);
935 verify(prov2).afterStart(mgr);
939 void testStop() throws Throwable {
940 // normal success case
941 testStop(true, () -> {
942 // arrange for first provider, server, source, and sink to throw exceptions
943 when(prov1.beforeStop(mgr)).thenThrow(new RuntimeException(EXPECTED));
944 when(prov1.afterStop(mgr)).thenThrow(new RuntimeException(EXPECTED));
945 when(server1.stop()).thenThrow(new RuntimeException(EXPECTED));
946 when(client1.stop()).thenThrow(new RuntimeException(EXPECTED));
947 when(source1.stop()).thenThrow(new RuntimeException(EXPECTED));
948 when(sink1.stop()).thenThrow(new RuntimeException(EXPECTED));
951 // not alive - shouldn't run anything besides beforeStop()
953 mgr.configure(properties);
954 assertTrue(mgr.stop());
955 verify(prov1).beforeStop(mgr);
956 verify(prov2).beforeStop(mgr);
957 verify(controller, never()).stop();
958 verify(source1, never()).stop();
959 verify(sink1, never()).stop();
960 verify(endpoint, never()).stop();
961 verify(server1, never()).stop();
962 verify(client1, never()).stop();
963 verify(prov1, never()).afterStop(mgr);
964 verify(prov2, never()).afterStop(mgr);
966 // controller fails to stop - still does everything
967 testStop(false, () -> when(controller.stop()).thenReturn(false));
969 // controller throws an exception - still does everything
970 testStop(false, () -> when(controller.stop()).thenThrow(new RuntimeException(EXPECTED)));
972 // topic source fails to stop - still does everything
973 testStop(false, () -> when(source1.stop()).thenReturn(false));
975 // topic sink fails to stop - still does everything
976 testStop(false, () -> when(sink1.stop()).thenReturn(false));
978 // endpoint manager fails to stop - still does everything
979 testStop(false, () -> when(endpoint.stop()).thenReturn(false));
981 // servlet fails to stop - still does everything
982 testStop(false, () -> when(server1.stop()).thenReturn(false));
984 // client fails to stop - still does everything
985 testStop(false, () -> when(client1.stop()).thenReturn(false));
987 // lock manager fails to stop - still does everything
988 testStop(false, () -> when(lockmgr.stop()).thenReturn(false));
990 // lock manager throws an exception - still does everything
991 testStop(false, () -> when(lockmgr.stop()).thenThrow(new RuntimeException(EXPECTED)));
995 (prov, flag) -> when(prov.beforeStop(mgr)).thenReturn(flag),
996 (prov, flag) -> when(prov.afterStop(mgr)).thenReturn(flag),
998 mgr.configure(properties);
1000 assertTrue(mgr.stop());
1002 prov -> verify(prov).beforeStop(mgr),
1003 () -> verify(endpoint).stop(),
1004 prov -> verify(prov).afterStop(mgr));
1008 * Tests the stop() method, after setting some option.
1010 * @param expectedResult what stop() is expected to return
1011 * @param setOption function that sets an option
1012 * @throws Throwable if an error occurs during setup
1014 private void testStop(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
1018 mgr.configure(properties);
1020 assertEquals(expectedResult, mgr.stop());
1022 verify(prov1).beforeStop(mgr);
1023 verify(prov2).beforeStop(mgr);
1025 verify(controller).stop();
1026 verify(controller2).stop();
1028 verify(source1).stop();
1029 verify(source2).stop();
1031 verify(sink1).stop();
1032 verify(sink2).stop();
1034 verify(endpoint).stop();
1036 verify(server1).stop();
1037 verify(server2).stop();
1039 verify(client1).stop();
1040 verify(client2).stop();
1042 verify(prov1).afterStop(mgr);
1043 verify(prov2).afterStop(mgr);
1047 void testShutdown() throws Throwable {
1048 // normal success case
1049 testShutdown(() -> {
1050 // arrange for first provider, source, and sink to throw exceptions
1051 when(prov1.beforeShutdown(mgr)).thenThrow(new RuntimeException(EXPECTED));
1052 when(prov1.afterShutdown(mgr)).thenThrow(new RuntimeException(EXPECTED));
1053 doThrow(new RuntimeException(EXPECTED)).when(source1).shutdown();
1054 doThrow(new RuntimeException(EXPECTED)).when(sink1).shutdown();
1057 assertNotNull(shutdownThread);
1058 assertTrue(threadStarted);
1059 assertTrue(threadInterrupted);
1062 // lock manager throws an exception - still does everything
1063 testShutdown(() -> doThrow(new RuntimeException(EXPECTED)).when(lockmgr).shutdown());
1067 (prov, flag) -> when(prov.beforeShutdown(mgr)).thenReturn(flag),
1068 (prov, flag) -> when(prov.afterShutdown(mgr)).thenReturn(flag),
1070 mgr.configure(properties);
1074 prov -> verify(prov).beforeShutdown(mgr),
1075 () -> assertTrue(jmxStopped),
1076 prov -> verify(prov).afterShutdown(mgr));
1080 * Tests the shutdown() method, after setting some option.
1082 * @param setOption function that sets an option
1083 * @throws Throwable if an error occurs during setup
1085 private void testShutdown(RunnableWithEx setOption) throws Throwable {
1089 mgr.configure(properties);
1093 verify(prov1).beforeShutdown(mgr);
1094 verify(prov2).beforeShutdown(mgr);
1096 verify(source1).shutdown();
1097 verify(source2).shutdown();
1099 verify(sink1).shutdown();
1100 verify(sink2).shutdown();
1102 verify(controllerFactory).shutdown();
1103 verify(endpoint).shutdown();
1104 verify(serverFactory).destroy();
1105 verify(clientFactory).destroy();
1107 assertTrue(jmxStopped);
1109 verify(prov1).afterShutdown(mgr);
1110 verify(prov2).afterShutdown(mgr);
1112 verify(exsvc).shutdownNow();
1116 void testShutdownThreadRun() throws Throwable {
1117 // arrange for first server to throw exceptions
1118 testShutdownThreadRun(() -> doThrow(new RuntimeException(EXPECTED)).when(server1).shutdown());
1120 // sleep throws an exception
1121 testShutdownThreadRun(() -> shouldInterrupt = true);
1125 * Tests the ShutdownThread.run() method, after setting some option.
1127 * @param setOption function that sets an option
1128 * @throws Throwable if an error occurs during setup
1130 private void testShutdownThreadRun(RunnableWithEx setOption) throws Throwable {
1134 mgr.configure(properties);
1138 assertNotNull(shutdownThread);
1140 shutdownThread.run();
1142 assertTrue(threadSleepMs >= 0);
1143 assertEquals(0, threadExitCode);
1145 verify(server1).shutdown();
1146 verify(server2).shutdown();
1148 verify(clientFactory).destroy();
1152 void testIsAlive() {
1153 mgr.configure(properties);
1154 assertFalse(mgr.isAlive());
1157 assertTrue(mgr.isAlive());
1160 assertFalse(mgr.isAlive());
1164 void testLock() throws Throwable {
1165 // normal success case
1166 testLock(true, () -> {
1167 // arrange for first provider to throw exceptions
1168 when(prov1.beforeLock(mgr)).thenThrow(new RuntimeException(EXPECTED));
1169 when(prov1.afterLock(mgr)).thenThrow(new RuntimeException(EXPECTED));
1172 // already locked - shouldn't run anything besides beforeLock()
1174 mgr.configure(properties);
1176 assertTrue(mgr.lock());
1177 verify(prov1, times(2)).beforeLock(mgr);
1178 verify(prov2, times(2)).beforeLock(mgr);
1179 verify(controller).lock();
1180 verify(controller2).lock();
1181 verify(endpoint).lock();
1182 verify(prov1).afterLock(mgr);
1183 verify(prov2).afterLock(mgr);
1185 // controller fails to lock - still does everything
1186 testLock(false, () -> when(controller.lock()).thenReturn(false));
1188 // controller throws an exception - still does everything
1189 testLock(false, () -> when(controller.lock()).thenThrow(new RuntimeException(EXPECTED)));
1191 // endpoint manager fails to lock - still does everything
1192 testLock(false, () -> when(endpoint.lock()).thenReturn(false));
1194 // lock manager fails to lock - still does everything
1195 testLock(false, () -> when(lockmgr.lock()).thenReturn(false));
1197 // lock manager throws an exception - still does everything
1198 testLock(false, () -> when(lockmgr.lock()).thenThrow(new RuntimeException(EXPECTED)));
1202 (prov, flag) -> when(prov.beforeLock(mgr)).thenReturn(flag),
1203 (prov, flag) -> when(prov.afterLock(mgr)).thenReturn(flag),
1205 mgr.configure(properties);
1207 assertTrue(mgr.lock());
1209 prov -> verify(prov).beforeLock(mgr),
1210 () -> verify(endpoint).lock(),
1211 prov -> verify(prov).afterLock(mgr));
1215 * Tests the lock() method, after setting some option.
1217 * @param expectedResult what lock() is expected to return
1218 * @param setOption function that sets an option
1219 * @throws Throwable if an error occurs during setup
1221 private void testLock(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
1225 mgr.configure(properties);
1226 assertEquals(expectedResult, mgr.lock());
1228 verify(prov1).beforeLock(mgr);
1229 verify(prov2).beforeLock(mgr);
1231 verify(controller).lock();
1232 verify(controller2).lock();
1234 verify(endpoint).lock();
1236 verify(prov1).afterLock(mgr);
1237 verify(prov2).afterLock(mgr);
1241 void testUnlock() throws Throwable {
1242 // normal success case
1243 testUnlock(true, () -> {
1244 // arrange for first provider to throw exceptions
1245 when(prov1.beforeUnlock(mgr)).thenThrow(new RuntimeException(EXPECTED));
1246 when(prov1.afterUnlock(mgr)).thenThrow(new RuntimeException(EXPECTED));
1249 // not locked - shouldn't run anything besides beforeUnlock()
1251 mgr.configure(properties);
1252 assertTrue(mgr.unlock());
1253 verify(prov1).beforeUnlock(mgr);
1254 verify(prov2).beforeUnlock(mgr);
1255 verify(controller, never()).unlock();
1256 verify(controller2, never()).unlock();
1257 verify(endpoint, never()).unlock();
1258 verify(prov1, never()).afterUnlock(mgr);
1259 verify(prov2, never()).afterUnlock(mgr);
1261 // controller fails to unlock - still does everything
1262 testUnlock(false, () -> when(controller.unlock()).thenReturn(false));
1264 // controller throws an exception - still does everything
1265 testUnlock(false, () -> when(controller.unlock()).thenThrow(new RuntimeException(EXPECTED)));
1267 // endpoint manager fails to unlock - still does everything
1268 testUnlock(false, () -> when(endpoint.unlock()).thenReturn(false));
1270 // lock manager fails to lock - still does everything
1271 testUnlock(false, () -> when(lockmgr.unlock()).thenReturn(false));
1273 // lock manager throws an exception - still does everything
1274 testUnlock(false, () -> when(lockmgr.unlock()).thenThrow(new RuntimeException(EXPECTED)));
1278 (prov, flag) -> when(prov.beforeUnlock(mgr)).thenReturn(flag),
1279 (prov, flag) -> when(prov.afterUnlock(mgr)).thenReturn(flag),
1281 mgr.configure(properties);
1283 assertTrue(mgr.unlock());
1285 prov -> verify(prov).beforeUnlock(mgr),
1286 () -> verify(endpoint).unlock(),
1287 prov -> verify(prov).afterUnlock(mgr));
1291 * Tests the unlock() method, after setting some option.
1293 * @param expectedResult what unlock() is expected to return
1294 * @param setOption function that sets an option
1295 * @throws Throwable if an error occurs during setup
1297 private void testUnlock(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
1301 mgr.configure(properties);
1303 assertEquals(expectedResult, mgr.unlock());
1305 verify(prov1).beforeUnlock(mgr);
1306 verify(prov2).beforeUnlock(mgr);
1308 verify(controller).unlock();
1309 verify(controller2).unlock();
1311 verify(endpoint).unlock();
1313 verify(prov1).afterUnlock(mgr);
1314 verify(prov2).afterUnlock(mgr);
1318 void testIsLocked() {
1319 mgr.configure(properties);
1320 assertFalse(mgr.isLocked());
1323 assertTrue(mgr.isLocked());
1326 assertFalse(mgr.isLocked());
1330 void testRemovePolicyControllerString() {
1331 mgr.removePolicyController(MY_NAME);
1333 verify(controllerFactory).destroy(MY_NAME);
1337 void testRemovePolicyControllerPolicyController() {
1338 mgr.removePolicyController(controller);
1340 verify(controllerFactory).destroy(controller);
1344 void testGetPolicyControllers() {
1345 assertEquals(controllers, mgr.getPolicyControllers());
1349 void testGetPolicyControllerIds() {
1350 assertEquals(Arrays.asList(CONTROLLER1, CONTROLLER2), mgr.getPolicyControllerIds());
1354 void testGetProperties() {
1355 properties.setProperty("prop-x", "value-x");
1356 properties.setProperty("prop-y", "value-y");
1358 mgr.configure(properties);
1359 assertEquals(properties, mgr.getProperties());
1363 void testGetSources() {
1364 mgr.configure(properties);
1365 assertEquals(sources, mgr.getSources());
1369 void testGetSinks() {
1370 mgr.configure(properties);
1371 assertEquals(sinks, mgr.getSinks());
1375 void testGetHttpServers() {
1376 mgr.configure(properties);
1377 assertEquals(servers, mgr.getHttpServers());
1381 void testGetFeatures() {
1382 assertEquals(Arrays.asList(FEATURE1, FEATURE2), mgr.getFeatures());
1386 void testGetFeatureProviders() {
1387 assertEquals(providers, mgr.getFeatureProviders());
1391 void testGetFeatureProvider() {
1392 assertEquals(prov1, mgr.getFeatureProvider(FEATURE1));
1393 assertEquals(prov2, mgr.getFeatureProvider(FEATURE2));
1396 assertThatIllegalArgumentException().isThrownBy(() -> mgr.getFeatureProvider(null));
1399 assertThatIllegalArgumentException().isThrownBy(() -> mgr.getFeatureProvider(""));
1402 assertThatIllegalArgumentException().isThrownBy(() -> mgr.getFeatureProvider("unknown-feature"));
1406 void testTransaction() {
1407 mgr.metric(CONTROLLER1, POLICY, new Metric());
1408 assertEquals(0, mgr.getStats().getGroupStat().getPolicyExecutedCount());
1409 assertEquals(0, mgr.getStats().getSubgroupStats().size());
1411 Metric metric = new Metric();
1412 mgr.transaction(CONTROLLER1, CONTROLLOOP, metric);
1413 assertEquals(1, mgr.getStats().getGroupStat().getPolicyExecutedCount());
1414 assertEquals(1, mgr.getStats().getSubgroupStats().size());
1415 assertEquals(1, mgr.getStats().getSubgroupStats().get(CONTROLLOOP).getPolicyExecutedFailCount());
1417 Summary.Child.Value summary =
1418 PolicyEngineManagerImpl.transLatencySecsSummary
1419 .labels(CONTROLLER1, CONTROLLOOP, POLICY, PdpResponseStatus.FAIL.name()).get();
1421 assertEquals(0, summary.count, 0.0);
1422 assertEquals(0, summary.sum, 0.0);
1424 metric.setServiceInstanceId(POLICY);
1425 metric.setElapsedTime(5000L);
1426 metric.setSuccess(false);
1427 mgr.transaction(CONTROLLER1, CONTROLLOOP, metric);
1430 PolicyEngineManagerImpl.transLatencySecsSummary
1431 .labels(CONTROLLER1, CONTROLLOOP, POLICY, PdpResponseStatus.FAIL.name()).get();
1433 assertEquals(1, summary.count, 0.0);
1434 assertEquals(5, summary.sum, 0.0);
1438 void testOnTopicEvent() {
1439 mgr.onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, pdpConfigJson);
1441 verify(controllerFactory).patch(controller3, drools3);
1442 verify(controllerFactory).patch(controller4, drools4);
1444 // null json - no additional patches
1445 mgr.onTopicEvent(CommInfrastructure.NOOP, MY_TOPIC, null);
1447 verify(controllerFactory).patch(controller3, drools3);
1448 verify(controllerFactory).patch(controller4, drools4);
1452 void testDeliverStringObject() throws Exception {
1453 mgr.configure(properties);
1456 assertTrue(mgr.deliver(MY_TOPIC, MY_EVENT));
1458 verify(sink1).send(MESSAGE);
1460 // invalid parameters
1461 String nullStr = null;
1462 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(nullStr, MY_EVENT));
1463 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver("", MY_EVENT));
1465 Object nullObj = null;
1466 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(MY_TOPIC, nullObj));
1470 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1475 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1477 // issues with topic
1479 mgr.configure(properties);
1483 when(endpoint.getTopicSinks(MY_TOPIC)).thenReturn(null);
1484 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1487 when(endpoint.getTopicSinks(MY_TOPIC)).thenReturn(Collections.emptyList());
1488 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1491 when(endpoint.getTopicSinks(MY_TOPIC)).thenReturn(sinks);
1492 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(MY_TOPIC, MY_EVENT));
1496 void testDeliverStringStringObject() {
1497 mgr.configure(properties);
1500 assertTrue(mgr.deliver(NOOP_STR, MY_TOPIC, MY_EVENT));
1502 verify(sink1).send(MESSAGE);
1504 // invalid parameters
1505 String nullStr = null;
1506 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(nullStr, MY_TOPIC, MY_EVENT));
1507 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver("", MY_TOPIC, MY_EVENT));
1508 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver("unknown-bus-type", MY_TOPIC, MY_EVENT));
1510 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(NOOP_STR, nullStr, MY_EVENT));
1511 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(NOOP_STR, "", MY_EVENT));
1513 Object nullObj = null;
1514 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(NOOP_STR, MY_TOPIC, nullObj));
1518 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(NOOP_STR, MY_TOPIC, MY_EVENT));
1523 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(NOOP_STR, MY_TOPIC, MY_EVENT));
1527 void testDeliverCommInfrastructureStringObject() throws Exception {
1528 mgr.configure(properties);
1531 assertTrue(mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1533 verify(controller, never()).deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT);
1535 verify(coder).encode(MY_TOPIC, MY_EVENT);
1536 verify(sink1).send(MESSAGE);
1538 // invalid parameters
1539 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, null, MY_EVENT));
1540 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, "", MY_EVENT));
1542 Object nullObj = null;
1543 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, nullObj));
1547 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1552 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1554 // send() throws an exception
1556 mgr.configure(properties);
1558 when(sink1.send(any())).thenThrow(new ArithmeticException(EXPECTED));
1559 assertThatThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT))
1560 .isInstanceOf(ArithmeticException.class);
1563 * For remaining tests, have the controller handle delivery.
1566 mgr.configure(properties);
1568 DroolsController drools = mock(DroolsController.class);
1569 when(coder.getDroolsController(MY_TOPIC, MY_EVENT)).thenReturn(drools);
1570 when(controllerFactory.get(drools)).thenReturn(controller);
1571 when(controller.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT)).thenReturn(true);
1573 assertTrue(mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1575 verify(controller).deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT);
1577 verify(coder, never()).encode(MY_TOPIC, MY_EVENT);
1578 verify(sink1, never()).send(MESSAGE);
1580 // controller throws exception, so should drop into regular handling
1581 when(controller.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT)).thenThrow(new RuntimeException(EXPECTED));
1583 assertTrue(mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT));
1585 // should have attempted this again
1586 verify(controller, times(2)).deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT);
1588 // now these should have been called
1589 verify(coder).encode(MY_TOPIC, MY_EVENT);
1590 verify(sink1).send(MESSAGE);
1594 void testDeliverCommInfrastructureStringString() {
1595 mgr.configure(properties);
1598 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MESSAGE));
1603 assertTrue(mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MESSAGE));
1604 verify(sink1).send(MESSAGE);
1605 verify(sink2, never()).send(any());
1607 // invalid parameters
1608 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, null, MESSAGE));
1609 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, "", MESSAGE));
1611 String nullStr = null;
1612 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, nullStr));
1613 assertThatIllegalArgumentException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, ""));
1616 assertThatIllegalStateException()
1617 .isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, "unknown-topic", MESSAGE));
1621 assertThatIllegalStateException().isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MESSAGE));
1626 void testActivate() throws Throwable {
1627 // normal success case
1628 testActivate(() -> {
1629 // arrange for first provider and controller to throw exceptions
1630 when(prov1.beforeActivate(mgr)).thenThrow(new RuntimeException(EXPECTED));
1631 when(prov1.afterActivate(mgr)).thenThrow(new RuntimeException(EXPECTED));
1632 when(controller.start()).thenThrow(new RuntimeException(EXPECTED));
1635 // controller generates linkage error
1636 testActivate(() -> when(controller.start()).thenThrow(new LinkageError(EXPECTED)));
1640 (prov, flag) -> when(prov.beforeActivate(mgr)).thenReturn(flag),
1641 (prov, flag) -> when(prov.afterActivate(mgr)).thenReturn(flag),
1643 mgr.configure(properties);
1647 prov -> verify(prov).beforeActivate(mgr),
1648 () -> assertFalse(mgr.isLocked()),
1649 prov -> verify(prov).afterActivate(mgr));
1653 * Tests the activate() method, after setting some option.
1655 * @param setOption function that sets an option
1656 * @throws Throwable if an error occurs during setup
1658 private void testActivate(RunnableWithEx setOption) throws Throwable {
1662 mgr.configure(properties);
1666 verify(prov1).beforeActivate(mgr);
1667 verify(prov2).beforeActivate(mgr);
1669 // unlocked by activate() AND by unlock() (which is invoked by activate())
1670 verify(controller, times(2)).unlock();
1671 verify(controller2, times(2)).unlock();
1673 verify(controller).start();
1674 verify(controller2).start();
1676 assertFalse(mgr.isLocked());
1678 verify(prov1).afterActivate(mgr);
1679 verify(prov2).afterActivate(mgr);
1683 void testDeactivate() throws Throwable {
1684 // normal success case
1685 testDeactivate(() -> {
1686 // arrange for first provider and controller to throw exceptions
1687 when(prov1.beforeDeactivate(mgr)).thenThrow(new RuntimeException(EXPECTED));
1688 when(prov1.afterDeactivate(mgr)).thenThrow(new RuntimeException(EXPECTED));
1689 when(controller.stop()).thenThrow(new RuntimeException(EXPECTED));
1692 // controller generates linkage error
1693 testDeactivate(() -> when(controller.stop()).thenThrow(new LinkageError(EXPECTED)));
1697 (prov, flag) -> when(prov.beforeDeactivate(mgr)).thenReturn(flag),
1698 (prov, flag) -> when(prov.afterDeactivate(mgr)).thenReturn(flag),
1700 mgr.configure(properties);
1703 prov -> verify(prov).beforeDeactivate(mgr),
1704 () -> assertTrue(mgr.isLocked()),
1705 prov -> verify(prov).afterDeactivate(mgr));
1709 * Tests the deactivate() method, after setting some option.
1711 * @param setOption function that sets an option
1712 * @throws Throwable if an error occurs during setup
1714 private void testDeactivate(RunnableWithEx setOption) throws Throwable {
1718 mgr.configure(properties);
1721 verify(prov1).beforeDeactivate(mgr);
1722 verify(prov2).beforeDeactivate(mgr);
1724 verify(controller).lock();
1725 verify(controller2).lock();
1727 verify(controller).stop();
1728 verify(controller2).stop();
1730 assertTrue(mgr.isLocked());
1732 verify(prov1).afterDeactivate(mgr);
1733 verify(prov2).afterDeactivate(mgr);
1737 void testCreateLock() {
1738 Lock lock = mock(Lock.class);
1739 LockCallback callback = mock(LockCallback.class);
1740 when(lockmgr.createLock(MY_RESOURCE, MY_OWNER, 10, callback, false)).thenReturn(lock);
1742 // not configured yet, thus no lock manager
1743 assertThatIllegalStateException()
1744 .isThrownBy(() -> mgr.createLock(MY_RESOURCE, MY_OWNER, 10, callback, false));
1746 // now configure it and try again
1747 mgr.configure(properties);
1748 assertSame(lock, mgr.createLock(MY_RESOURCE, MY_OWNER, 10, callback, false));
1750 // test illegal args
1751 assertThatThrownBy(() -> mgr.createLock(null, MY_OWNER, 10, callback, false))
1752 .hasMessageContaining("resourceId");
1753 assertThatThrownBy(() -> mgr.createLock(MY_RESOURCE, null, 10, callback, false))
1754 .hasMessageContaining("ownerKey");
1755 assertThatIllegalArgumentException()
1756 .isThrownBy(() -> mgr.createLock(MY_RESOURCE, MY_OWNER, -1, callback, false))
1757 .withMessageContaining("holdSec");
1758 assertThatThrownBy(() -> mgr.createLock(MY_RESOURCE, MY_OWNER, 10, null, false))
1759 .hasMessageContaining("callback");
1763 void testOpen() throws Throwable {
1764 when(prov1.beforeOpen(mgr)).thenThrow(new RuntimeException(EXPECTED));
1765 when(prov1.afterOpen(mgr)).thenThrow(new RuntimeException(EXPECTED));
1767 assertTrue(mgr.lock());
1768 assertThatIllegalStateException().isThrownBy(() -> mgr.open());
1771 assertTrue(mgr.unlock());
1775 mgr.configure(properties);
1776 assertTrue(mgr.start());
1778 verify(source1, never()).start();
1779 verify(source2, never()).start();
1781 assertTrue(mgr.open());
1783 verify(prov1).beforeOpen(mgr);
1784 verify(prov2).beforeOpen(mgr);
1786 verify(source1).start();
1787 verify(source2).start();
1789 verify(prov1).afterOpen(mgr);
1790 verify(prov2).afterOpen(mgr);
1792 when(source1.start()).thenReturn(false);
1793 assertFalse(mgr.open());
1794 when(source1.start()).thenReturn(true);
1796 when(sink1.start()).thenReturn(false);
1797 assertFalse(mgr.open());
1798 when(sink1.start()).thenReturn(true);
1800 assertTrue(mgr.open());
1803 private void unsuccessfulOpen() {
1804 verify(prov1).beforeOpen(mgr);
1805 verify(prov2).beforeOpen(mgr);
1807 verify(prov1, never()).afterOpen(mgr);
1808 verify(prov2, never()).afterOpen(mgr);
1810 verify(source1, never()).start();
1811 verify(source2, never()).start();
1813 verify(sink1, never()).start();
1814 verify(sink2, never()).start();
1818 void testControllerConfig() throws Exception {
1819 mgr.configure(properties);
1820 assertTrue(mgr.configure(pdpConfig));
1822 verify(controllerFactory).patch(controller3, drools3);
1823 verify(controllerFactory).patch(controller4, drools4);
1825 // empty controllers
1826 pdpConfig.getControllers().clear();
1827 assertFalse(mgr.configure(pdpConfig));
1830 pdpConfig.setControllers(null);
1831 assertFalse(mgr.configure(pdpConfig));
1833 // arrange for controller3 to fail
1835 config3.setOperation("fail-3");
1836 assertFalse(mgr.configure(pdpConfig));
1838 verify(controllerFactory, never()).patch(controller3, drools3);
1839 verify(controllerFactory).patch(controller4, drools4);
1841 // arrange for both controllers to fail
1843 config3.setOperation("fail-3");
1844 config4.setOperation("fail-4");
1845 assertFalse(mgr.configure(pdpConfig));
1849 void testToString() {
1850 assertTrue(mgr.toString().startsWith("PolicyEngineManager("));
1854 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries
1855 * combinations where beforeXxx and afterXxx return {@code true} and {@code false}.
1857 * @param setBefore function to set the return value of a provider's beforeXxx method
1858 * @param setAfter function to set the return value of a provider's afterXxx method
1859 * @param action invokes the operation
1860 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
1861 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
1862 * and the afterXxx loop was invoked
1863 * @param verifyAfter verifies that a provider's afterXxx method was invoked
1864 * @throws Exception if an error occurs while calling {@link #setUp()}
1866 private void checkBeforeAfter(BiConsumer<PolicyEngineFeatureApi, Boolean> setBefore,
1867 BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
1868 Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
1869 Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
1871 checkBeforeAfter_FalseFalse(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
1872 checkBeforeAfter_FalseTrue(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
1873 checkBeforeAfter_TrueFalse(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
1875 // don't need to test true-true, as it's behavior is a subset of true-false
1879 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
1880 * case where both the beforeXxx and afterXxx methods return {@code false}.
1882 * @param setBefore function to set the return value of a provider's beforeXxx method
1883 * @param setAfter function to set the return value of a provider's afterXxx method
1884 * @param action invokes the operation
1885 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
1886 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
1887 * and the afterXxx loop was invoked
1888 * @param verifyAfter verifies that a provider's afterXxx method was invoked
1889 * @throws Exception if an error occurs while calling {@link #setUp()}
1891 private void checkBeforeAfter_FalseFalse(BiConsumer<PolicyEngineFeatureApi, Boolean> setBefore,
1892 BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
1893 Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
1894 Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
1898 // configure for the test
1899 setBefore.accept(prov1, false);
1900 setBefore.accept(prov2, false);
1902 setAfter.accept(prov1, false);
1903 setAfter.accept(prov2, false);
1908 // verify that various methods were invoked
1909 verifyBefore.accept(prov1);
1910 verifyBefore.accept(prov2);
1914 verifyAfter.accept(prov1);
1915 verifyAfter.accept(prov2);
1919 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
1920 * case where the first provider's afterXxx returns {@code true}, while the others
1921 * return {@code false}.
1923 * @param setBefore function to set the return value of a provider's beforeXxx method
1924 * @param setAfter function to set the return value of a provider's afterXxx method
1925 * @param action invokes the operation
1926 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
1927 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
1928 * and the afterXxx loop was invoked
1929 * @param verifyAfter verifies that a provider's afterXxx method was invoked
1930 * @throws Exception if an error occurs while calling {@link #setUp()}
1932 private void checkBeforeAfter_FalseTrue(BiConsumer<PolicyEngineFeatureApi, Boolean> setBefore,
1933 BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
1934 Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
1935 Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
1939 // configure for the test
1940 setBefore.accept(prov1, false);
1941 setBefore.accept(prov2, false);
1943 setAfter.accept(prov1, true);
1944 setAfter.accept(prov2, false);
1949 // verify that various methods were invoked
1950 verifyBefore.accept(prov1);
1951 verifyBefore.accept(prov2);
1955 verifyAfter.accept(prov1);
1956 assertThatThrownBy(() -> verifyAfter.accept(prov2)).isInstanceOf(AssertionError.class);
1960 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
1961 * case where the first provider's beforeXxx returns {@code true}, while the others
1962 * return {@code false}.
1964 * @param setBefore function to set the return value of a provider's beforeXxx method
1965 * @param setAfter function to set the return value of a provider's afterXxx method
1966 * @param action invokes the operation
1967 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
1968 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
1969 * and the afterXxx loop was invoked
1970 * @param verifyAfter verifies that a provider's afterXxx method was invoked
1971 * @throws Exception if an error occurs while calling {@link #setUp()}
1973 private void checkBeforeAfter_TrueFalse(BiConsumer<PolicyEngineFeatureApi, Boolean> setBefore,
1974 BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
1975 Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
1976 Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
1980 // configure for the test
1981 setBefore.accept(prov1, true);
1982 setBefore.accept(prov2, false);
1984 setAfter.accept(prov1, false);
1985 setAfter.accept(prov2, false);
1990 // verify that various methods were invoked
1991 verifyBefore.accept(prov1);
1993 // remaining methods should not have been invoked
1994 assertThatThrownBy(() -> verifyBefore.accept(prov2)).isInstanceOf(AssertionError.class);
1996 assertThatThrownBy(verifyMiddle::run).isInstanceOf(AssertionError.class);
1998 assertThatThrownBy(() -> verifyAfter.accept(prov1)).isInstanceOf(AssertionError.class);
1999 assertThatThrownBy(() -> verifyAfter.accept(prov2)).isInstanceOf(AssertionError.class);
2003 * Manager with overrides.
2005 private class PolicyEngineManagerImpl extends PolicyEngineManager {
2008 protected List<PolicyEngineFeatureApi> getEngineProviders() {
2013 protected List<PolicyControllerFeatureApi> getControllerProviders() {
2014 return contProviders;
2018 protected void globalInitContainer(String[] cliArgs) {
2019 globalInitArgs = cliArgs;
2023 protected TopicEndpoint getTopicEndpointManager() {
2028 protected HttpServletServerFactory getServletFactory() {
2029 return serverFactory;
2033 protected HttpClientFactory getHttpClientFactory() {
2034 return clientFactory;
2038 protected PolicyControllerFactory getControllerFactory() {
2039 return controllerFactory;
2043 protected void startPdpJmxListener() {
2048 protected void stopPdpJmxListener() {
2053 protected Thread makeShutdownThread() {
2054 shutdownThread = new MyShutdown();
2055 return shutdownThread;
2059 protected EventProtocolCoder getProtocolCoder() {
2064 protected SystemPersistence getPersistenceManager() {
2069 protected PolicyEngine getPolicyEngine() {
2074 protected ScheduledExecutorService makeScheduledExecutor(int nthreads) {
2079 public PolicyStatsManager getStats() {
2080 return statsManager;
2084 * Shutdown thread with overrides.
2086 private class MyShutdown extends ShutdownThread {
2089 protected void doSleep(long sleepMs) throws InterruptedException {
2090 threadSleepMs = sleepMs;
2092 if (shouldInterrupt) {
2093 throw new InterruptedException(EXPECTED);
2098 protected void doExit(int code) {
2099 threadExitCode = code;
2103 public synchronized void start() {
2104 threadStarted = true;
2108 public void interrupt() {
2109 threadInterrupted = true;
2114 @FunctionalInterface
2115 private interface RunnableWithEx {
2116 void run() throws Exception;