e2464e368562e2da262de364b4fa573a20b53d28
[policy/apex-pdp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  *  Modifications Copyright (C) 2020 Nordix Foundation.
5  *  Modifications Copyright (C) 2022 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.testsuites.integration.uservice.engine;
24
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertNotNull;
27 import static org.junit.Assert.assertTrue;
28 import static org.junit.Assert.fail;
29
30 import java.io.ByteArrayOutputStream;
31 import java.io.IOException;
32 import java.util.Date;
33 import java.util.HashMap;
34 import java.util.Map;
35 import org.junit.After;
36 import org.junit.AfterClass;
37 import org.junit.Before;
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.infrastructure.threading.ThreadUtilities;
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.ApexModelWriter;
53 import org.onap.policy.apex.model.basicmodel.service.ModelService;
54 import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
55 import org.onap.policy.apex.plugins.executor.javascript.JavascriptExecutorParameters;
56 import org.onap.policy.apex.plugins.executor.mvel.MvelExecutorParameters;
57 import org.onap.policy.apex.service.engine.event.ApexEvent;
58 import org.onap.policy.apex.service.engine.runtime.ApexEventListener;
59 import org.onap.policy.apex.service.engine.runtime.EngineService;
60 import org.onap.policy.apex.service.engine.runtime.EngineServiceEventInterface;
61 import org.onap.policy.apex.service.engine.runtime.impl.EngineServiceImpl;
62 import org.onap.policy.apex.service.parameters.ApexParameterConstants;
63 import org.onap.policy.apex.service.parameters.engineservice.EngineServiceParameters;
64 import org.onap.policy.apex.testsuites.integration.common.model.SampleDomainModelFactory;
65 import org.onap.policy.common.parameters.ParameterService;
66 import org.slf4j.ext.XLogger;
67 import org.slf4j.ext.XLoggerFactory;
68
69 /**
70  * The Class ApexServiceTest.
71  *
72  * @author Liam Fallon (liam.fallon@ericsson.com)
73  */
74 public class ApexServiceTest {
75     // Logger for this class
76     private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexServiceTest.class);
77
78     private static final long MAX_STOP_WAIT = 5000; // 5 sec
79     private static final long MAX_START_WAIT = 5000; // 5 sec
80     private static final long MAX_RECV_WAIT = 5000; // 5 sec
81
82     private static final AxArtifactKey engineServiceKey = new AxArtifactKey("Machine-1_process-1_engine-1", "0.0.0");
83     private static final EngineServiceParameters parameters = new EngineServiceParameters();
84     private static EngineService service = null;
85     private static TestListener listener = null;
86     private static AxPolicyModel apexPolicyModel = null;
87     private static int actionEventsReceived = 0;
88
89     private static String apexModelString;
90
91     private boolean waitFlag = true;
92
93     @BeforeClass
94     public static void beforeSetUp() throws Exception {
95         // create engine with 3 threads
96         parameters.setInstanceCount(3);
97         parameters.setName(engineServiceKey.getName());
98         parameters.setVersion(engineServiceKey.getVersion());
99         parameters.setId(100);
100         parameters.setPolicyModel("policy model impl");
101         parameters.getEngineParameters().getExecutorParameterMap().put("MVEL", new MvelExecutorParameters());
102         service = EngineServiceImpl.create(parameters);
103
104         LOGGER.debug("Running TestApexEngine. . .");
105
106         apexPolicyModel = new SampleDomainModelFactory().getSamplePolicyModel("JAVASCRIPT");
107         assertNotNull(apexPolicyModel);
108
109         apexModelString = getModelString(apexPolicyModel);
110
111         // create engine
112         listener = new TestListener();
113         service.registerActionListener("Listener", listener);
114     }
115
116     @AfterClass
117     public static void afterCleardown() throws Exception {
118         ModelService.clear();
119     }
120
121     /**
122      * Set up parameters.
123      */
124     @Before
125     public void setupParameters() {
126         ParameterService.register(new SchemaParameters());
127         ParameterService.register(new ContextParameters());
128         ParameterService.register(new DistributorParameters());
129         ParameterService.register(new LockManagerParameters());
130         ParameterService.register(new PersistorParameters());
131         ParameterService.register(new EngineServiceParameters());
132
133         EngineParameters engineParameters = new EngineParameters();
134         engineParameters.getExecutorParameterMap().put("JAVASCRIPT", new JavascriptExecutorParameters());
135         ParameterService.register(engineParameters);
136     }
137
138     /**
139      * Clear down parameters.
140      */
141     @After
142     public void teardownParameters() {
143         ParameterService.deregister(EngineParameterConstants.MAIN_GROUP_NAME);
144         ParameterService.deregister(ApexParameterConstants.ENGINE_SERVICE_GROUP_NAME);
145         ParameterService.deregister(ContextParameterConstants.PERSISTENCE_GROUP_NAME);
146         ParameterService.deregister(ContextParameterConstants.LOCKING_GROUP_NAME);
147         ParameterService.deregister(ContextParameterConstants.DISTRIBUTOR_GROUP_NAME);
148         ParameterService.deregister(ContextParameterConstants.MAIN_GROUP_NAME);
149         ParameterService.deregister(ContextParameterConstants.SCHEMA_GROUP_NAME);
150     }
151
152     /**
153      * Update the engine then test the engine with 2 sample events.
154      *
155      * @throws ApexException if there is a problem
156      */
157     @Test
158     public void testExecutionSet1() throws ApexException {
159         service.updateModel(parameters.getEngineKey(), apexModelString, true);
160
161         final long starttime = System.currentTimeMillis();
162         for (final AxArtifactKey engineKey : service.getEngineKeys()) {
163             LOGGER.debug("{}", service.getStatus(engineKey));
164         }
165         while (!service.isStarted() && System.currentTimeMillis() - starttime < MAX_START_WAIT) {
166             ThreadUtilities.sleep(200);
167         }
168         if (!service.isStarted()) {
169             fail("Apex Service " + service.getKey() + " failed to start after " + MAX_START_WAIT + " ms");
170         }
171
172         final EngineServiceEventInterface engineServiceEventInterface = service.getEngineServiceEventInterface();
173
174         // Send some events
175         final Date testStartTime = new Date();
176         final Map<String, Object> eventDataMap = new HashMap<String, Object>();
177         eventDataMap.put("TestSlogan", "This is a test slogan");
178         eventDataMap.put("TestMatchCase", (byte) 123);
179         eventDataMap.put("TestTimestamp", testStartTime.getTime());
180         eventDataMap.put("TestTemperature", 34.5445667);
181
182         final ApexEvent event =
183                 new ApexEvent("Event0000", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex", "");
184         event.setExecutionId(System.nanoTime());
185         event.putAll(eventDataMap);
186         engineServiceEventInterface.sendEvent(event);
187
188         final ApexEvent event2 =
189                 new ApexEvent("Event0100", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex", "");
190         event2.setExecutionId(System.nanoTime());
191         event2.putAll(eventDataMap);
192         engineServiceEventInterface.sendEvent(event2);
193
194         // Wait for results
195         final long recvtime = System.currentTimeMillis();
196         while (actionEventsReceived < 2 && System.currentTimeMillis() - recvtime < MAX_RECV_WAIT) {
197             ThreadUtilities.sleep(100);
198         }
199         ThreadUtilities.sleep(500);
200         assertEquals(2, actionEventsReceived);
201         actionEventsReceived = 0;
202
203         // Stop all engines on this engine service
204         final long stoptime = System.currentTimeMillis();
205         service.stop();
206         while (!service.isStopped() && System.currentTimeMillis() - stoptime < MAX_STOP_WAIT) {
207             ThreadUtilities.sleep(200);
208         }
209         if (!service.isStopped()) {
210             fail("Apex Service " + service.getKey() + " failed to stop after " + MAX_STOP_WAIT + " ms");
211         }
212     }
213
214     /**
215      * Update the engine then test the engine with 2 sample events.
216      *
217      * @throws ApexException if there is a problem
218      */
219     @Test
220     public void testExecutionSet1Sync() throws ApexException {
221         service.updateModel(parameters.getEngineKey(), apexModelString, true);
222
223         final long starttime = System.currentTimeMillis();
224         for (final AxArtifactKey engineKey : service.getEngineKeys()) {
225             LOGGER.debug("{}", service.getStatus(engineKey));
226         }
227         while (!service.isStarted() && System.currentTimeMillis() - starttime < MAX_START_WAIT) {
228             ThreadUtilities.sleep(200);
229         }
230         if (!service.isStarted()) {
231             fail("Apex Service " + service.getKey() + " failed to start after " + MAX_START_WAIT + " ms");
232         }
233
234         // Send some events
235         final Date testStartTime = new Date();
236         final Map<String, Object> eventDataMap = new HashMap<String, Object>();
237         eventDataMap.put("TestSlogan", "This is a test slogan");
238         eventDataMap.put("TestMatchCase", (byte) 123);
239         eventDataMap.put("TestTimestamp", testStartTime.getTime());
240         eventDataMap.put("TestTemperature", 34.5445667);
241
242         final ApexEvent event1 =
243                 new ApexEvent("Event0000", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex", "");
244         event1.putAll(eventDataMap);
245         event1.setExecutionId(System.nanoTime());
246
247         final ApexEventListener myEventListener1 = new ApexEventListener() {
248             @Override
249             public void onApexEvent(final ApexEvent responseEvent) {
250                 assertNotNull("Synchronous sendEventWait failed", responseEvent);
251                 assertEquals(event1.getExecutionId(), responseEvent.getExecutionId());
252                 waitFlag = false;
253             }
254         };
255
256         waitFlag = true;
257         service.registerActionListener("Listener1", myEventListener1);
258         service.getEngineServiceEventInterface().sendEvent(event1);
259
260         while (waitFlag) {
261             ThreadUtilities.sleep(100);
262         }
263
264         final ApexEvent event2 =
265                 new ApexEvent("Event0100", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex", "");
266         event2.setExecutionId(System.nanoTime());
267         event2.putAll(eventDataMap);
268
269         final ApexEventListener myEventListener2 = new ApexEventListener() {
270             @Override
271             public void onApexEvent(final ApexEvent responseEvent) {
272                 assertNotNull("Synchronous sendEventWait failed", responseEvent);
273                 assertEquals(event2.getExecutionId(), responseEvent.getExecutionId());
274                 assertEquals(2, actionEventsReceived);
275                 waitFlag = false;
276             }
277         };
278
279         waitFlag = true;
280         service.deregisterActionListener("Listener1");
281         service.registerActionListener("Listener2", myEventListener2);
282         service.getEngineServiceEventInterface().sendEvent(event2);
283
284         while (waitFlag) {
285             ThreadUtilities.sleep(100);
286         }
287         service.deregisterActionListener("Listener2");
288
289         actionEventsReceived = 0;
290
291         // Stop all engines on this engine service
292         final long stoptime = System.currentTimeMillis();
293         service.stop();
294         while (!service.isStopped() && System.currentTimeMillis() - stoptime < MAX_STOP_WAIT) {
295             ThreadUtilities.sleep(200);
296         }
297         if (!service.isStopped()) {
298             fail("Apex Service " + service.getKey() + " failed to stop after " + MAX_STOP_WAIT + " ms");
299         }
300     }
301
302     /**
303      * Update the engine then test the engine with 2 sample events - again.
304      *
305      * @throws ApexException if there is a problem
306      */
307     @Test
308     public void testExecutionSet2() throws ApexException {
309         service.updateModel(parameters.getEngineKey(), apexModelString, true);
310
311         final long starttime = System.currentTimeMillis();
312         for (final AxArtifactKey engineKey : service.getEngineKeys()) {
313             LOGGER.debug("{}", service.getStatus(engineKey));
314         }
315         while (!service.isStarted() && System.currentTimeMillis() - starttime < MAX_START_WAIT) {
316             ThreadUtilities.sleep(200);
317         }
318         if (!service.isStarted()) {
319             fail("Apex Service " + service.getKey() + " failed to start after " + MAX_START_WAIT + " ms");
320         }
321
322         final EngineServiceEventInterface engineServiceEventInterface = service.getEngineServiceEventInterface();
323
324         // Send some events
325         final Date testStartTime = new Date();
326         final Map<String, Object> eventDataMap = new HashMap<String, Object>();
327         eventDataMap.put("TestSlogan", "This is a test slogan");
328         eventDataMap.put("TestMatchCase", (byte) 123);
329         eventDataMap.put("TestTimestamp", testStartTime.getTime());
330         eventDataMap.put("TestTemperature", 34.5445667);
331
332         final ApexEvent event =
333                 new ApexEvent("Event0000", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex", "");
334         event.setExecutionId(System.nanoTime());
335         event.putAll(eventDataMap);
336         engineServiceEventInterface.sendEvent(event);
337
338         final ApexEvent event2 =
339                 new ApexEvent("Event0100", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex", "");
340         event2.setExecutionId(System.nanoTime());
341         event2.putAll(eventDataMap);
342         engineServiceEventInterface.sendEvent(event2);
343
344         // Wait for results
345         final long recvtime = System.currentTimeMillis();
346         while (actionEventsReceived < 2 && System.currentTimeMillis() - recvtime < MAX_RECV_WAIT) {
347             ThreadUtilities.sleep(100);
348         }
349         ThreadUtilities.sleep(500);
350         assertEquals(2, actionEventsReceived);
351         actionEventsReceived = 0;
352
353         // Stop all engines on this engine service
354         final long stoptime = System.currentTimeMillis();
355         service.stop();
356         while (!service.isStopped() && System.currentTimeMillis() - stoptime < MAX_STOP_WAIT) {
357             ThreadUtilities.sleep(200);
358         }
359         if (!service.isStopped()) {
360             fail("Apex Service " + service.getKey() + " failed to stop after " + MAX_STOP_WAIT + " ms");
361         }
362     }
363
364     /**
365      * Update the engine then test the engine with 2 sample events - again.
366      *
367      * @throws ApexException if there is a problem
368      */
369     @Test
370     public void testExecutionSet2Sync() throws ApexException {
371         service.updateModel(parameters.getEngineKey(), apexModelString, true);
372
373         final long starttime = System.currentTimeMillis();
374         for (final AxArtifactKey engineKey : service.getEngineKeys()) {
375             LOGGER.debug("{}", service.getStatus(engineKey));
376         }
377         while (!service.isStarted() && System.currentTimeMillis() - starttime < MAX_START_WAIT) {
378             ThreadUtilities.sleep(200);
379         }
380         if (!service.isStarted()) {
381             fail("Apex Service " + service.getKey() + " failed to start after " + MAX_START_WAIT + " ms");
382         }
383
384         // Send some events
385         final Date testStartTime = new Date();
386         final Map<String, Object> eventDataMap = new HashMap<String, Object>();
387         eventDataMap.put("TestSlogan", "This is a test slogan");
388         eventDataMap.put("TestMatchCase", (byte) 123);
389         eventDataMap.put("TestTimestamp", testStartTime.getTime());
390         eventDataMap.put("TestTemperature", 34.5445667);
391
392         final ApexEvent event1 =
393                 new ApexEvent("Event0000", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex", "");
394         event1.putAll(eventDataMap);
395
396         final ApexEventListener myEventListener1 = new ApexEventListener() {
397             @Override
398             public void onApexEvent(final ApexEvent responseEvent) {
399                 assertNotNull("Synchronous sendEventWait failed", responseEvent);
400                 assertEquals(event1.getExecutionId(), responseEvent.getExecutionId());
401                 waitFlag = false;
402             }
403         };
404
405         waitFlag = true;
406         service.registerActionListener("Listener1", myEventListener1);
407         service.getEngineServiceEventInterface().sendEvent(event1);
408
409         while (waitFlag) {
410             ThreadUtilities.sleep(100);
411         }
412
413         final ApexEvent event2 =
414                 new ApexEvent("Event0100", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex", "");
415         event2.putAll(eventDataMap);
416
417         final ApexEventListener myEventListener2 = new ApexEventListener() {
418             @Override
419             public void onApexEvent(final ApexEvent responseEvent) {
420                 assertNotNull("Synchronous sendEventWait failed", responseEvent);
421                 assertEquals(event2.getExecutionId(), responseEvent.getExecutionId());
422                 waitFlag = false;
423             }
424         };
425
426         waitFlag = true;
427         service.registerActionListener("Listener2", myEventListener2);
428         service.deregisterActionListener("Listener1");
429         service.getEngineServiceEventInterface().sendEvent(event2);
430
431         while (waitFlag) {
432             ThreadUtilities.sleep(100);
433         }
434
435         service.deregisterActionListener("Listener2");
436
437         assertEquals(2, actionEventsReceived);
438
439         actionEventsReceived = 0;
440
441         // Stop all engines on this engine service
442         final long stoptime = System.currentTimeMillis();
443         service.stop();
444         while (!service.isStopped() && System.currentTimeMillis() - stoptime < MAX_STOP_WAIT) {
445             ThreadUtilities.sleep(200);
446         }
447         if (!service.isStopped()) {
448             fail("Apex Service " + service.getKey() + " failed to stop after " + MAX_STOP_WAIT + " ms");
449         }
450     }
451
452     /**
453      * Tear down the the test infrastructure.
454      *
455      * @throws ApexException if there is an error
456      */
457     @AfterClass
458     public static void tearDown() throws Exception {
459         // Stop all engines on this engine service
460         final long stoptime = System.currentTimeMillis();
461         service.stop();
462         while (!service.isStopped() && System.currentTimeMillis() - stoptime < MAX_STOP_WAIT) {
463             ThreadUtilities.sleep(200);
464         }
465         if (!service.isStopped()) {
466             fail("Apex Service " + service.getKey() + " failed to stop after " + MAX_STOP_WAIT + " ms");
467         }
468         service = null;
469     }
470
471     /**
472      * The listener interface for receiving test events. The class that is interested in processing a test event
473      * implements this interface, and the object created with that class is registered with a component using the
474      * component's <code>addTestListener</code> method. When the test event occurs, that object's appropriate method is
475      * invoked.
476      */
477     private static final class TestListener implements ApexEventListener {
478
479         /**
480          * {@inheritDoc}.
481          */
482         @Override
483         public synchronized void onApexEvent(final ApexEvent event) {
484             LOGGER.debug("result 1 is:" + event);
485             checkResult(event);
486             actionEventsReceived++;
487
488             final Date testStartTime = new Date((Long) event.get("TestTimestamp"));
489             final Date testEndTime = new Date();
490
491             LOGGER.debug("policy execution time: " + (testEndTime.getTime() - testStartTime.getTime()) + "ms");
492         }
493
494         /**
495          * Check result.
496          *
497          * @param result the result
498          */
499         private void checkResult(final ApexEvent result) {
500             assertTrue(result.getName().startsWith("Event0004") || result.getName().startsWith("Event0104"));
501
502             assertEquals("This is a test slogan", result.get("TestSlogan"));
503             assertEquals((byte) 123, result.get("TestMatchCase"));
504             assertEquals(34.5445667, result.get("TestTemperature"));
505             assertTrue(((byte) result.get("TestMatchCaseSelected")) >= 0
506                     && ((byte) result.get("TestMatchCaseSelected") <= 3));
507             assertTrue(((byte) result.get("TestEstablishCaseSelected")) >= 0
508                     && ((byte) result.get("TestEstablishCaseSelected") <= 3));
509             assertTrue(((byte) result.get("TestDecideCaseSelected")) >= 0
510                     && ((byte) result.get("TestDecideCaseSelected") <= 3));
511             assertTrue(
512                     ((byte) result.get("TestActCaseSelected")) >= 0 && ((byte) result.get("TestActCaseSelected") <= 3));
513         }
514     }
515
516     /**
517      * Gets the model string.
518      *
519      * @param policyModel the eca policy model
520      * @return the model string
521      * @throws ApexModelException the apex model exception
522      * @throws IOException Signals that an I/O exception has occurred.
523      */
524     private static String getModelString(final AxPolicyModel policyModel) throws ApexModelException, IOException {
525         try (final ByteArrayOutputStream baOutputStream = new ByteArrayOutputStream()) {
526             new ApexModelWriter<AxPolicyModel>(AxPolicyModel.class).write(policyModel, baOutputStream);
527             return baOutputStream.toString();
528         }
529     }
530 }