Removing deprecated DMAAP library
[policy/drools-pdp.git] / policy-management / src / test / java / org / onap / policy / drools / system / PolicyControllerFactoryTest.java
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 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.system;
23
24 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
25 import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
26 import static org.junit.jupiter.api.Assertions.assertEquals;
27 import static org.junit.jupiter.api.Assertions.assertNotNull;
28 import static org.junit.jupiter.api.Assertions.assertSame;
29 import static org.mockito.ArgumentMatchers.any;
30 import static org.mockito.Mockito.mock;
31 import static org.mockito.Mockito.never;
32 import static org.mockito.Mockito.times;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.when;
35 import static org.onap.policy.drools.properties.DroolsPropertyConstants.PROPERTY_CONTROLLER_TYPE;
36
37 import java.util.Arrays;
38 import java.util.Collections;
39 import java.util.Comparator;
40 import java.util.List;
41 import java.util.Properties;
42 import org.junit.jupiter.api.BeforeEach;
43 import org.junit.jupiter.api.Test;
44 import org.onap.policy.common.utils.gson.GsonTestUtils;
45 import org.onap.policy.drools.controller.DroolsController;
46 import org.onap.policy.drools.controller.internal.NullDroolsController;
47 import org.onap.policy.drools.features.DroolsControllerFeatureApi;
48 import org.onap.policy.drools.features.PolicyControllerFeatureApi;
49 import org.onap.policy.drools.protocol.coders.TopicCoderFilterConfiguration;
50 import org.onap.policy.drools.protocol.configuration.DroolsConfiguration;
51 import org.onap.policy.drools.system.internal.AggregatedPolicyController;
52
53 class PolicyControllerFactoryTest {
54     private static final String POLICY_CONTROLLER_BUILDER_TAG = "PolicyControllerFactoryTest";
55
56     private static final String MY_NAME = "my-name-a";
57     private static final String MY_NAME2 = "my-name-b";
58
59     private static final String ARTIFACT1 = "artifact-a";
60     private static final String GROUP1 = "group-a";
61     private static final String VERSION1 = "version-a";
62
63     private static final String ARTIFACT2 = "artifact-b";
64     private static final String GROUP2 = "group-b";
65     private static final String VERSION2 = "version-b";
66
67     private static final String FEATURE1 = "feature-a";
68     private static final String FEATURE2 = "feature-b";
69
70     private PolicyController controller;
71     private PolicyController controller2;
72     private Properties properties;
73     private DroolsController drools;
74     private DroolsController drools2;
75     private DroolsConfiguration config;
76     private PolicyControllerFeatureApi feature1;
77     private PolicyControllerFeatureApi feature2;
78     private List<PolicyControllerFeatureApi> providers;
79     private IndexedPolicyControllerFactory ipc;
80
81     /**
82      * Initializes the object to be tested.
83      */
84     @BeforeEach
85     public void setUp() {
86         controller = mock(PolicyController.class);
87         controller2 = mock(PolicyController.class);
88         properties = new Properties();
89         drools = mock(DroolsController.class);
90         drools2 = mock(DroolsController.class);
91         config = mock(DroolsConfiguration.class);
92         feature1 = mock(PolicyControllerFeatureApi.class);
93         feature2 = mock(PolicyControllerFeatureApi.class);
94         providers = Arrays.asList(feature1, feature2);
95
96         when(feature1.getName()).thenReturn(FEATURE1);
97         when(feature2.getName()).thenReturn(FEATURE2);
98
99         when(drools.getArtifactId()).thenReturn(ARTIFACT1);
100         when(drools.getGroupId()).thenReturn(GROUP1);
101         when(drools.getVersion()).thenReturn(VERSION1);
102
103         when(drools2.getArtifactId()).thenReturn(ARTIFACT2);
104         when(drools2.getGroupId()).thenReturn(GROUP2);
105         when(drools2.getVersion()).thenReturn(VERSION2);
106
107         when(controller.getName()).thenReturn(MY_NAME);
108         when(controller.getDrools()).thenReturn(drools);
109         when(controller.updateDrools(any())).thenReturn(true);
110
111         when(controller2.getName()).thenReturn(MY_NAME2);
112         when(controller2.getDrools()).thenReturn(drools2);
113         when(controller2.updateDrools(any())).thenReturn(true);
114
115         ipc = new IndexedPolicyControllerFactoryImpl();
116     }
117
118     @Test
119     void testFactory() {
120         // use a REAL object instead of an Impl
121         ipc = new IndexedPolicyControllerFactory();
122         assertNotNull(ipc.getProviders());
123     }
124
125     @Test
126     void testBuild() {
127         assertEquals(controller, ipc.build(MY_NAME, properties));
128
129         // re-build - should not create another one
130         assertEquals(controller, ipc.build(MY_NAME, properties));
131
132         // brained
133         setUp();
134         when(drools.isBrained()).thenReturn(true);
135         ipc.build(MY_NAME, properties);
136     }
137
138     @Test
139     void testSerialize() {
140         assertEquals(controller, ipc.build(MY_NAME, properties));
141
142         new GsonTestUtils().compareGson(ipc, PolicyControllerFactoryTest.class);
143     }
144
145     @Test
146     void testPatchStringDroolsConfiguration() {
147         // unknown controller
148         assertThatIllegalArgumentException().isThrownBy(() -> ipc.patch(MY_NAME, config));
149
150         /*
151          * Build controller to be used by remaining tests.
152          */
153         ipc.build(MY_NAME, properties);
154
155         // null name
156         String nullName = null;
157         assertThatIllegalArgumentException().isThrownBy(() -> ipc.patch(nullName, config));
158
159         // empty name
160         assertThatIllegalArgumentException().isThrownBy(() -> ipc.patch("", config));
161
162         // success
163         ipc.patch(MY_NAME, config);
164         verify(controller).updateDrools(config);
165
166         // create a factory whose get() method returns null
167         ipc = new IndexedPolicyControllerFactory() {
168             @Override
169             public PolicyController get(String name) {
170                 return null;
171             }
172         };
173         ipc.build(MY_NAME, properties);
174         assertThatIllegalArgumentException().isThrownBy(() -> ipc.patch(MY_NAME, config));
175     }
176
177     @Test
178     void testPatchPolicyControllerDroolsConfiguration() {
179         ipc.patch(controller, config);
180         verify(controller).updateDrools(config);
181
182         // null controller
183         PolicyController nullCtlr = null;
184         assertThatIllegalArgumentException().isThrownBy(() -> ipc.patch(nullCtlr, config));
185
186         // null config
187         assertThatIllegalArgumentException().isThrownBy(() -> ipc.patch(controller, null));
188
189         // brained
190         when(drools.isBrained()).thenReturn(true);
191         ipc.patch(controller, config);
192
193         // update failed
194         when(controller.updateDrools(config)).thenReturn(false);
195         assertThatIllegalArgumentException().isThrownBy(() -> ipc.patch(controller, config));
196     }
197
198     @Test
199     void testShutdownString() {
200         // null name
201         String nullName = null;
202         assertThatIllegalArgumentException().isThrownBy(() -> ipc.shutdown(nullName));
203
204         // empty name
205         assertThatIllegalArgumentException().isThrownBy(() -> ipc.shutdown(""));
206
207         // unknown controller
208         ipc.shutdown(MY_NAME);
209         verify(controller, never()).shutdown();
210
211         // valid controller
212         ipc.build(MY_NAME, properties);
213         ipc.shutdown(MY_NAME);
214         verify(controller).shutdown();
215     }
216
217     @Test
218     void testShutdownPolicyController() {
219         ipc.build(MY_NAME, properties);
220
221         ipc.shutdown(controller);
222
223         verify(controller).shutdown();
224
225         // should no longer be managed
226         assertThatIllegalArgumentException().isThrownBy(() -> ipc.get(MY_NAME));
227     }
228
229     @Test
230     void testShutdown() {
231         ipc.build(MY_NAME, properties);
232         ipc.build(MY_NAME2, properties);
233
234         ipc.shutdown();
235
236         verify(controller).shutdown();
237         verify(controller2).shutdown();
238
239         // should no longer be managed
240         assertThatIllegalArgumentException().isThrownBy(() -> ipc.get(MY_NAME));
241         assertThatIllegalArgumentException().isThrownBy(() -> ipc.get(MY_NAME2));
242     }
243
244     @Test
245     void testUnmanage() {
246         ipc.build(MY_NAME, properties);
247         ipc.build(MY_NAME2, properties);
248
249         ipc.shutdown(MY_NAME);
250
251         verify(controller).shutdown();
252         verify(controller2, never()).shutdown();
253
254         // should no longer be managed
255         assertThatIllegalArgumentException().isThrownBy(() -> ipc.get(MY_NAME));
256
257         // should still be managed
258         assertEquals(controller2, ipc.get(MY_NAME2));
259
260         // null controller
261         PolicyController nullCtlr = null;
262         assertThatIllegalArgumentException().isThrownBy(() -> ipc.shutdown(nullCtlr));
263
264         // unknown controller
265         ipc.shutdown(controller);
266         verify(controller, times(2)).shutdown();
267     }
268
269     @Test
270     void testDestroyString() {
271         // null name
272         String nullName = null;
273         assertThatIllegalArgumentException().isThrownBy(() -> ipc.destroy(nullName));
274
275         // empty name
276         assertThatIllegalArgumentException().isThrownBy(() -> ipc.destroy(""));
277
278         // unknown controller
279         ipc.destroy(MY_NAME);
280         verify(controller, never()).halt();
281
282         // valid controller
283         ipc.build(MY_NAME, properties);
284         ipc.destroy(MY_NAME);
285         verify(controller).halt();
286     }
287
288     @Test
289     void testDestroyPolicyController() {
290         ipc.build(MY_NAME, properties);
291
292         ipc.destroy(controller);
293
294         verify(controller).halt();
295
296         // should no longer be managed
297         assertThatIllegalArgumentException().isThrownBy(() -> ipc.get(MY_NAME));
298     }
299
300     @Test
301     void testDestroy() {
302         ipc.build(MY_NAME, properties);
303         ipc.build(MY_NAME2, properties);
304
305         ipc.destroy();
306
307         verify(controller).halt();
308         verify(controller2).halt();
309
310         // should no longer be managed
311         assertThatIllegalArgumentException().isThrownBy(() -> ipc.get(MY_NAME));
312         assertThatIllegalArgumentException().isThrownBy(() -> ipc.get(MY_NAME2));
313     }
314
315     @Test
316     void testGetString() {
317         // unknown name
318         assertThatIllegalArgumentException().isThrownBy(() -> ipc.get(MY_NAME));
319
320         ipc.build(MY_NAME, properties);
321         ipc.build(MY_NAME2, properties);
322
323         assertEquals(controller, ipc.get(MY_NAME));
324         assertEquals(controller2, ipc.get(MY_NAME2));
325
326         // null name
327         String nullName = null;
328         assertThatIllegalArgumentException().isThrownBy(() -> ipc.get(nullName));
329
330         // empty name
331         assertThatIllegalArgumentException().isThrownBy(() -> ipc.get(""));
332     }
333
334     @Test
335     void testGetStringString_testToKey() {
336         // unknown controller
337         assertThatIllegalArgumentException().isThrownBy(() -> ipc.get(GROUP1, ARTIFACT1));
338
339         when(drools.isBrained()).thenReturn(true);
340         when(drools2.isBrained()).thenReturn(true);
341
342         ipc.build(MY_NAME, properties);
343         ipc.build(MY_NAME2, properties);
344
345         assertEquals(controller, ipc.get(GROUP1, ARTIFACT1));
346         assertEquals(controller2, ipc.get(GROUP2, ARTIFACT2));
347
348         // null group
349         assertThatIllegalArgumentException().isThrownBy(() -> ipc.get(null, ARTIFACT1));
350
351         // empty group
352         assertThatIllegalArgumentException().isThrownBy(() -> ipc.get("", ARTIFACT1));
353
354         // null artifact
355         assertThatIllegalArgumentException().isThrownBy(() -> ipc.get(GROUP1, null));
356
357         // empty artifact
358         assertThatIllegalArgumentException().isThrownBy(() -> ipc.get(GROUP1, ""));
359     }
360
361     @Test
362     void testGetDroolsController() {
363         // unknown controller
364         assertThatIllegalStateException().isThrownBy(() -> ipc.get(drools));
365
366         when(drools.isBrained()).thenReturn(true);
367         when(drools2.isBrained()).thenReturn(true);
368
369         ipc.build(MY_NAME, properties);
370         ipc.build(MY_NAME2, properties);
371
372         assertEquals(controller, ipc.get(drools));
373         assertEquals(controller2, ipc.get(drools2));
374
375         // null controller
376         DroolsController nullDrools = null;
377         assertThatIllegalArgumentException().isThrownBy(() -> ipc.get(nullDrools));
378     }
379
380     @Test
381     void testInventory() {
382         ipc.build(MY_NAME, properties);
383         ipc.build(MY_NAME2, properties);
384
385         List<PolicyController> lst = ipc.inventory();
386         lst.sort(Comparator.comparing(PolicyController::getName));
387         assertEquals(Arrays.asList(controller, controller2), lst);
388     }
389
390     @Test
391     void testGetFeatures() {
392         assertEquals(Arrays.asList(FEATURE1, FEATURE2), ipc.getFeatures());
393     }
394
395     @Test
396     void testGetFeatureProviders() {
397         assertEquals(providers, ipc.getFeatureProviders());
398     }
399
400     @Test
401     void testGetFeatureProvider() {
402         // null name
403         assertThatIllegalArgumentException().isThrownBy(() -> ipc.getFeatureProvider(null));
404
405         // empty name
406         assertThatIllegalArgumentException().isThrownBy(() -> ipc.getFeatureProvider(""));
407
408         // unknown name
409         assertThatIllegalArgumentException().isThrownBy(() -> ipc.getFeatureProvider("unknown-feature"));
410
411         assertEquals(feature1, ipc.getFeatureProvider(FEATURE1));
412         assertEquals(feature2, ipc.getFeatureProvider(FEATURE2));
413     }
414
415     @Test
416     void testControllerType() {
417         PolicyControllerFactory factory = new IndexedPolicyControllerFactory();
418         Properties props = new Properties();
419
420         // this should build an 'AggregatedPolicyController'
421         final String name1 = "ctrl1";
422         PolicyController ctrl1 = factory.build(name1, props);
423
424         // this should build a 'TestPolicyController'
425         final String name2 = "ctrl2";
426         props.setProperty(PROPERTY_CONTROLLER_TYPE, POLICY_CONTROLLER_BUILDER_TAG);
427         PolicyController ctrl2 = factory.build(name2, props);
428
429         // verify controller types
430         assertSame(AggregatedPolicyController.class, ctrl1.getClass());
431         assertSame(TestPolicyController.class, ctrl2.getClass());
432         assertSame(NullDroolsController.class, ctrl2.getDrools().getClass());
433
434         // verify controller lookups
435         assertSame(ctrl1, factory.get(name1));
436         assertSame(ctrl2, factory.get(name2));
437     }
438
439     /**
440      * Factory with overrides.
441      */
442     private class IndexedPolicyControllerFactoryImpl extends IndexedPolicyControllerFactory {
443
444         @Override
445         protected PolicyController newPolicyController(String name, Properties properties) {
446             if (MY_NAME.equals(name)) {
447                 return controller;
448
449             } else if (MY_NAME2.equals(name)) {
450                 return controller2;
451
452             } else {
453                 throw new IllegalArgumentException("unknown controller name: " + name);
454
455             }
456         }
457
458         @Override
459         protected List<PolicyControllerFeatureApi> getProviders() {
460             return providers;
461         }
462     }
463
464     /**
465      * This class provides an alternate PolicyController implementation,
466      * for the purpose of easy identification within a junit test.
467      */
468     public static class TestPolicyController extends AggregatedPolicyController {
469         public TestPolicyController(String name, Properties properties) {
470             super(name, properties);
471         }
472     }
473
474     /**
475      * An instance of this class is created by 'IndexedPolicyControllerFactory',
476      * using features. It does the build operation when the value of the
477      * 'controller.type' property matches the value of POLICY_CONTROLLER_BUILDER_TAG.
478      */
479     public static class PolicyBuilder implements PolicyControllerFeatureApi {
480         @Override
481         public int getSequenceNumber() {
482             return 1;
483         }
484
485         @Override
486         public PolicyController beforeInstance(String name, Properties properties) {
487             if (POLICY_CONTROLLER_BUILDER_TAG.equals(properties.getProperty(PROPERTY_CONTROLLER_TYPE))) {
488                 return new TestPolicyController(name, properties);
489             }
490             return null;
491         }
492     }
493
494     /**
495      * An instance of this class is created by 'IndexedDroolsControllerFactory',
496      * using features. It does the build operation when the value of the
497      * 'controller.type' property matches the value of POLICY_CONTROLLER_BUILDER_TAG.
498      */
499     public static class DroolsBuilder implements DroolsControllerFeatureApi {
500         @Override
501         public int getSequenceNumber() {
502             return 1;
503         }
504
505         @Override
506         public DroolsController beforeInstance(Properties properties,
507                 String groupId, String artifactId, String version,
508                 List<TopicCoderFilterConfiguration> decoderConfigurations,
509                 List<TopicCoderFilterConfiguration> encoderConfigurations) {
510
511             if (POLICY_CONTROLLER_BUILDER_TAG.equals(properties.getProperty(PROPERTY_CONTROLLER_TYPE))) {
512                 return new NullDroolsController();
513             }
514             return null;
515         }
516     }
517 }