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