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