APEX standalone support for ToscaPolicy format
[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  *  Modifications Copyright (C) 2020 Bell Canada. 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.assertj.core.api.Assertions.assertThatThrownBy;
26 import static org.junit.Assert.assertEquals;
27 import static org.junit.Assert.assertFalse;
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 org.junit.AfterClass;
35 import org.junit.BeforeClass;
36 import org.junit.Test;
37 import org.onap.policy.apex.context.parameters.ContextParameterConstants;
38 import org.onap.policy.apex.context.parameters.ContextParameters;
39 import org.onap.policy.apex.context.parameters.DistributorParameters;
40 import org.onap.policy.apex.context.parameters.LockManagerParameters;
41 import org.onap.policy.apex.context.parameters.PersistorParameters;
42 import org.onap.policy.apex.context.parameters.SchemaParameters;
43 import org.onap.policy.apex.core.engine.EngineParameterConstants;
44 import org.onap.policy.apex.core.engine.EngineParameters;
45 import org.onap.policy.apex.core.engine.ExecutorParameters;
46 import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
47 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
48 import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
49 import org.onap.policy.apex.model.basicmodel.handling.ApexModelReader;
50 import org.onap.policy.apex.model.basicmodel.service.ModelService;
51 import org.onap.policy.apex.model.enginemodel.concepts.AxEngineState;
52 import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
53 import org.onap.policy.apex.service.engine.event.ApexEvent;
54 import org.onap.policy.apex.service.parameters.engineservice.EngineServiceParameters;
55 import org.onap.policy.common.parameters.ParameterService;
56 import org.onap.policy.common.utils.resources.TextFileUtils;
57
58 /**
59  * Test the engine service implementation.
60  */
61 public class EngineServiceImplTest {
62
63     private static String simpleModelString;
64     private static String differentModelString;
65     private static AxPolicyModel simpleModel;
66
67     /**
68      * Read the models into strings.
69      *
70      * @throws IOException on model reading errors
71      * @throws ApexModelException on model reading exceptions
72      */
73     @BeforeClass
74     public static void readSimpleModel() throws IOException, ApexModelException {
75         simpleModelString = TextFileUtils.getTextFileAsString("src/test/resources/policymodels/SmallModel.json");
76
77         differentModelString =
78             TextFileUtils.getTextFileAsString("src/test/resources/policymodels/SmallModelDifferent.json");
79
80         final ApexModelReader<AxPolicyModel> modelReader = new ApexModelReader<>(AxPolicyModel.class);
81         simpleModel = modelReader.read(new ByteArrayInputStream(simpleModelString.getBytes()));
82     }
83
84     /**
85      * Initialize default parameters.
86      */
87     @BeforeClass
88     public static void initializeDefaultParameters() {
89         ParameterService.clear();
90         final SchemaParameters schemaParameters = new SchemaParameters();
91         schemaParameters.setName(ContextParameterConstants.SCHEMA_GROUP_NAME);
92         ParameterService.register(schemaParameters);
93
94         final ContextParameters contextParameters = new ContextParameters();
95         contextParameters.setName(ContextParameterConstants.MAIN_GROUP_NAME);
96         ParameterService.register(contextParameters);
97
98         final DistributorParameters distributorParameters = new DistributorParameters();
99         distributorParameters.setName(ContextParameterConstants.DISTRIBUTOR_GROUP_NAME);
100         ParameterService.register(distributorParameters);
101
102         final LockManagerParameters lockManagerParameters = new LockManagerParameters();
103         lockManagerParameters.setName(ContextParameterConstants.LOCKING_GROUP_NAME);
104         ParameterService.register(lockManagerParameters);
105
106         final PersistorParameters persistorParameters = new PersistorParameters();
107         persistorParameters.setName(ContextParameterConstants.PERSISTENCE_GROUP_NAME);
108         ParameterService.register(persistorParameters);
109
110         final EngineParameters engineParameters = new EngineParameters();
111         engineParameters.setName(EngineParameterConstants.MAIN_GROUP_NAME);
112         ExecutorParameters jsExecutorParameters = new ExecutorParameters();
113         jsExecutorParameters.setName("JAVASCRIPT");
114         jsExecutorParameters
115             .setTaskSelectionExecutorPluginClass("org.onap.policy.apex.service.engine.runtime.impl.DummyTse");
116         jsExecutorParameters.setTaskExecutorPluginClass("org.onap.policy.apex.service.engine.runtime.impl.DummyTe");
117         jsExecutorParameters
118             .setStateFinalizerExecutorPluginClass("org.onap.policy.apex.service.engine.runtime.impl.DummySfe");
119         engineParameters.getExecutorParameterMap().put("JAVASCRIPT", jsExecutorParameters);
120         ExecutorParameters mvvelExecutorParameters = new ExecutorParameters();
121         mvvelExecutorParameters.setName("MVEL");
122         mvvelExecutorParameters
123             .setTaskSelectionExecutorPluginClass("org.onap.policy.apex.service.engine.runtime.impl.DummyTse");
124         mvvelExecutorParameters.setTaskExecutorPluginClass("org.onap.policy.apex.service.engine.runtime.impl.DummyTe");
125         mvvelExecutorParameters
126             .setStateFinalizerExecutorPluginClass("org.onap.policy.apex.service.engine.runtime.impl.DummySfe");
127         engineParameters.getExecutorParameterMap().put("MVEL", jsExecutorParameters);
128         ParameterService.register(engineParameters);
129     }
130
131     /**
132      * Teardown default parameters.
133      */
134     @AfterClass
135     public static void teardownDefaultParameters() {
136         ParameterService.deregister(ContextParameterConstants.SCHEMA_GROUP_NAME);
137         ParameterService.deregister(ContextParameterConstants.DISTRIBUTOR_GROUP_NAME);
138         ParameterService.deregister(ContextParameterConstants.LOCKING_GROUP_NAME);
139         ParameterService.deregister(ContextParameterConstants.PERSISTENCE_GROUP_NAME);
140         ParameterService.deregister(ContextParameterConstants.MAIN_GROUP_NAME);
141         ParameterService.deregister(EngineParameterConstants.MAIN_GROUP_NAME);
142         ModelService.clear();
143     }
144
145     @Test
146     public void testEngineServiceImplSanity() throws ApexException {
147         assertThatThrownBy(() -> EngineServiceImpl.create(null)).isInstanceOf(ApexException.class)
148             .hasMessage("engine service configuration parameters are null");
149         EngineServiceParameters config = new EngineServiceParameters();
150         config.setInstanceCount(0);
151         assertThatThrownBy(() -> EngineServiceImpl.create(config)).isInstanceOf(ApexException.class)
152             .hasMessageContaining("Invalid engine service configuration parameters");
153
154         config.setId(123);
155         config.setEngineKey(new AxArtifactKey("Engine", "0.0.1"));
156         config.setInstanceCount(1);
157         config.setPolicyModel("policyModelContent");
158
159         EngineServiceImpl esImpl = EngineServiceImpl.create(config);
160         assertEquals("Engine:0.0.1", esImpl.getKey().getId());
161
162         esImpl.registerActionListener(null, null);
163         esImpl.registerActionListener("DummyListener", null);
164         esImpl.registerActionListener(null, new DummyApexEventListener());
165
166         esImpl.registerActionListener("DummyListener", new DummyApexEventListener());
167         assertThatThrownBy(() -> esImpl.deregisterActionListener(null))
168             .hasMessage("removeEventListener()<-Engine-0:0.0.1,STOPPED, listenerName is null");
169
170         esImpl.deregisterActionListener("DummyListener");
171
172         assertEquals(esImpl, esImpl.getEngineServiceEventInterface());
173         assertEquals(1, esImpl.getEngineKeys().size());
174
175         assertNull(esImpl.getApexModelKey());
176
177         assertThatThrownBy(() -> esImpl.getRuntimeInfo(null)).isInstanceOf(ApexException.class)
178             .hasMessage("engine key must be specified and may not be null");
179
180         assertThatThrownBy(() -> esImpl.getRuntimeInfo(new AxArtifactKey("DummyKey", "0.0.1")))
181             .isInstanceOf(ApexException.class).hasMessage("engine with key DummyKey:0.0.1 not found in engine service");
182
183         String runtimeInfo = esImpl.getRuntimeInfo(esImpl.getEngineKeys().iterator().next());
184         assertEquals("{\n  \"TimeStamp\":", runtimeInfo.substring(0, 16));
185
186         assertEquals(AxEngineState.STOPPED, esImpl.getState());
187
188         assertThatThrownBy(() -> esImpl.getStatus(null)).isInstanceOf(ApexException.class)
189             .hasMessage("engine key must be specified and may not be null");
190         assertThatThrownBy(() -> esImpl.getStatus(new AxArtifactKey("DummyKey", "0.0.1")))
191             .isInstanceOf(ApexException.class).hasMessage("engine with key DummyKey:0.0.1 not found in engine service");
192
193         String status = esImpl.getStatus(esImpl.getEngineKeys().iterator().next());
194         assertTrue(status.contains("\n   \"apexEngineModel\" :"));
195
196         assertFalse(esImpl.isStarted());
197         assertFalse(esImpl.isStarted(null));
198         assertFalse(esImpl.isStarted(new AxArtifactKey("DummyKey", "0.0.1")));
199         assertFalse(esImpl.isStarted(esImpl.getEngineKeys().iterator().next()));
200         assertTrue(esImpl.isStopped());
201         assertTrue(esImpl.isStopped(null));
202         assertTrue(esImpl.isStopped(new AxArtifactKey("DummyKey", "0.0.1")));
203         assertTrue(esImpl.isStopped(esImpl.getEngineKeys().iterator().next()));
204
205         assertThatThrownBy(() -> esImpl.start(null)).isInstanceOf(ApexException.class)
206             .hasMessage("engine key must be specified and may not be null");
207
208         assertThatThrownBy(() -> esImpl.start(new AxArtifactKey("DummyKey", "0.0.1"))).isInstanceOf(ApexException.class)
209             .hasMessage("engine with key DummyKey:0.0.1 not found in engine service");
210
211         assertThatThrownBy(() -> esImpl.start(esImpl.getEngineKeys().iterator().next()))
212             .isInstanceOf(ApexException.class).hasMessage("start()<-Engine-0:0.0.1,STOPPED,  cannot start engine, "
213                 + "engine has not been initialized, its model is not loaded");
214
215         assertThatThrownBy(() -> esImpl.startAll()).isInstanceOf(ApexException.class)
216             .hasMessage("start()<-Engine-0:0.0.1,STOPPED,  cannot start engine, "
217                 + "engine has not been initialized, its model is not loaded");
218
219         assertThatThrownBy(() -> esImpl.stop(null)).isInstanceOf(ApexException.class)
220             .hasMessage("engine key must be specified and may not be null");
221
222         assertThatThrownBy(() -> esImpl.stop(new AxArtifactKey("DummyKey", "0.0.1"))).isInstanceOf(ApexException.class)
223             .hasMessage("engine with key DummyKey:0.0.1 not found in engine service");
224
225         esImpl.stop(esImpl.getEngineKeys().iterator().next());
226
227         esImpl.stop();
228         esImpl.sendEvent(null);
229         esImpl.sendEvent(new ApexEvent("SomeEvent", "0.0.1", "the.event.namespace", "EventSource", "EventTarget"));
230
231         esImpl.startPeriodicEvents(100000);
232
233         assertThatThrownBy(() -> esImpl.startPeriodicEvents(100000)).isInstanceOf(ApexException.class)
234             .hasMessage("Peiodic event geneation already running on engine Engine:0.0.1, ApexPeriodicEventGenerator "
235                 + "[period=100000, firstEventTime=0, lastEventTime=0, eventCount=0]");
236
237         esImpl.stopPeriodicEvents();
238
239         assertThatThrownBy(() -> esImpl.stopPeriodicEvents()).isInstanceOf(ApexException.class)
240             .hasMessage("Peiodic event geneation not running on engine Engine:0.0.1");
241
242         assertThatThrownBy(() -> esImpl.clear(null)).isInstanceOf(ApexException.class)
243             .hasMessage("engine key must be specified and may not be null");
244
245         assertThatThrownBy(() -> esImpl.clear(new AxArtifactKey("DummyKey", "0.0.1"))).isInstanceOf(ApexException.class)
246             .hasMessage("engine with key DummyKey:0.0.1 not found in engine service");
247         esImpl.clear(esImpl.getEngineKeys().iterator().next());
248         esImpl.clear();
249
250         assertThatThrownBy(() -> esImpl.updateModel(null, (String) null, true)).isInstanceOf(ApexException.class)
251             .hasMessage("engine key must be specified and may not be null");
252
253         assertThatThrownBy(() -> esImpl.updateModel(new AxArtifactKey("DummyKey", "0.0.1"), (String) null, true))
254             .isInstanceOf(ApexException.class)
255             .hasMessage("model for updating engine service with key DummyKey:0.0.1 is empty");
256
257         assertThatThrownBy(() -> esImpl.updateModel(new AxArtifactKey("DummyKey", "0.0.1"), "", true))
258             .isInstanceOf(ApexException.class)
259             .hasMessage("model for updating engine service with key DummyKey:0.0.1 is empty");
260
261         assertThatThrownBy(
262             () -> esImpl.updateModel(new AxArtifactKey("DummyKey", "0.0.1"), "I am not an Apex model", true))
263                 .isInstanceOf(ApexException.class)
264                 .hasMessage("failed to unmarshal the apex model on engine service DummyKey:0.0.1");
265
266         assertThatThrownBy(() -> esImpl.updateModel(new AxArtifactKey("DummyKey", "0.0.1"), simpleModelString, true))
267             .isInstanceOf(ApexException.class)
268             .hasMessage("engine service key DummyKey:0.0.1 does not match the keyEngine:0.0.1 of this engine service");
269
270         assertThatThrownBy(() -> esImpl.updateModel(null, simpleModelString, true)).isInstanceOf(ApexException.class)
271             .hasMessage("engine key must be specified and may not be null");
272
273         assertThatThrownBy(() -> esImpl.updateModel(null, (AxPolicyModel) null, true)).isInstanceOf(ApexException.class)
274             .hasMessage("engine key must be specified and may not be null");
275
276         assertThatThrownBy(() -> esImpl.updateModel(new AxArtifactKey("DummyKey", "0.0.1"), (AxPolicyModel) null, true))
277             .isInstanceOf(ApexException.class)
278             .hasMessage("model for updating on engine service with key DummyKey:0.0.1 is null");
279
280         assertThatThrownBy(() -> esImpl.updateModel(new AxArtifactKey("DummyKey", "0.0.1"), simpleModel, true))
281             .isInstanceOf(ApexException.class)
282             .hasMessage("engine service key DummyKey:0.0.1 does not match the keyEngine:0.0.1 of this engine service");
283     }
284
285     @Test
286     public void testApexImplModelWIthModel() throws ApexException {
287         EngineServiceParameters config = new EngineServiceParameters();
288         config.setId(123);
289         config.setEngineKey(new AxArtifactKey("Engine", "0.0.1"));
290         config.setInstanceCount(1);
291         config.setPolicyModel("policyModelContent");
292         EngineServiceImpl esImpl = EngineServiceImpl.create(config);
293         assertEquals("Engine:0.0.1", esImpl.getKey().getId());
294
295         try {
296             esImpl.updateModel(config.getEngineKey(), simpleModelString, false);
297         } catch (ApexException apEx) {
298             fail("test should not throw an exception");
299         }
300
301         try {
302             esImpl.updateModel(config.getEngineKey(), differentModelString, false);
303             fail("test should throw an exception");
304         } catch (ApexException apEx) {
305             assertEquals("apex model update failed, supplied model with key \"SmallModelDifferent:0.0.1\" is not a "
306                     + "compatible model update " + "from the existing engine model with key \"SmallModel:0.0.1\"",
307                     apEx.getMessage());
308         }
309
310         try {
311             esImpl.updateModel(config.getEngineKey(), differentModelString, true);
312         } catch (ApexException apEx) {
313             fail("test should not throw an exception");
314         }
315
316         try {
317             esImpl.updateModel(config.getEngineKey(), simpleModelString, true);
318         } catch (ApexException apEx) {
319             fail("test should not throw an exception");
320         }
321
322         String runtimeInfo = esImpl.getRuntimeInfo(esImpl.getEngineKeys().iterator().next());
323         assertEquals("{\n  \"TimeStamp\":", runtimeInfo.substring(0, 16));
324
325         assertEquals(AxEngineState.EXECUTING, esImpl.getState());
326
327         String status = esImpl.getStatus(esImpl.getEngineKeys().iterator().next());
328         assertTrue(status.contains("\n   \"apexEngineModel\" :"));
329         assertTrue(esImpl.isStarted());
330         assertTrue(esImpl.isStarted(esImpl.getEngineKeys().iterator().next()));
331         assertFalse(esImpl.isStopped());
332         assertFalse(esImpl.isStopped(esImpl.getEngineKeys().iterator().next()));
333
334         try {
335             esImpl.start(esImpl.getEngineKeys().iterator().next());
336             fail("test should throw an exception");
337         } catch (ApexException apEx) {
338             assertEquals("apex engine for engine key Engine-0:0.0.1 is already running with state READY",
339                     apEx.getMessage());
340         }
341
342         try {
343             esImpl.startAll();
344             fail("test should throw an exception");
345         } catch (ApexException apEx) {
346             assertEquals("apex engine for engine key Engine-0:0.0.1 is already running with state READY",
347                     apEx.getMessage());
348         }
349
350         try {
351             esImpl.stop(esImpl.getEngineKeys().iterator().next());
352         } catch (ApexException apEx) {
353             fail("test should not throw an exception");
354         }
355
356         try {
357             esImpl.start(esImpl.getEngineKeys().iterator().next());
358         } catch (ApexException apEx) {
359             fail("test should not throw an exception");
360         }
361
362         try {
363             esImpl.stop();
364         } catch (ApexException apEx) {
365             fail("test should not throw an exception");
366         }
367
368         try {
369             esImpl.startAll();
370         } catch (ApexException apEx) {
371             fail("test should not throw an exception");
372         }
373
374         try {
375             esImpl.sendEvent(new ApexEvent("SomeEvent", "0.0.1", "the.event.namespace", "EventSource", "EventTarget"));
376         } catch (ApexException apEx) {
377             fail("test should not throw an exception");
378         }
379
380         esImpl.startPeriodicEvents(100000);
381         esImpl.stop();
382         esImpl.startAll();
383         esImpl.stopPeriodicEvents();
384
385         esImpl.startPeriodicEvents(100000);
386         try {
387             esImpl.startPeriodicEvents(100000);
388             fail("test should throw an exception");
389         } catch (ApexException apEx) {
390             assertEquals("Peiodic event geneation already running on engine Engine:0.0.1, ApexPeriodicEventGenerator "
391                     + "[period=100000, firstEventTime=0, lastEventTime=0, eventCount=0]", apEx.getMessage());
392         }
393
394         esImpl.stopPeriodicEvents();
395         try {
396             esImpl.stopPeriodicEvents();
397             fail("test should throw an exception");
398         } catch (ApexException apEx) {
399             assertEquals("Peiodic event geneation not running on engine Engine:0.0.1", apEx.getMessage());
400         }
401
402         try {
403             esImpl.clear(esImpl.getEngineKeys().iterator().next());
404         } catch (ApexException apEx) {
405             fail("test should not throw an exception");
406         }
407
408         try {
409             esImpl.clear();
410         } catch (ApexException apEx) {
411             fail("test should not throw an exception");
412         }
413     }
414 }