b904fb1d43cb4adbf2a7aac34de511a231516466
[policy/apex-pdp.git] / services / services-engine / src / test / java / org / onap / policy / apex / service / engine / runtime / impl / EngineWorkerTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2018 Ericsson. All rights reserved.
4  *  Modifications Copyright (C) 2020,2022 Nordix Foundation.
5  *  Modifications Copyright (C) 2021-2022 Bell Canada Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * SPDX-License-Identifier: Apache-2.0
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.policy.apex.service.engine.runtime.impl;
24
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertFalse;
27 import static org.junit.Assert.assertNotNull;
28 import static org.junit.Assert.assertNull;
29 import static org.junit.Assert.assertTrue;
30 import static org.junit.Assert.fail;
31
32 import java.io.ByteArrayInputStream;
33 import java.io.IOException;
34 import java.util.concurrent.BlockingQueue;
35 import java.util.concurrent.LinkedBlockingQueue;
36 import org.junit.After;
37 import org.junit.AfterClass;
38 import org.junit.BeforeClass;
39 import org.junit.Test;
40 import org.onap.policy.apex.context.parameters.ContextParameterConstants;
41 import org.onap.policy.apex.context.parameters.ContextParameters;
42 import org.onap.policy.apex.context.parameters.DistributorParameters;
43 import org.onap.policy.apex.context.parameters.LockManagerParameters;
44 import org.onap.policy.apex.context.parameters.PersistorParameters;
45 import org.onap.policy.apex.context.parameters.SchemaParameters;
46 import org.onap.policy.apex.core.engine.EngineParameterConstants;
47 import org.onap.policy.apex.core.engine.EngineParameters;
48 import org.onap.policy.apex.core.engine.ExecutorParameters;
49 import org.onap.policy.apex.core.infrastructure.threading.ApplicationThreadFactory;
50 import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
51 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
52 import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
53 import org.onap.policy.apex.model.basicmodel.handling.ApexModelReader;
54 import org.onap.policy.apex.model.basicmodel.service.ModelService;
55 import org.onap.policy.apex.model.enginemodel.concepts.AxEngineState;
56 import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
57 import org.onap.policy.apex.service.engine.event.ApexEvent;
58 import org.onap.policy.apex.service.engine.main.ApexPolicyStatisticsManager;
59 import org.onap.policy.common.parameters.ParameterService;
60 import org.onap.policy.common.utils.resources.TextFileUtils;
61 import org.onap.policy.common.utils.services.Registry;
62
63 /**
64  * Test the engine worker class.
65  */
66 public class EngineWorkerTest {
67     private final ApplicationThreadFactory atFactory = new ApplicationThreadFactory("apex-engine-service", 512);
68
69     private static String simpleModelString;
70     private static String differentModelString;
71     private static AxPolicyModel simpleModel;
72
73     /**
74      * Read the models into strings.
75      *
76      * @throws IOException on model reading errors
77      * @throws ApexModelException on model reading exceptions
78      */
79     @BeforeClass
80     public static void readSimpleModel() throws IOException, ApexModelException {
81         simpleModelString = TextFileUtils.getTextFileAsString("src/test/resources/policymodels/SmallModel.json");
82
83         differentModelString =
84                 TextFileUtils.getTextFileAsString("src/test/resources/policymodels/SmallModelDifferent.json");
85
86         final ApexModelReader<AxPolicyModel> modelReader = new ApexModelReader<>(AxPolicyModel.class);
87         simpleModel = modelReader.read(new ByteArrayInputStream(simpleModelString.getBytes()));
88     }
89
90     /**
91      * Initialize default parameters.
92      */
93     @BeforeClass
94     public static void initializeDefaultParameters() {
95         ParameterService.clear();
96         final SchemaParameters schemaParameters = new SchemaParameters();
97         schemaParameters.setName(ContextParameterConstants.SCHEMA_GROUP_NAME);
98         ParameterService.register(schemaParameters);
99
100         final ContextParameters contextParameters = new ContextParameters();
101         contextParameters.setName(ContextParameterConstants.MAIN_GROUP_NAME);
102         ParameterService.register(contextParameters);
103
104         final DistributorParameters distributorParameters = new DistributorParameters();
105         distributorParameters.setName(ContextParameterConstants.DISTRIBUTOR_GROUP_NAME);
106         ParameterService.register(distributorParameters);
107
108         final LockManagerParameters lockManagerParameters = new LockManagerParameters();
109         lockManagerParameters.setName(ContextParameterConstants.LOCKING_GROUP_NAME);
110         ParameterService.register(lockManagerParameters);
111
112         final PersistorParameters persistorParameters = new PersistorParameters();
113         persistorParameters.setName(ContextParameterConstants.PERSISTENCE_GROUP_NAME);
114         ParameterService.register(persistorParameters);
115
116         final EngineParameters engineParameters = new EngineParameters();
117         engineParameters.setName(EngineParameterConstants.MAIN_GROUP_NAME);
118         ExecutorParameters jsExecutorParameters = new ExecutorParameters();
119         jsExecutorParameters.setName("JAVASCRIPT");
120         jsExecutorParameters
121                 .setTaskSelectionExecutorPluginClass("org.onap.policy.apex.service.engine.runtime.impl.DummyTse");
122         jsExecutorParameters.setTaskExecutorPluginClass("org.onap.policy.apex.service.engine.runtime.impl.DummyTe");
123         jsExecutorParameters
124                 .setStateFinalizerExecutorPluginClass("org.onap.policy.apex.service.engine.runtime.impl.DummySfe");
125         engineParameters.getExecutorParameterMap().put("JAVASCRIPT", jsExecutorParameters);
126         ExecutorParameters mvvelExecutorParameters = new ExecutorParameters();
127         mvvelExecutorParameters.setName("MVEL");
128         mvvelExecutorParameters
129                 .setTaskSelectionExecutorPluginClass("org.onap.policy.apex.service.engine.runtime.impl.DummyTse");
130         mvvelExecutorParameters.setTaskExecutorPluginClass("org.onap.policy.apex.service.engine.runtime.impl.DummyTe");
131         mvvelExecutorParameters
132                 .setStateFinalizerExecutorPluginClass("org.onap.policy.apex.service.engine.runtime.impl.DummySfe");
133         engineParameters.getExecutorParameterMap().put("MVEL", jsExecutorParameters);
134         ParameterService.register(engineParameters);
135
136     }
137
138     /**
139      * Teardown default parameters.
140      */
141     @AfterClass
142     public static void teardownDefaultParameters() {
143         ParameterService.deregister(ContextParameterConstants.SCHEMA_GROUP_NAME);
144         ParameterService.deregister(ContextParameterConstants.DISTRIBUTOR_GROUP_NAME);
145         ParameterService.deregister(ContextParameterConstants.LOCKING_GROUP_NAME);
146         ParameterService.deregister(ContextParameterConstants.PERSISTENCE_GROUP_NAME);
147         ParameterService.deregister(ContextParameterConstants.MAIN_GROUP_NAME);
148         ParameterService.deregister(EngineParameterConstants.MAIN_GROUP_NAME);
149     }
150
151     @After
152     public void cleardownTest() {
153         ModelService.clear();
154     }
155
156     @Test
157     public void testEngineWorker() {
158
159         BlockingQueue<ApexEvent> eventQueue = new LinkedBlockingQueue<>();
160
161         EngineWorker worker = new EngineWorker(new AxArtifactKey("Worker", "0.0.1"), eventQueue, atFactory);
162
163         try {
164             worker.registerActionListener(null, null);
165             fail("test should throw an exception");
166         } catch (Exception apEx) {
167             assertEquals("addEventListener()<-Worker:0.0.1,STOPPED, listenerName is null", apEx.getMessage());
168         }
169
170         worker.registerActionListener("DummyListener", null);
171
172         try {
173             worker.registerActionListener(null, new DummyApexEventListener());
174             fail("test should throw an exception");
175         } catch (Exception apEx) {
176             assertEquals("addEventListener()<-Worker:0.0.1,STOPPED, listenerName is null", apEx.getMessage());
177         }
178
179         worker.registerActionListener("DummyListener", new DummyApexEventListener());
180
181         try {
182             worker.deregisterActionListener(null);
183             fail("test should throw an exception");
184         } catch (Exception apEx) {
185             assertEquals("removeEventListener()<-Worker:0.0.1,STOPPED, listenerName is null", apEx.getMessage());
186         }
187
188         worker.deregisterActionListener("DummyListener");
189
190         try {
191             worker.getEngineServiceEventInterface();
192             fail("test should throw an exception");
193         } catch (Exception apEx) {
194             assertEquals("getEngineServiceEventInterface() call is not allowed on an Apex Engine Worker",
195                     apEx.getMessage());
196         }
197
198         try {
199             worker.startPeriodicEvents(100000);
200             fail("test should throw an exception");
201         } catch (Exception apEx) {
202             assertEquals("startPeriodicEvents() call is not allowed on an Apex Engine Worker", apEx.getMessage());
203         }
204
205         try {
206             worker.stopPeriodicEvents();
207             fail("test should throw an exception");
208         } catch (Exception apEx) {
209             assertEquals("stopPeriodicEvents() call is not allowed on an Apex Engine Worker", apEx.getMessage());
210         }
211
212         assertEquals("Worker:0.0.1", worker.getEngineKeys().iterator().next().getId());
213
214         assertNull(worker.getApexModelKey());
215
216         String runtimeInfo = worker.getRuntimeInfo(worker.getEngineKeys().iterator().next());
217         assertEquals("{\"TimeStamp\":", runtimeInfo.replaceAll("\\s+", "").substring(0, 13));
218
219         assertEquals(AxEngineState.STOPPED, worker.getState());
220
221         String status = worker.getStatus(worker.getEngineKeys().iterator().next());
222         assertEquals("{\"TimeStamp\":", runtimeInfo.replaceAll("\\s+", "").substring(0, 13));
223
224         assertFalse(worker.isStarted());
225         assertFalse(worker.isStarted(null));
226         assertFalse(worker.isStarted(new AxArtifactKey("DummyKey", "0.0.1")));
227         assertFalse(worker.isStarted(worker.getEngineKeys().iterator().next()));
228         assertTrue(worker.isStopped());
229         assertTrue(worker.isStopped(null));
230         assertTrue(worker.isStopped(new AxArtifactKey("DummyKey", "0.0.1")));
231         assertTrue(worker.isStopped(worker.getEngineKeys().iterator().next()));
232
233         try {
234             worker.start(new AxArtifactKey("DummyKey", "0.0.1"));
235             fail("test should throw an exception");
236         } catch (ApexException apEx) {
237             assertEquals("engine key DummyKey:0.0.1 does not match the keyWorker:0.0.1 of this engine",
238                     apEx.getMessage());
239         }
240
241         try {
242             worker.start(worker.getEngineKeys().iterator().next());
243             fail("test should throw an exception");
244         } catch (ApexException apEx) {
245             assertEquals("start()<-Worker:0.0.1,STOPPED,  cannot start engine, engine has not been initialized, "
246                     + "its model is not loaded", apEx.getMessage());
247         }
248
249         try {
250             worker.startAll();
251             fail("test should throw an exception");
252         } catch (ApexException apEx) {
253             assertEquals("start()<-Worker:0.0.1,STOPPED,  cannot start engine, "
254                     + "engine has not been initialized, its model is not loaded", apEx.getMessage());
255         }
256
257         try {
258             worker.stop(new AxArtifactKey("DummyKey", "0.0.1"));
259             fail("test should throw an exception");
260         } catch (ApexException apEx) {
261             assertEquals("engine key DummyKey:0.0.1 does not match the keyWorker:0.0.1 of this engine",
262                     apEx.getMessage());
263         }
264
265         try {
266             worker.stop(worker.getEngineKeys().iterator().next());
267         } catch (ApexException apEx) {
268             fail("test should not throw an exception");
269         }
270
271         try {
272             worker.stop();
273         } catch (ApexException apEx) {
274             fail("test should not throw an exception");
275         }
276
277         try {
278             worker.clear(new AxArtifactKey("DummyKey", "0.0.1"));
279             fail("test should throw an exception");
280         } catch (ApexException apEx) {
281             assertEquals("engine key DummyKey:0.0.1 does not match the keyWorker:0.0.1 of this engine",
282                     apEx.getMessage());
283         }
284
285         try {
286             worker.clear(worker.getEngineKeys().iterator().next());
287         } catch (ApexException apEx) {
288             fail("test should not throw an exception");
289         }
290
291         try {
292             worker.clear();
293         } catch (ApexException apEx) {
294             fail("test should not throw an exception");
295         }
296
297         try {
298             worker.updateModel(new AxArtifactKey("DummyKey", "0.0.1"), "", true);
299             fail("test should throw an exception");
300         } catch (ApexException apEx) {
301             assertEquals("failed to unmarshal the apex model on engine DummyKey:0.0.1", apEx.getMessage());
302         }
303
304         try {
305             worker.updateModel(new AxArtifactKey("DummyKey", "0.0.1"), "I am not an Apex model", true);
306             fail("test should throw an exception");
307         } catch (ApexException apEx) {
308             assertEquals("failed to unmarshal the apex model on engine DummyKey:0.0.1", apEx.getMessage());
309         }
310
311         try {
312             worker.updateModel(new AxArtifactKey("DummyKey", "0.0.1"), simpleModelString, true);
313             fail("test should throw an exception");
314         } catch (ApexException apEx) {
315             assertEquals("engine key DummyKey:0.0.1 does not match the keyWorker:0.0.1 of this engine",
316                     apEx.getMessage());
317         }
318
319         try {
320             worker.updateModel(new AxArtifactKey("DummyKey", "0.0.1"), (AxPolicyModel) null, true);
321             fail("test should throw an exception");
322         } catch (ApexException apEx) {
323             assertEquals("engine key DummyKey:0.0.1 does not match the keyWorker:0.0.1 of this engine",
324                     apEx.getMessage());
325         }
326
327         try {
328             worker.updateModel(new AxArtifactKey("DummyKey", "0.0.1"), simpleModel, true);
329             fail("test should throw an exception");
330         } catch (ApexException apEx) {
331             assertEquals("engine key DummyKey:0.0.1 does not match the keyWorker:0.0.1 of this engine",
332                     apEx.getMessage());
333         }
334     }
335
336     @Test
337     public void testApexImplModelWIthModel() throws ApexException {
338         Registry.newRegistry();
339         Registry.register(ApexPolicyStatisticsManager.REG_APEX_PDP_POLICY_COUNTER, new ApexPolicyStatisticsManager());
340         BlockingQueue<ApexEvent> eventQueue = new LinkedBlockingQueue<>();
341
342         EngineWorker worker = new EngineWorker(new AxArtifactKey("Worker", "0.0.1"), eventQueue, atFactory);
343         assertEquals("Worker:0.0.1", worker.getKey().getId());
344
345         try {
346             worker.updateModel(worker.getKey(), simpleModelString, false);
347         } catch (ApexException apEx) {
348             fail("test should not throw an exception");
349         }
350
351         eventQueue.add(new ApexEvent("SomeEvent", "0.0.1", "the.event.namespace", "EventSource", "EventTarget", ""));
352
353         try {
354             worker.updateModel(worker.getKey(), differentModelString, false);
355             fail("test should throw an exception");
356         } catch (ApexException apEx) {
357             assertEquals("apex model update failed, supplied model with key \"SmallModelDifferent:0.0.1\" is not a "
358                     + "compatible model update " + "from the existing engine model with key \"SmallModel:0.0.1\"",
359                     apEx.getMessage());
360         }
361
362         try {
363             worker.updateModel(worker.getKey(), differentModelString, true);
364         } catch (ApexException apEx) {
365             fail("test should not throw an exception");
366         }
367
368         try {
369             worker.updateModel(worker.getKey(), simpleModelString, true);
370         } catch (ApexException apEx) {
371             fail("test should not throw an exception");
372         }
373
374         String runtimeInfo = worker.getRuntimeInfo(worker.getEngineKeys().iterator().next());
375         assertEquals("{\"TimeStamp\":", runtimeInfo.replaceAll("\\s+", "").substring(0, 13));
376
377         assertEquals(AxEngineState.STOPPED, worker.getState());
378         worker.startAll();
379
380         assertEquals(AxEngineState.READY, worker.getState());
381
382         String status = worker.getStatus(worker.getEngineKeys().iterator().next());
383         assertEquals("{\"timestamp\":", status.replaceAll("\\s+", "").substring(0, 13));
384
385         assertTrue(worker.isStarted());
386         assertTrue(worker.isStarted(worker.getEngineKeys().iterator().next()));
387         assertFalse(worker.isStopped());
388         assertFalse(worker.isStopped(worker.getEngineKeys().iterator().next()));
389
390         try {
391             worker.start(worker.getEngineKeys().iterator().next());
392             fail("test should throw an exception");
393         } catch (ApexException apEx) {
394             assertEquals("apex engine for engine key Worker:0.0.1 is already running with state READY",
395                     apEx.getMessage());
396         }
397
398         try {
399             worker.startAll();
400             fail("test should throw an exception");
401         } catch (ApexException apEx) {
402             assertEquals("apex engine for engine key Worker:0.0.1 is already running with state READY",
403                     apEx.getMessage());
404         }
405
406         try {
407             worker.stop(worker.getEngineKeys().iterator().next());
408         } catch (ApexException apEx) {
409             fail("test should not throw an exception");
410         }
411
412         try {
413             worker.start(worker.getEngineKeys().iterator().next());
414         } catch (ApexException apEx) {
415             fail("test should not throw an exception");
416         }
417
418         try {
419             worker.stop();
420         } catch (ApexException apEx) {
421             fail("test should not throw an exception");
422         }
423
424         try {
425             worker.startAll();
426         } catch (ApexException apEx) {
427             fail("test should not throw an exception");
428         }
429
430         worker.stop();
431         worker.startAll();
432
433         try {
434             worker.clear(worker.getEngineKeys().iterator().next());
435             fail("test should throw an exception");
436         } catch (ApexException apEx) {
437             assertEquals("clear()<-Worker:0.0.1,READY, cannot clear engine, engine is not stopped", apEx.getMessage());
438         }
439
440         try {
441             worker.stop(worker.getEngineKeys().iterator().next());
442             worker.clear(worker.getEngineKeys().iterator().next());
443         } catch (ApexException apEx) {
444             fail("test should not throw an exception");
445         }
446
447         try {
448             worker.clear();
449         } catch (ApexException apEx) {
450             fail("test should not throw an exception");
451         }
452
453         assertNotNull(worker.getApexModelKey());
454
455         final ApexPolicyStatisticsManager policyCounter = ApexPolicyStatisticsManager.getInstanceFromRegistry();
456         assertNotNull(policyCounter);
457         assertEquals(policyCounter.getPolicyExecutedCount(),
458                 policyCounter.getPolicyExecutedFailCount() + policyCounter.getPolicyExecutedSuccessCount());
459     }
460 }