2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2018 Ericsson. All rights reserved.
4 * Modifications Copyright (C) 2020-2021 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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * SPDX-License-Identifier: Apache-2.0
20 * ============LICENSE_END=========================================================
23 package org.onap.policy.apex.service.engine.runtime.impl;
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;
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;
59 * Test the engine service implementation.
61 public class EngineServiceImplTest {
63 private static String simpleModelString;
64 private static String differentModelString;
65 private static AxPolicyModel simpleModel;
68 * Read the models into strings.
70 * @throws IOException on model reading errors
71 * @throws ApexModelException on model reading exceptions
74 public static void readSimpleModel() throws IOException, ApexModelException {
75 simpleModelString = TextFileUtils.getTextFileAsString("src/test/resources/policymodels/SmallModel.json");
77 differentModelString =
78 TextFileUtils.getTextFileAsString("src/test/resources/policymodels/SmallModelDifferent.json");
80 final ApexModelReader<AxPolicyModel> modelReader = new ApexModelReader<>(AxPolicyModel.class);
81 simpleModel = modelReader.read(new ByteArrayInputStream(simpleModelString.getBytes()));
85 * Initialize default parameters.
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);
94 final ContextParameters contextParameters = new ContextParameters();
95 contextParameters.setName(ContextParameterConstants.MAIN_GROUP_NAME);
96 ParameterService.register(contextParameters);
98 final DistributorParameters distributorParameters = new DistributorParameters();
99 distributorParameters.setName(ContextParameterConstants.DISTRIBUTOR_GROUP_NAME);
100 ParameterService.register(distributorParameters);
102 final LockManagerParameters lockManagerParameters = new LockManagerParameters();
103 lockManagerParameters.setName(ContextParameterConstants.LOCKING_GROUP_NAME);
104 ParameterService.register(lockManagerParameters);
106 final PersistorParameters persistorParameters = new PersistorParameters();
107 persistorParameters.setName(ContextParameterConstants.PERSISTENCE_GROUP_NAME);
108 ParameterService.register(persistorParameters);
110 final EngineParameters engineParameters = new EngineParameters();
111 engineParameters.setName(EngineParameterConstants.MAIN_GROUP_NAME);
112 ExecutorParameters jsExecutorParameters = new ExecutorParameters();
113 jsExecutorParameters.setName("JAVASCRIPT");
115 .setTaskSelectionExecutorPluginClass("org.onap.policy.apex.service.engine.runtime.impl.DummyTse");
116 jsExecutorParameters.setTaskExecutorPluginClass("org.onap.policy.apex.service.engine.runtime.impl.DummyTe");
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);
132 * Teardown default parameters.
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();
145 private EngineServiceParameters makeConfig() {
146 EngineServiceParameters config = new EngineServiceParameters();
147 config.setInstanceCount(0);
149 config.setEngineKey(new AxArtifactKey("Engine", "0.0.1"));
150 config.setInstanceCount(1);
151 config.setPolicyModel("policyModelContent");
156 public void testEngineServiceImplSanity() throws ApexException {
157 assertThatThrownBy(() -> EngineServiceImpl.create(null)).isInstanceOf(ApexException.class)
158 .hasMessage("engine service configuration parameters are null");
160 EngineServiceParameters invalidConfig = new EngineServiceParameters();
161 invalidConfig.setInstanceCount(0);
162 assertThatThrownBy(() -> EngineServiceImpl.create(invalidConfig)).isInstanceOf(ApexException.class)
163 .hasMessageContaining("Invalid engine service configuration parameters");
165 EngineServiceParameters config = makeConfig();
166 EngineServiceImpl esImpl = EngineServiceImpl.create(config);
167 assertEquals("Engine:0.0.1", esImpl.getKey().getId());
169 esImpl.registerActionListener(null, null);
170 esImpl.registerActionListener("DummyListener", null);
171 esImpl.registerActionListener(null, new DummyApexEventListener());
173 esImpl.registerActionListener("DummyListener", new DummyApexEventListener());
174 assertThatThrownBy(() -> esImpl.deregisterActionListener(null))
175 .hasMessage("removeEventListener()<-Engine-0:0.0.1,STOPPED, listenerName is null");
177 esImpl.deregisterActionListener("DummyListener");
179 assertEquals(esImpl, esImpl.getEngineServiceEventInterface());
180 assertEquals(1, esImpl.getEngineKeys().size());
182 assertNull(esImpl.getApexModelKey());
184 assertThatThrownBy(() -> esImpl.getRuntimeInfo(null)).isInstanceOf(ApexException.class)
185 .hasMessage("engine key must be specified and may not be null");
187 assertThatThrownBy(() -> esImpl.getRuntimeInfo(new AxArtifactKey("DummyKey", "0.0.1")))
188 .isInstanceOf(ApexException.class).hasMessage("engine with key DummyKey:0.0.1 not found in engine service");
190 String runtimeInfo = esImpl.getRuntimeInfo(esImpl.getEngineKeys().iterator().next());
191 assertEquals("{\n \"TimeStamp\":", runtimeInfo.substring(0, 16));
193 assertEquals(AxEngineState.STOPPED, esImpl.getState());
195 assertThatThrownBy(() -> esImpl.getStatus(null)).isInstanceOf(ApexException.class)
196 .hasMessage("engine key must be specified and may not be null");
197 assertThatThrownBy(() -> esImpl.getStatus(new AxArtifactKey("DummyKey", "0.0.1")))
198 .isInstanceOf(ApexException.class).hasMessage("engine with key DummyKey:0.0.1 not found in engine service");
200 String status = esImpl.getStatus(esImpl.getEngineKeys().iterator().next());
201 assertTrue(status.contains("\n \"apexEngineModel\" :"));
203 assertFalse(esImpl.isStarted());
204 assertFalse(esImpl.isStarted(null));
205 assertFalse(esImpl.isStarted(new AxArtifactKey("DummyKey", "0.0.1")));
206 assertFalse(esImpl.isStarted(esImpl.getEngineKeys().iterator().next()));
207 assertTrue(esImpl.isStopped());
208 assertTrue(esImpl.isStopped(null));
209 assertTrue(esImpl.isStopped(new AxArtifactKey("DummyKey", "0.0.1")));
210 assertTrue(esImpl.isStopped(esImpl.getEngineKeys().iterator().next()));
214 public void testEngineServiceExceptions() throws ApexException {
215 EngineServiceParameters config = makeConfig();
216 EngineServiceImpl esImpl = EngineServiceImpl.create(config);
217 assertThatThrownBy(() -> esImpl.start(null)).isInstanceOf(ApexException.class)
218 .hasMessage("engine key must be specified and may not be null");
220 assertThatThrownBy(() -> esImpl.start(new AxArtifactKey("DummyKey", "0.0.1"))).isInstanceOf(ApexException.class)
221 .hasMessage("engine with key DummyKey:0.0.1 not found in engine service");
223 assertThatThrownBy(() -> esImpl.start(esImpl.getEngineKeys().iterator().next()))
224 .isInstanceOf(ApexException.class).hasMessage("start()<-Engine-0:0.0.1,STOPPED, cannot start engine, "
225 + "engine has not been initialized, its model is not loaded");
227 assertThatThrownBy(() -> esImpl.startAll()).isInstanceOf(ApexException.class)
228 .hasMessage("start()<-Engine-0:0.0.1,STOPPED, cannot start engine, "
229 + "engine has not been initialized, its model is not loaded");
231 assertThatThrownBy(() -> esImpl.stop(null)).isInstanceOf(ApexException.class)
232 .hasMessage("engine key must be specified and may not be null");
234 assertThatThrownBy(() -> esImpl.stop(new AxArtifactKey("DummyKey", "0.0.1"))).isInstanceOf(ApexException.class)
235 .hasMessage("engine with key DummyKey:0.0.1 not found in engine service");
237 esImpl.stop(esImpl.getEngineKeys().iterator().next());
240 esImpl.sendEvent(null);
241 esImpl.sendEvent(new ApexEvent("SomeEvent", "0.0.1", "the.event.namespace", "EventSource", "EventTarget"));
243 esImpl.startPeriodicEvents(100000);
245 assertThatThrownBy(() -> esImpl.startPeriodicEvents(100000)).isInstanceOf(ApexException.class)
246 .hasMessage("Peiodic event geneation already running on engine Engine:0.0.1, ApexPeriodicEventGenerator "
247 + "[period=100000, firstEventTime=0, lastEventTime=0, eventCount=0]");
249 esImpl.stopPeriodicEvents();
251 assertThatThrownBy(() -> esImpl.stopPeriodicEvents()).isInstanceOf(ApexException.class)
252 .hasMessage("Peiodic event geneation not running on engine Engine:0.0.1");
254 assertThatThrownBy(() -> esImpl.clear(null)).isInstanceOf(ApexException.class)
255 .hasMessage("engine key must be specified and may not be null");
257 assertThatThrownBy(() -> esImpl.clear(new AxArtifactKey("DummyKey", "0.0.1"))).isInstanceOf(ApexException.class)
258 .hasMessage("engine with key DummyKey:0.0.1 not found in engine service");
259 esImpl.clear(esImpl.getEngineKeys().iterator().next());
262 assertThatThrownBy(() -> esImpl.updateModel(null, (String) null, true)).isInstanceOf(ApexException.class)
263 .hasMessage("engine key must be specified and may not be null");
265 assertThatThrownBy(() -> esImpl.updateModel(new AxArtifactKey("DummyKey", "0.0.1"), (String) null, true))
266 .isInstanceOf(ApexException.class)
267 .hasMessage("model for updating engine service with key DummyKey:0.0.1 is empty");
269 assertThatThrownBy(() -> esImpl.updateModel(new AxArtifactKey("DummyKey", "0.0.1"), "", true))
270 .isInstanceOf(ApexException.class)
271 .hasMessage("model for updating engine service with key DummyKey:0.0.1 is empty");
274 () -> esImpl.updateModel(new AxArtifactKey("DummyKey", "0.0.1"), "I am not an Apex model", true))
275 .isInstanceOf(ApexException.class)
276 .hasMessage("failed to unmarshal the apex model on engine service DummyKey:0.0.1");
278 assertThatThrownBy(() -> esImpl.updateModel(new AxArtifactKey("DummyKey", "0.0.1"), simpleModelString, true))
279 .isInstanceOf(ApexException.class)
280 .hasMessage("engine service key DummyKey:0.0.1 does not match the keyEngine:0.0.1 of this engine service");
282 assertThatThrownBy(() -> esImpl.updateModel(null, simpleModelString, true)).isInstanceOf(ApexException.class)
283 .hasMessage("engine key must be specified and may not be null");
285 assertThatThrownBy(() -> esImpl.updateModel(null, (AxPolicyModel) null, true)).isInstanceOf(ApexException.class)
286 .hasMessage("engine key must be specified and may not be null");
288 assertThatThrownBy(() -> esImpl.updateModel(new AxArtifactKey("DummyKey", "0.0.1"), (AxPolicyModel) null, true))
289 .isInstanceOf(ApexException.class)
290 .hasMessage("model for updating on engine service with key DummyKey:0.0.1 is null");
292 assertThatThrownBy(() -> esImpl.updateModel(new AxArtifactKey("DummyKey", "0.0.1"), simpleModel, true))
293 .isInstanceOf(ApexException.class)
294 .hasMessage("engine service key DummyKey:0.0.1 does not match the keyEngine:0.0.1 of this engine service");
298 public void testApexImplModelWIthModel() throws ApexException {
299 EngineServiceParameters config = makeConfig();
300 EngineServiceImpl esImpl = EngineServiceImpl.create(config);
301 assertEquals("Engine:0.0.1", esImpl.getKey().getId());
304 esImpl.updateModel(config.getEngineKey(), simpleModelString, false);
305 } catch (ApexException apEx) {
306 fail("test should not throw an exception");
310 esImpl.updateModel(config.getEngineKey(), differentModelString, false);
311 fail("test should throw an exception");
312 } catch (ApexException apEx) {
313 assertEquals("apex model update failed, supplied model with key \"SmallModelDifferent:0.0.1\" is not a "
314 + "compatible model update " + "from the existing engine model with key \"SmallModel:0.0.1\"",
319 esImpl.updateModel(config.getEngineKey(), differentModelString, true);
320 } catch (ApexException apEx) {
321 fail("test should not throw an exception");
325 esImpl.updateModel(config.getEngineKey(), simpleModelString, true);
326 } catch (ApexException apEx) {
327 fail("test should not throw an exception");
330 String runtimeInfo = esImpl.getRuntimeInfo(esImpl.getEngineKeys().iterator().next());
331 assertEquals("{\n \"TimeStamp\":", runtimeInfo.substring(0, 16));
333 assertEquals(AxEngineState.EXECUTING, esImpl.getState());
335 String status = esImpl.getStatus(esImpl.getEngineKeys().iterator().next());
336 assertTrue(status.contains("\n \"apexEngineModel\" :"));
337 assertTrue(esImpl.isStarted());
338 assertTrue(esImpl.isStarted(esImpl.getEngineKeys().iterator().next()));
339 assertFalse(esImpl.isStopped());
340 assertFalse(esImpl.isStopped(esImpl.getEngineKeys().iterator().next()));
343 esImpl.start(esImpl.getEngineKeys().iterator().next());
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",
352 fail("test should throw an exception");
353 } catch (ApexException apEx) {
354 assertEquals("apex engine for engine key Engine-0:0.0.1 is already running with state READY",
359 esImpl.stop(esImpl.getEngineKeys().iterator().next());
360 } catch (ApexException apEx) {
361 fail("test should not throw an exception");
365 esImpl.start(esImpl.getEngineKeys().iterator().next());
366 } catch (ApexException apEx) {
367 fail("test should not throw an exception");
372 } catch (ApexException apEx) {
373 fail("test should not throw an exception");
378 } catch (ApexException apEx) {
379 fail("test should not throw an exception");
383 esImpl.sendEvent(new ApexEvent("SomeEvent", "0.0.1", "the.event.namespace", "EventSource", "EventTarget"));
384 } catch (ApexException apEx) {
385 fail("test should not throw an exception");
388 esImpl.startPeriodicEvents(100000);
391 esImpl.stopPeriodicEvents();
393 esImpl.startPeriodicEvents(100000);
395 esImpl.startPeriodicEvents(100000);
396 fail("test should throw an exception");
397 } catch (ApexException apEx) {
398 assertEquals("Peiodic event geneation already running on engine Engine:0.0.1, ApexPeriodicEventGenerator "
399 + "[period=100000, firstEventTime=0, lastEventTime=0, eventCount=0]", apEx.getMessage());
402 esImpl.stopPeriodicEvents();
404 esImpl.stopPeriodicEvents();
405 fail("test should throw an exception");
406 } catch (ApexException apEx) {
407 assertEquals("Peiodic event geneation not running on engine Engine:0.0.1", apEx.getMessage());
411 esImpl.clear(esImpl.getEngineKeys().iterator().next());
412 } catch (ApexException apEx) {
413 fail("test should not throw an exception");
418 } catch (ApexException apEx) {
419 fail("test should not throw an exception");