Removing deprecated DMAAP library
[policy/drools-pdp.git] / policy-core / src / test / java / org / onap / policy / drools / core / DroolsContainerTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * policy-core
4  * ================================================================================
5  * Copyright (C) 2017-2021 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.core;
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.assertNotNull;
27 import static org.junit.jupiter.api.Assertions.assertSame;
28 import static org.junit.jupiter.api.Assertions.assertTrue;
29 import static org.mockito.ArgumentMatchers.any;
30 import static org.mockito.Mockito.mock;
31 import static org.mockito.Mockito.when;
32
33 import java.nio.file.Paths;
34 import java.util.Arrays;
35 import java.util.Collection;
36 import java.util.List;
37 import java.util.Objects;
38 import java.util.concurrent.LinkedBlockingQueue;
39 import java.util.concurrent.TimeUnit;
40 import org.drools.core.WorkingMemory;
41 import org.junit.jupiter.api.BeforeAll;
42 import org.junit.jupiter.api.Test;
43 import org.onap.policy.drools.util.KieUtils;
44
45 /**
46  * These tests focus on the following classes.
47  *     PolicyContainer
48  *     PolicySession
49  *     PolicySessionFeatureAPI
50  */
51 public class DroolsContainerTest {
52
53     private static final long TIMEOUT_SEC = 5;
54
55     /**
56      * This test is centered around the creation of a 'PolicyContainer'
57      * and 'PolicySession', and the updating of that container to a new
58      * version.
59      */
60     @BeforeAll
61     public static void setUp() throws Exception {
62         KieUtils.installArtifact(
63                 Paths.get("src/test/resources/drools-artifact-1.1/src/main/resources/META-INF/kmodule.xml").toFile(),
64                 Paths.get("src/test/resources/drools-artifact-1.1/pom.xml").toFile(),
65                 "src/main/resources/rules/org/onap/policy/drools/core/test/",
66                 Paths.get("src/test/resources/drools-artifact-1.1/src/main/resources/rules.drl").toFile());
67
68         KieUtils.installArtifact(
69                 Paths.get("src/test/resources/drools-artifact-1.2/src/main/resources/META-INF/kmodule.xml").toFile(),
70                 Paths.get("src/test/resources/drools-artifact-1.2/pom.xml").toFile(),
71                 "src/main/resources/rules/org/onap/policy/drools/core/test/",
72                 Paths.get("src/test/resources/drools-artifact-1.2/src/main/resources/rules.drl").toFile());
73     }
74
75     /**
76      * This test is centered around the creation of a 'PolicyContainer'
77      * and 'PolicySession', and the updating of that container to a new
78      * version.
79      */
80     @Test
81     void createAndUpdate() throws Exception {
82         // make sure feature log starts out clean
83         PolicySessionFeatureApiMock.getLog();
84
85         // run 'globalInit', and verify expected feature hook fired
86         PolicyContainer.globalInit(new String[0]);
87         assertEquals(List.of("globalInit"),
88                 PolicySessionFeatureApiMock.getLog());
89
90         // initial conditions -- there should be no containers
91         assertEquals(0, PolicyContainer.getPolicyContainers().size());
92
93         // create the container, and start it
94         PolicyContainer container =
95                 new PolicyContainer("org.onap.policy.drools-pdp",
96                         "drools-artifact1", "17.1.0-SNAPSHOT");
97         container.start();
98         assertTrue(container.isAlive());
99
100         // verify expected feature hooks fired
101         assertEquals(Arrays.asList("activatePolicySession",
102                 "newPolicySession",
103                 "selectThreadModel"),
104                 PolicySessionFeatureApiMock.getLog());
105
106         // this container should be on the list
107         {
108             Collection<PolicyContainer> containers =
109                     PolicyContainer.getPolicyContainers();
110             assertEquals(1, containers.size());
111             assertTrue(containers.contains(container));
112         }
113
114         // verify initial container attributes
115         assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT",
116                 container.getName());
117         assertEquals("org.onap.policy.drools-pdp", container.getGroupId());
118         assertEquals("drools-artifact1", container.getArtifactId());
119         assertEquals("17.1.0-SNAPSHOT", container.getVersion());
120
121         try {
122             // fetch the session, and verify that it exists
123             PolicySession session = container.getPolicySession("session1");
124             assertNotNull(session);
125
126             // get all sessions, and verify that this one is the only one
127             {
128                 Collection<PolicySession> sessions = container.getPolicySessions();
129                 assertEquals(1, sessions.size());
130                 assertTrue(sessions.contains(session));
131             }
132
133             // verify session attributes
134             assertEquals(container, session.getContainer());
135             assertEquals("session1", session.getName());
136             assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT:session1",
137                     session.getFullName());
138
139             // insert a new fact
140             LinkedBlockingQueue<Integer> result = new LinkedBlockingQueue<>();
141             session.getKieSession().insert(Arrays.asList(3, 8, 2));
142             session.getKieSession().insert(result);
143
144             // the Drools rules should add 3 + 8 + 2, and store 13 in a[0]
145             assertEquals(13, Objects.requireNonNull(result.poll(TIMEOUT_SEC, TimeUnit.SECONDS)).intValue());
146
147             // update the container to a new version --
148             // the rules will then multiply values rather than add them
149             assertEquals("[]",
150                 container.updateToVersion("17.2.0-SNAPSHOT"));
151
152             // verify expected feature hooks fired
153             assertEquals(List.of("selectThreadModel"),
154                     PolicySessionFeatureApiMock.getLog());
155
156             // verify new container attributes
157             assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.2.0-SNAPSHOT",
158                     container.getName());
159             assertEquals("org.onap.policy.drools-pdp", container.getGroupId());
160             assertEquals("drools-artifact1", container.getArtifactId());
161             assertEquals("17.2.0-SNAPSHOT", container.getVersion());
162
163             // verify new session attributes
164             assertEquals(container, session.getContainer());
165             assertEquals("session1", session.getName());
166             assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.2.0-SNAPSHOT:session1",
167                     session.getFullName());
168
169             // the updated rules should now multiply 3 * 8 * 2, and return 48
170
171             result = new LinkedBlockingQueue<>();
172             container.insert("session1", Arrays.asList(3, 8, 2));
173             container.insert("session1", result);
174
175             assertEquals(48, Objects.requireNonNull(result.poll(TIMEOUT_SEC, TimeUnit.SECONDS)).intValue());
176
177             /*
178              * verify that default KiePackages have been added by testing that
179              * 'DroolsRunnable' is functioning. Also verifies that DroolsExecutor works by
180              * using it to inject the runnable, though we have to mock the WorkingMemory
181              * object since I don't know how to obtain it from the kieSession
182              */
183
184             WorkingMemory wm = mock(WorkingMemory.class);
185             when(wm.insert(any())).thenAnswer(ans -> {
186                 Object object = ans.getArgument(0);
187                 return container.getPolicySession("session1").getKieSession().insert(object);
188             });
189
190             DroolsExecutor executor = new DroolsExecutor(wm);
191
192             final LinkedBlockingQueue<String> lbq = new LinkedBlockingQueue<>();
193             executor.execute(() -> lbq.add("DroolsRunnable String"));
194             assertEquals("DroolsRunnable String", lbq.poll(TIMEOUT_SEC, TimeUnit.SECONDS));
195
196             executor.execute(() -> lbq.add("another DroolsRunnable String"));
197             assertEquals("another DroolsRunnable String", lbq.poll(TIMEOUT_SEC, TimeUnit.SECONDS));
198
199         } finally {
200             container.shutdown();
201             assertFalse(container.isAlive());
202
203             // verify expected feature hooks fired
204             assertEquals(List.of("disposeKieSession"),
205                     PolicySessionFeatureApiMock.getLog());
206         }
207
208         // final conditions -- there should be no containers
209         assertEquals(0, PolicyContainer.getPolicyContainers().size());
210     }
211
212     /**
213      * This test create a 'PolicyContainer' and 'PolicySession', and verifies
214      * their behavior, but uses alternate interfaces to increase code coverage.
215      * In addition, feature hook invocations will trigger exceptions in this
216      * test, also to increase code coverage.
217      */
218     @Test
219     void versionList() throws Exception {
220         // make sure feature log starts out clean
221         PolicySessionFeatureApiMock.getLog();
222
223         // trigger exceptions in all feature hooks
224         PolicySessionFeatureApiMock.setExceptionTrigger(true);
225
226         // run 'globalInit', and verify expected feature hook fired
227         PolicyContainer.globalInit(new String[0]);
228         assertEquals(List.of("globalInit-exception"),
229                 PolicySessionFeatureApiMock.getLog());
230
231         // initial conditions -- there should be no containers
232         assertEquals(0, PolicyContainer.getPolicyContainers().size());
233
234         String versionList =
235                 "17.3.0-SNAPSHOT,17.1.0-SNAPSHOT,17.2.0-SNAPSHOT";
236
237         // versions should be tried in order -- the 17.1.0-SNAPSHOT should "win",
238         // given the fact that '17.3.0-SNAPSHOT' doesn't exist
239         PolicyContainer container =
240                 new PolicyContainer("org.onap.policy.drools-pdp",
241                         "drools-artifact1", versionList);
242         // the following should be equivalent to 'container.start()'
243         PolicyContainer.activate();
244         assertTrue(container.isAlive());
245
246         // verify expected feature hooks fired
247         assertEquals(Arrays.asList("activatePolicySession-exception",
248                 "newPolicySession-exception",
249                 "selectThreadModel-exception"),
250                 PolicySessionFeatureApiMock.getLog());
251
252         // this container should be on the list
253         {
254             Collection<PolicyContainer> containers =
255                     PolicyContainer.getPolicyContainers();
256             assertEquals(1, containers.size());
257             assertTrue(containers.contains(container));
258         }
259
260         // verify initial container attributes
261         assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT",
262                 container.getName());
263         assertEquals("org.onap.policy.drools-pdp", container.getGroupId());
264         assertEquals("drools-artifact1", container.getArtifactId());
265         assertEquals("17.1.0-SNAPSHOT", container.getVersion());
266
267         // some container adjunct tests
268         {
269             Object bogusAdjunct = new Object();
270
271             // initially, no adjunct
272             assertSame(null, container.getAdjunct(this));
273
274             // set and verify adjunct
275             container.setAdjunct(this, bogusAdjunct);
276             assertSame(bogusAdjunct, container.getAdjunct(this));
277
278             // clear and verify adjunct
279             container.setAdjunct(this, null);
280             assertSame(null, container.getAdjunct(this));
281         }
282
283         try {
284             // fetch the session, and verify that it exists
285             PolicySession session = container.getPolicySession("session1");
286             assertNotNull(session);
287
288             // get all sessions, and verify that this one is the only one
289             {
290                 Collection<PolicySession> sessions = container.getPolicySessions();
291                 assertEquals(1, sessions.size());
292                 assertTrue(sessions.contains(session));
293             }
294
295             // verify session attributes
296             assertEquals(container, session.getContainer());
297             assertEquals("session1", session.getName());
298             assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT:session1",
299                     session.getFullName());
300
301             // some session adjunct tests
302             {
303                 Object bogusAdjunct = new Object();
304
305                 // initially, no adjunct
306                 assertSame(null, session.getAdjunct(this));
307
308                 // set and verify adjunct
309                 session.setAdjunct(this, bogusAdjunct);
310                 assertSame(bogusAdjunct, session.getAdjunct(this));
311
312                 // clear and verify adjunct
313                 session.setAdjunct(this, null);
314                 assertSame(null, session.getAdjunct(this));
315             }
316
317             // insert a new fact (using 'insertAll')
318             LinkedBlockingQueue<Integer> result = new LinkedBlockingQueue<>();
319             container.insertAll(Arrays.asList(7, 3, 4));
320             container.insertAll(result);
321
322             // the Drools rules should add 7 + 3 + 4, and store 14 in a[0]
323             assertEquals(14, Objects.requireNonNull(result.poll(TIMEOUT_SEC, TimeUnit.SECONDS)).intValue());
324
325             // exercise some more API methods
326             assertEquals(container.getClassLoader(),
327                     container.getKieContainer().getClassLoader());
328         } finally {
329             // should be equivalent to 'shutdown' without persistence
330             container.destroy();
331             assertFalse(container.isAlive());
332
333             // verify expected feature hooks fired
334             assertEquals(List.of("destroyKieSession-exception"),
335                     PolicySessionFeatureApiMock.getLog());
336
337             // clear exception trigger
338             PolicySessionFeatureApiMock.setExceptionTrigger(false);
339         }
340
341         // final conditions -- there should be no containers
342         assertEquals(0, PolicyContainer.getPolicyContainers().size());
343     }
344 }