Removing deprecated DMAAP library
[policy/drools-pdp.git] / feature-pooling-messages / src / test / java / org / onap / policy / drools / pooling / PoolingFeatureTest.java
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2018, 2020 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2020, 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
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
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=========================================================
20  */
21
22 package org.onap.policy.drools.pooling;
23
24 import static org.junit.jupiter.api.Assertions.assertEquals;
25 import static org.junit.jupiter.api.Assertions.assertFalse;
26 import static org.junit.jupiter.api.Assertions.assertNotEquals;
27 import static org.junit.jupiter.api.Assertions.assertNotNull;
28 import static org.junit.jupiter.api.Assertions.assertThrows;
29 import static org.junit.jupiter.api.Assertions.assertTrue;
30 import static org.mockito.ArgumentMatchers.any;
31 import static org.mockito.Mockito.doThrow;
32 import static org.mockito.Mockito.mock;
33 import static org.mockito.Mockito.never;
34 import static org.mockito.Mockito.times;
35 import static org.mockito.Mockito.verify;
36 import static org.mockito.Mockito.when;
37
38 import java.util.Collections;
39 import java.util.LinkedList;
40 import java.util.List;
41 import java.util.Properties;
42 import java.util.concurrent.CountDownLatch;
43 import org.apache.commons.lang3.tuple.Pair;
44 import org.junit.jupiter.api.BeforeEach;
45 import org.junit.jupiter.api.Test;
46 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
47 import org.onap.policy.common.endpoints.event.comm.TopicSink;
48 import org.onap.policy.common.endpoints.event.comm.TopicSource;
49 import org.onap.policy.drools.controller.DroolsController;
50 import org.onap.policy.drools.system.PolicyController;
51 import org.onap.policy.drools.system.PolicyEngine;
52
53 class PoolingFeatureTest {
54
55     private static final String CONTROLLER1 = "controllerA";
56     private static final String CONTROLLER2 = "controllerB";
57     private static final String CONTROLLER_DISABLED = "controllerDisabled";
58     private static final String CONTROLLER_EX = "controllerException";
59     private static final String CONTROLLER_UNKNOWN = "controllerUnknown";
60
61     private static final String TOPIC1 = "topic.one";
62     private static final String TOPIC2 = "topic.two";
63
64     private static final String EVENT1 = "event.one";
65     private static final String EVENT2 = "event.two";
66
67     private static final Object OBJECT1 = new Object();
68     private static final Object OBJECT2 = new Object();
69
70     private Properties props;
71     private PolicyEngine engine;
72     private PolicyController controller1;
73     private PolicyController controller2;
74     private PolicyController controllerDisabled;
75     private PolicyController controllerException;
76     private PolicyController controllerUnknown;
77     private DroolsController drools1;
78     private DroolsController drools2;
79     private DroolsController droolsDisabled;
80     private List<Pair<PoolingManagerImpl, PoolingProperties>> managers;
81     private PoolingManagerImpl mgr1;
82     private PoolingManagerImpl mgr2;
83
84     private PoolingFeature pool;
85
86     /**
87      * Setup.
88      *
89      * @throws Exception exception
90      */
91     @BeforeEach
92     public void setUp() throws Exception {
93         props = initProperties();
94         engine = mock(PolicyEngine.class);
95         controller1 = mock(PolicyController.class);
96         controller2 = mock(PolicyController.class);
97         controllerDisabled = mock(PolicyController.class);
98         controllerException = mock(PolicyController.class);
99         controllerUnknown = mock(PolicyController.class);
100         drools1 = mock(DroolsController.class);
101         drools2 = mock(DroolsController.class);
102         droolsDisabled = mock(DroolsController.class);
103         managers = new LinkedList<>();
104
105         when(controller1.getName()).thenReturn(CONTROLLER1);
106         when(controller2.getName()).thenReturn(CONTROLLER2);
107         when(controllerDisabled.getName()).thenReturn(CONTROLLER_DISABLED);
108         when(controllerException.getName()).thenReturn(CONTROLLER_EX);
109         when(controllerUnknown.getName()).thenReturn(CONTROLLER_UNKNOWN);
110
111         pool = new PoolingFeatureImpl();
112
113         pool.beforeStart(engine);
114
115         pool.afterCreate(controller1);
116         pool.afterCreate(controller2);
117
118         mgr1 = managers.get(0).getLeft();
119         mgr2 = managers.get(1).getLeft();
120     }
121
122     @Test
123     void test() {
124         assertEquals(2, managers.size());
125     }
126
127     @Test
128     void testGetHost() {
129         String host = pool.getHost();
130         assertNotNull(host);
131
132         // create another and ensure it generates another host name
133         pool = new PoolingFeatureImpl();
134         String host2 = pool.getHost();
135         assertNotNull(host2);
136
137         assertNotEquals(host, host2);
138     }
139
140     @Test
141     void testGetSequenceNumber() {
142         assertEquals(0, pool.getSequenceNumber());
143     }
144
145     @Test
146     void testBeforeStartEngine() {
147         pool = new PoolingFeatureImpl();
148
149         assertFalse(pool.beforeStart(engine));
150     }
151
152     @Test
153     void testAfterCreate() {
154         managers.clear();
155         pool = new PoolingFeatureImpl();
156         pool.beforeStart(engine);
157
158         assertFalse(pool.afterCreate(controller1));
159         assertEquals(1, managers.size());
160
161         // duplicate
162         assertFalse(pool.afterCreate(controller1));
163         assertEquals(1, managers.size());
164
165         // second controller
166         assertFalse(pool.afterCreate(controller2));
167         assertEquals(2, managers.size());
168     }
169
170     @Test
171     void testAfterCreate_NotEnabled() {
172         managers.clear();
173         pool = new PoolingFeatureImpl();
174         pool.beforeStart(engine);
175
176         assertFalse(pool.afterCreate(controllerDisabled));
177         assertTrue(managers.isEmpty());
178     }
179
180     @Test
181     void testAfterCreate_PropertyEx() {
182         managers.clear();
183         pool = new PoolingFeatureImpl();
184         pool.beforeStart(engine);
185
186         assertThrows(PoolingFeatureRtException.class, () -> pool.afterCreate(controllerException));
187     }
188
189     @Test
190     void testAfterCreate_NoProps() {
191         pool = new PoolingFeatureImpl();
192
193         // did not perform globalInit, which is an error
194
195         assertThrows(PoolingFeatureRtException.class, () -> pool.afterCreate(controller1));
196     }
197
198     @Test
199     void testAfterCreate_NoFeatProps() {
200         managers.clear();
201         pool = new PoolingFeatureImpl();
202         pool.beforeStart(engine);
203
204         assertFalse(pool.afterCreate(controllerUnknown));
205         assertTrue(managers.isEmpty());
206     }
207
208     @Test
209     void testBeforeStart() throws Exception {
210         assertFalse(pool.beforeStart(controller1));
211         verify(mgr1).beforeStart();
212
213         // ensure it's still in the map by re-invoking
214         assertFalse(pool.beforeStart(controller1));
215         verify(mgr1, times(2)).beforeStart();
216
217         assertFalse(pool.beforeStart(controllerDisabled));
218     }
219
220     @Test
221     void testAfterStart() {
222         assertFalse(pool.afterStart(controller1));
223         verify(mgr1).afterStart();
224
225         // ensure it's still in the map by re-invoking
226         assertFalse(pool.afterStart(controller1));
227         verify(mgr1, times(2)).afterStart();
228
229         assertFalse(pool.afterStart(controllerDisabled));
230     }
231
232     @Test
233     void testBeforeStop() {
234         assertFalse(pool.beforeStop(controller1));
235         verify(mgr1).beforeStop();
236
237         // ensure it's still in the map by re-invoking
238         assertFalse(pool.beforeStop(controller1));
239         verify(mgr1, times(2)).beforeStop();
240
241         assertFalse(pool.beforeStop(controllerDisabled));
242     }
243
244     @Test
245     void testAfterStop() {
246         assertFalse(pool.afterStop(controller1));
247         verify(mgr1).afterStop();
248
249         assertFalse(pool.afterStop(controllerDisabled));
250
251         // count should be unchanged
252         verify(mgr1).afterStop();
253     }
254
255     @Test
256     void testAfterHalt() {
257         assertFalse(pool.afterHalt(controller1));
258         assertFalse(pool.afterHalt(controller1));
259
260         verify(mgr1, never()).afterStop();
261
262         assertFalse(pool.afterStop(controllerDisabled));
263     }
264
265     @Test
266     void testAfterShutdown() {
267         assertFalse(pool.afterShutdown(controller1));
268         assertFalse(pool.afterShutdown(controller1));
269
270         verify(mgr1, never()).afterStop();
271
272         assertFalse(pool.afterStop(controllerDisabled));
273     }
274
275     @Test
276     void testBeforeLock() {
277         assertFalse(pool.beforeLock(controller1));
278         verify(mgr1).beforeLock();
279
280         // ensure it's still in the map by re-invoking
281         assertFalse(pool.beforeLock(controller1));
282         verify(mgr1, times(2)).beforeLock();
283
284         assertFalse(pool.beforeLock(controllerDisabled));
285     }
286
287     @Test
288     void testAfterUnlock() {
289         assertFalse(pool.afterUnlock(controller1));
290         verify(mgr1).afterUnlock();
291
292         // ensure it's still in the map by re-invoking
293         assertFalse(pool.afterUnlock(controller1));
294         verify(mgr1, times(2)).afterUnlock();
295
296         assertFalse(pool.afterUnlock(controllerDisabled));
297     }
298
299     @Test
300     void testBeforeOffer() {
301         assertFalse(pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC1, EVENT1));
302         verify(mgr1).beforeOffer(TOPIC1, EVENT1);
303
304         // ensure that the args were captured
305         pool.beforeInsert(drools1, OBJECT1);
306         verify(mgr1).beforeInsert(TOPIC1, OBJECT1);
307
308
309         // ensure it's still in the map by re-invoking
310         assertFalse(pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC2, EVENT2));
311         verify(mgr1).beforeOffer(TOPIC2, EVENT2);
312
313         // ensure that the new args were captured
314         pool.beforeInsert(drools1, OBJECT2);
315         verify(mgr1).beforeInsert(TOPIC2, OBJECT2);
316
317
318         assertFalse(pool.beforeOffer(controllerDisabled, CommInfrastructure.UEB, TOPIC1, EVENT1));
319     }
320
321     @Test
322     void testBeforeOffer_NotFound() {
323         assertFalse(pool.beforeOffer(controllerDisabled, CommInfrastructure.UEB, TOPIC1, EVENT1));
324     }
325
326     @Test
327     void testBeforeOffer_MgrTrue() {
328
329         // manager will return true
330         when(mgr1.beforeOffer(any(), any())).thenReturn(true);
331
332         assertTrue(pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC1, EVENT1));
333         verify(mgr1).beforeOffer(TOPIC1, EVENT1);
334
335         // ensure it's still in the map by re-invoking
336         assertTrue(pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC2, EVENT2));
337         verify(mgr1).beforeOffer(TOPIC2, EVENT2);
338
339         assertFalse(pool.beforeOffer(controllerDisabled, CommInfrastructure.UEB, TOPIC1, EVENT1));
340     }
341
342     @Test
343     void testBeforeInsert() {
344         pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC1, EVENT1);
345         assertFalse(pool.beforeInsert(drools1, OBJECT1));
346         verify(mgr1).beforeInsert(TOPIC1, OBJECT1);
347
348         // ensure it's still in the map by re-invoking
349         pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC2, EVENT2);
350         assertFalse(pool.beforeInsert(drools1, OBJECT2));
351         verify(mgr1).beforeInsert(TOPIC2, OBJECT2);
352
353         pool.beforeOffer(controllerDisabled, CommInfrastructure.UEB, TOPIC2, EVENT2);
354         assertFalse(pool.beforeInsert(droolsDisabled, OBJECT1));
355     }
356
357     @Test
358     void testBeforeInsert_NoArgs() {
359
360         // call beforeInsert without beforeOffer
361         assertFalse(pool.beforeInsert(drools1, OBJECT1));
362         verify(mgr1, never()).beforeInsert(any(), any());
363
364         assertFalse(pool.beforeInsert(droolsDisabled, OBJECT1));
365         verify(mgr1, never()).beforeInsert(any(), any());
366     }
367
368     @Test
369     void testBeforeInsert_ArgEx() {
370         // generate exception
371         pool = new PoolingFeatureImpl() {
372             @Override
373             protected PolicyController getController(DroolsController droolsController) {
374                 throw new IllegalArgumentException();
375             }
376         };
377
378         pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC1, EVENT1);
379         assertFalse(pool.beforeInsert(drools1, OBJECT1));
380         verify(mgr1, never()).beforeInsert(any(), any());
381     }
382
383     @Test
384     void testBeforeInsert_StateEx() {
385         // generate exception
386         pool = new PoolingFeatureImpl() {
387             @Override
388             protected PolicyController getController(DroolsController droolsController) {
389                 throw new IllegalStateException();
390             }
391         };
392
393         pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC1, EVENT1);
394         assertFalse(pool.beforeInsert(drools1, OBJECT1));
395         verify(mgr1, never()).beforeInsert(any(), any());
396     }
397
398     @Test
399     void testBeforeInsert_NullController() {
400
401         // return null controller
402         pool = new PoolingFeatureImpl() {
403             @Override
404             protected PolicyController getController(DroolsController droolsController) {
405                 return null;
406             }
407         };
408
409         pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC1, EVENT1);
410         assertFalse(pool.beforeInsert(drools1, OBJECT1));
411         verify(mgr1, never()).beforeInsert(any(), any());
412     }
413
414     @Test
415     void testBeforeInsert_NotFound() {
416
417         pool.beforeOffer(controllerDisabled, CommInfrastructure.UEB, TOPIC2, EVENT2);
418         assertFalse(pool.beforeInsert(droolsDisabled, OBJECT1));
419     }
420
421     @Test
422     void testAfterOffer() {
423         // this will create OfferArgs
424         pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC1, EVENT1);
425
426         // this should clear them
427         assertFalse(pool.afterOffer(controller1, CommInfrastructure.UEB, TOPIC2, EVENT2, true));
428
429         assertFalse(pool.beforeInsert(drools1, OBJECT1));
430         verify(mgr1, never()).beforeInsert(any(), any());
431
432
433         assertFalse(pool.beforeInsert(droolsDisabled, OBJECT1));
434     }
435
436     @Test
437     void testDoManager() {
438         assertFalse(pool.beforeStart(controller1));
439         verify(mgr1).beforeStart();
440
441         // ensure it's still in the map by re-invoking
442         assertFalse(pool.beforeStart(controller1));
443         verify(mgr1, times(2)).beforeStart();
444
445
446         // different controller
447         assertFalse(pool.beforeStart(controller2));
448         verify(mgr2).beforeStart();
449
450         // ensure it's still in the map by re-invoking
451         assertFalse(pool.beforeStart(controller2));
452         verify(mgr2, times(2)).beforeStart();
453
454
455         assertFalse(pool.beforeStart(controllerDisabled));
456     }
457
458     @Test
459     void testDoManager_NotFound() {
460         assertFalse(pool.beforeStart(controllerDisabled));
461     }
462
463     @Test
464     void testDoManager_Ex() {
465
466         // generate exception
467         doThrow(new RuntimeException()).when(mgr1).beforeStart();
468
469         assertThrows(RuntimeException.class, () -> pool.beforeStart(controller1));
470     }
471
472     private Properties initProperties() {
473         Properties props = new Properties();
474
475         initProperties(props, "A", 0);
476         initProperties(props, "B", 1);
477         initProperties(props, "Exception", 2);
478
479         props.setProperty("pooling.controllerDisabled.enabled", "false");
480
481         props.setProperty("pooling.controllerException.offline.queue.limit", "INVALID NUMBER");
482
483         return props;
484     }
485
486     private void initProperties(Properties props, String suffix, int offset) {
487         props.setProperty("pooling.controller" + suffix + ".topic", "topic." + suffix);
488         props.setProperty("pooling.controller" + suffix + ".enabled", "true");
489         props.setProperty("pooling.controller" + suffix + ".offline.queue.limit", String.valueOf(5 + offset));
490         props.setProperty("pooling.controller" + suffix + ".offline.queue.age.milliseconds",
491                         String.valueOf(100 + offset));
492         props.setProperty("pooling.controller" + suffix + ".start.heartbeat.milliseconds", String.valueOf(10 + offset));
493         props.setProperty("pooling.controller" + suffix + ".reactivate.milliseconds", String.valueOf(20 + offset));
494         props.setProperty("pooling.controller" + suffix + ".identification.milliseconds", String.valueOf(30 + offset));
495         props.setProperty("pooling.controller" + suffix + ".active.heartbeat.milliseconds",
496                         String.valueOf(40 + offset));
497         props.setProperty("pooling.controller" + suffix + ".inter.heartbeat.milliseconds", String.valueOf(50 + offset));
498     }
499
500     /**
501      * Feature with overrides.
502      */
503     private class PoolingFeatureImpl extends PoolingFeature {
504
505         @Override
506         protected Properties getProperties(String featName) {
507             if (PoolingProperties.FEATURE_NAME.equals(featName)) {
508                 return props;
509             } else {
510                 throw new IllegalArgumentException("unknown feature name");
511             }
512         }
513
514         @Override
515         protected PoolingManagerImpl makeManager(String host, PolicyController controller, PoolingProperties props,
516                         CountDownLatch activeLatch) {
517
518             PoolingManagerImpl mgr = mock(PoolingManagerImpl.class);
519
520             managers.add(Pair.of(mgr, props));
521
522             return mgr;
523         }
524
525         @Override
526         protected PolicyController getController(DroolsController droolsController) {
527             if (droolsController == drools1) {
528                 return controller1;
529             } else if (droolsController == drools2) {
530                 return controller2;
531             } else if (droolsController == droolsDisabled) {
532                 return controllerDisabled;
533             } else {
534                 throw new IllegalArgumentException("unknown drools controller");
535             }
536         }
537
538         @Override
539         protected List<TopicSource> initTopicSources(Properties props) {
540             return Collections.emptyList();
541         }
542
543         @Override
544         protected List<TopicSink> initTopicSinks(Properties props) {
545             return Collections.emptyList();
546         }
547     }
548 }