3a15b3906c5cb593b4627a2d3220baca0e85b3e1
[policy/apex-pdp.git] / testsuites / integration / integration-uservice-test / src / test / java / org / onap / policy / apex / testsuites / integration / uservice / engine / ApexServiceModelUpdateTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-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.testsuites.integration.uservice.engine;
23
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertNotNull;
26 import static org.junit.Assert.assertTrue;
27 import static org.junit.Assert.fail;
28
29 import java.io.ByteArrayOutputStream;
30 import java.io.IOException;
31 import java.util.Date;
32 import java.util.HashMap;
33 import java.util.Map;
34
35 import org.junit.After;
36 import org.junit.Before;
37 import org.junit.Test;
38 import org.onap.policy.apex.context.parameters.ContextParameterConstants;
39 import org.onap.policy.apex.context.parameters.ContextParameters;
40 import org.onap.policy.apex.context.parameters.DistributorParameters;
41 import org.onap.policy.apex.context.parameters.LockManagerParameters;
42 import org.onap.policy.apex.context.parameters.PersistorParameters;
43 import org.onap.policy.apex.context.parameters.SchemaParameters;
44 import org.onap.policy.apex.core.engine.EngineParameterConstants;
45 import org.onap.policy.apex.core.engine.EngineParameters;
46 import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities;
47 import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
48 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
49 import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
50 import org.onap.policy.apex.model.basicmodel.handling.ApexModelWriter;
51 import org.onap.policy.apex.model.basicmodel.service.ModelService;
52 import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
53 import org.onap.policy.apex.plugins.executor.javascript.JavascriptExecutorParameters;
54 import org.onap.policy.apex.plugins.executor.mvel.MvelExecutorParameters;
55 import org.onap.policy.apex.service.engine.event.ApexEvent;
56 import org.onap.policy.apex.service.engine.event.ApexEventException;
57 import org.onap.policy.apex.service.engine.runtime.ApexEventListener;
58 import org.onap.policy.apex.service.engine.runtime.EngineService;
59 import org.onap.policy.apex.service.engine.runtime.EngineServiceEventInterface;
60 import org.onap.policy.apex.service.engine.runtime.impl.EngineServiceImpl;
61 import org.onap.policy.apex.service.parameters.ApexParameterConstants;
62 import org.onap.policy.apex.service.parameters.engineservice.EngineServiceParameters;
63 import org.onap.policy.apex.testsuites.integration.common.model.SampleDomainModelFactory;
64 import org.onap.policy.common.parameters.ParameterService;
65 import org.slf4j.ext.XLogger;
66 import org.slf4j.ext.XLoggerFactory;
67
68 /**
69  * The Class ApexServiceTest.
70  *
71  * @author Liam Fallon (liam.fallon@ericsson.com)
72  */
73 public class ApexServiceModelUpdateTest {
74     // Logger for this class
75     private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexServiceModelUpdateTest.class);
76
77     private final AxArtifactKey engineServiceKey = new AxArtifactKey("Machine-1_process-1_engine-1", "0.0.0");
78     private final EngineServiceParameters parameters = new EngineServiceParameters();
79     private EngineService service = null;
80     private TestListener listener = null;
81     private int actionEventsReceived = 0;
82
83     private AxPolicyModel apexSamplePolicyModel = null;
84     private String apexSampleModelString;
85
86     /**
87      * Set up parameters.
88      */
89     @Before
90     public void setupParameters() {
91         ParameterService.register(new SchemaParameters());
92         ParameterService.register(new ContextParameters());
93         ParameterService.register(new DistributorParameters());
94         ParameterService.register(new LockManagerParameters());
95         ParameterService.register(new PersistorParameters());
96         ParameterService.register(new EngineServiceParameters());
97
98         EngineParameters engineParameters = new EngineParameters();
99         engineParameters.getExecutorParameterMap().put("JAVASCRIPT", new JavascriptExecutorParameters());
100         ParameterService.register(engineParameters);
101     }
102
103     /**
104      * Clear down parameters.
105      */
106     @After
107     public void teardownParameters() {
108         ParameterService.deregister(EngineParameterConstants.MAIN_GROUP_NAME);
109         ParameterService.deregister(ApexParameterConstants.ENGINE_SERVICE_GROUP_NAME);
110         ParameterService.deregister(ContextParameterConstants.PERSISTENCE_GROUP_NAME);
111         ParameterService.deregister(ContextParameterConstants.LOCKING_GROUP_NAME);
112         ParameterService.deregister(ContextParameterConstants.DISTRIBUTOR_GROUP_NAME);
113         ParameterService.deregister(ContextParameterConstants.MAIN_GROUP_NAME);
114         ParameterService.deregister(ContextParameterConstants.SCHEMA_GROUP_NAME);
115     }
116
117     /**
118      * Sets up the test by creating an engine and reading in the test policy.
119      *
120      * @throws ApexException if something goes wrong
121      * @throws IOException on IO exceptions
122      */
123     @Before
124     public void setUp() throws ApexException, IOException {
125         // create engine with 3 threads
126         parameters.setInstanceCount(3);
127         parameters.setName(engineServiceKey.getName());
128         parameters.setVersion(engineServiceKey.getVersion());
129         parameters.setId(100);
130         parameters.getEngineParameters().getExecutorParameterMap().put("MVEL", new MvelExecutorParameters());
131         service = EngineServiceImpl.create(parameters);
132
133         LOGGER.debug("Running TestApexEngine. . .");
134
135         apexSamplePolicyModel = new SampleDomainModelFactory().getSamplePolicyModel("JAVASCRIPT");
136         assertNotNull(apexSamplePolicyModel);
137
138         apexSampleModelString = getModelString(apexSamplePolicyModel);
139
140         // create engine
141         listener = new TestListener();
142         service.registerActionListener("MyListener", listener);
143     }
144
145     /**
146      * Tear down the the test infrastructure.
147      *
148      * @throws ApexException if there is an error
149      */
150     @After
151     public void tearDown() throws Exception {
152         if (service != null) {
153             service.stop();
154         }
155         service = null;
156     }
157
158     /**
159      * Test start with no model.
160      */
161     @Test
162     public void testNoModelStart() {
163         try {
164             service.startAll();
165             fail("Engine should not start with no model");
166         } catch (final Exception e) {
167             e.printStackTrace();
168             assertEquals("start()<-Machine-1_process-1_engine-1-0:0.0.0,STOPPED,  cannot start engine, "
169                     + "engine has not been initialized, its model is not loaded", e.getMessage());
170         }
171     }
172
173     /**
174      * Test model update with string model without force.
175      *
176      * @throws ApexException if there is an error
177      */
178     @Test
179     public void testModelUpdateStringNewNoForce() throws ApexException {
180         service.updateModel(parameters.getEngineKey(), apexSampleModelString, false);
181
182         assertEquals(apexSamplePolicyModel.getKey(), ModelService.getModel(AxPolicyModel.class).getKey());
183     }
184
185     /**
186      * Test model update with string model with force.
187      *
188      * @throws ApexException if there is an error
189      */
190     @Test
191     public void testModelUpdateStringNewForce() throws ApexException {
192         service.updateModel(parameters.getEngineKey(), apexSampleModelString, true);
193
194         assertEquals(apexSamplePolicyModel.getKey(), ModelService.getModel(AxPolicyModel.class).getKey());
195     }
196
197     /**
198      * Test model update with a new string model without force.
199      *
200      * @throws ApexException if there is an error
201      */
202     @Test
203     public void testModelUpdateStringNewNewNoForce() throws ApexException {
204         service.updateModel(parameters.getEngineKey(), apexSampleModelString, false);
205
206         assertEquals(apexSamplePolicyModel.getKey(), ModelService.getModel(AxPolicyModel.class).getKey());
207
208         sendEvents();
209
210         service.updateModel(parameters.getEngineKey(), apexSampleModelString, false);
211         assertEquals(apexSamplePolicyModel.getKey(), ModelService.getModel(AxPolicyModel.class).getKey());
212
213         sendEvents();
214     }
215
216     /**
217      * Test incompatible model update with a model object without force.
218      *
219      * @throws ApexException if there is an error
220      */
221     @Test
222     public void testModelUpdateIncoNoForce() throws ApexException {
223         service.updateModel(parameters.getEngineKey(), apexSamplePolicyModel, false);
224
225         assertEquals(apexSamplePolicyModel.getKey(), ModelService.getModel(AxPolicyModel.class).getKey());
226
227         // Different model name, incompatible
228         final AxPolicyModel incoPolicyModel0 = new AxPolicyModel(apexSamplePolicyModel);
229         incoPolicyModel0.getKey().setName("INCOMPATIBLE");
230
231         try {
232             service.updateModel(parameters.getEngineKey(), incoPolicyModel0, false);
233             fail("model update should fail on incompatible model without force being true");
234         } catch (final Exception e) {
235             System.err.println(e.getMessage());
236             assertEquals("apex model update failed, supplied model with key \"INCOMPATIBLE:0.0.1\" is not a compatible "
237                     + "model update from the existing engine model " + "with key \"SamplePolicyModelJAVASCRIPT:0.0.1\"",
238                     e.getMessage());
239         }
240
241         // Still on old model
242         sendEvents();
243
244         // Different major version, incompatible
245         final AxPolicyModel incoPolicyModel1 = new AxPolicyModel(apexSamplePolicyModel);
246         incoPolicyModel1.getKey().setVersion("1.0.1");
247
248         try {
249             service.updateModel(parameters.getEngineKey(), incoPolicyModel1, false);
250             fail("model update should fail on incompatible model without force being true");
251         } catch (final Exception e) {
252             System.err.println(e.getMessage());
253             e.printStackTrace();
254             assertEquals("apex model update failed, supplied model with key \"SamplePolicyModelJAVASCRIPT:1.0.1\" "
255                     + "is not a compatible model update from the existing engine model with key "
256                     + "\"SamplePolicyModelJAVASCRIPT:0.0.1\"", e.getMessage());
257         }
258
259         // Still on old model
260         sendEvents();
261
262         // Different minor version, compatible
263         final AxPolicyModel coPolicyModel0 = new AxPolicyModel(apexSamplePolicyModel);
264         coPolicyModel0.getKey().setVersion("0.1.0");
265         service.updateModel(parameters.getEngineKey(), coPolicyModel0, false);
266
267         // On new compatible model
268         sendEvents();
269
270         // Different patch version, compatible
271         final AxPolicyModel coPolicyModel1 = new AxPolicyModel(apexSamplePolicyModel);
272         coPolicyModel1.getKey().setVersion("0.0.2");
273         service.updateModel(parameters.getEngineKey(), coPolicyModel1, false);
274
275         // On new compatible model
276         sendEvents();
277
278     }
279
280     /**
281      * Test incompatible model update with a model object with force.
282      *
283      * @throws ApexException if there is an error
284      */
285     @Test
286     public void testModelUpdateIncoForce() throws ApexException {
287         service.updateModel(parameters.getEngineKey(), apexSamplePolicyModel, false);
288
289         assertEquals(apexSamplePolicyModel.getKey(), ModelService.getModel(AxPolicyModel.class).getKey());
290
291         // Different model name, incompatible
292         final AxPolicyModel incoPolicyModel0 = new AxPolicyModel(apexSamplePolicyModel);
293         incoPolicyModel0.getKey().setName("INCOMPATIBLE");
294         service.updateModel(parameters.getEngineKey(), incoPolicyModel0, true);
295
296         // On updated model
297         sendEvents();
298
299         // Different major version, incompatible
300         final AxPolicyModel incoPolicyModel1 = new AxPolicyModel(apexSamplePolicyModel);
301         incoPolicyModel1.getKey().setVersion("1.0.1");
302         service.updateModel(parameters.getEngineKey(), incoPolicyModel1, true);
303
304         // On updated model
305         sendEvents();
306
307         // Different minor version, compatible
308         final AxPolicyModel coPolicyModel0 = new AxPolicyModel(apexSamplePolicyModel);
309         coPolicyModel0.getKey().setVersion("0.1.0");
310         service.updateModel(parameters.getEngineKey(), coPolicyModel0, true);
311
312         // On new compatible model
313         sendEvents();
314
315         // Different patch version, compatible
316         final AxPolicyModel coPolicyModel1 = new AxPolicyModel(apexSamplePolicyModel);
317         coPolicyModel1.getKey().setVersion("0.0.2");
318         service.updateModel(parameters.getEngineKey(), coPolicyModel1, true);
319
320         // On new compatible model
321         sendEvents();
322
323     }
324
325     /**
326      * Utility method to send some events into the test engine.
327      *
328      * @throws ApexEventException if there is an error
329      */
330     private void sendEvents() throws ApexEventException {
331         final EngineServiceEventInterface engineServiceEventInterface = service.getEngineServiceEventInterface();
332
333         // Send some events
334         final Date testStartTime = new Date();
335         final Map<String, Object> eventDataMap = new HashMap<String, Object>();
336         eventDataMap.put("TestSlogan", "This is a test slogan");
337         eventDataMap.put("TestMatchCase", (byte) 123);
338         eventDataMap.put("TestTimestamp", testStartTime.getTime());
339         eventDataMap.put("TestTemperature", 34.5445667);
340
341         final ApexEvent event =
342                 new ApexEvent("Event0000", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex");
343         event.putAll(eventDataMap);
344         engineServiceEventInterface.sendEvent(event);
345
346         final ApexEvent event2 =
347                 new ApexEvent("Event0100", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex");
348         event2.putAll(eventDataMap);
349         engineServiceEventInterface.sendEvent(event2);
350
351         // Wait for results
352         while (actionEventsReceived < 2) {
353             ThreadUtilities.sleep(100);
354         }
355         ThreadUtilities.sleep(500);
356     }
357
358     /**
359      * The listener interface for receiving test events. The class that is interested in processing a test event
360      * implements this interface, and the object created with that class is registered with a component using the
361      * component's <code>addTestListener</code> method. When the test event occurs, that object's appropriate method is
362      * invoked.
363      *
364      * @see TestEvent
365      */
366     private final class TestListener implements ApexEventListener {
367
368         /**
369          * {@inheritDoc}.
370          */
371         @Override
372         public synchronized void onApexEvent(final ApexEvent event) {
373             LOGGER.debug("result 1 is:" + event);
374             checkResult(event);
375             actionEventsReceived++;
376
377             final Date testStartTime = new Date((Long) event.get("TestTimestamp"));
378             final Date testEndTime = new Date();
379
380             LOGGER.info("policy execution time: " + (testEndTime.getTime() - testStartTime.getTime()) + "ms");
381         }
382
383         /**
384          * Check result.
385          *
386          * @param result the result
387          */
388         private void checkResult(final ApexEvent result) {
389             assertTrue(result.getName().startsWith("Event0004") || result.getName().startsWith("Event0104"));
390
391             assertTrue(result.get("TestSlogan").equals("This is a test slogan"));
392             assertTrue(result.get("TestMatchCase").equals((byte) 123));
393             assertTrue(result.get("TestTemperature").equals(34.5445667));
394             assertTrue(((byte) result.get("TestMatchCaseSelected")) >= 0
395                     && ((byte) result.get("TestMatchCaseSelected") <= 3));
396             assertTrue(((byte) result.get("TestEstablishCaseSelected")) >= 0
397                     && ((byte) result.get("TestEstablishCaseSelected") <= 3));
398             assertTrue(((byte) result.get("TestDecideCaseSelected")) >= 0
399                     && ((byte) result.get("TestDecideCaseSelected") <= 3));
400             assertTrue(
401                     ((byte) result.get("TestActCaseSelected")) >= 0 && ((byte) result.get("TestActCaseSelected") <= 3));
402         }
403     }
404
405     /**
406      * Gets the model string.
407      *
408      * @param policyModel the eca policy model
409      * @return the model string
410      * @throws ApexModelException the apex model exception
411      * @throws IOException Signals that an I/O exception has occurred.
412      */
413     private String getModelString(final AxPolicyModel policyModel) throws ApexModelException, IOException {
414         try (final ByteArrayOutputStream baOutputStream = new ByteArrayOutputStream()) {
415             new ApexModelWriter<AxPolicyModel>(AxPolicyModel.class).write(policyModel, baOutputStream);
416             return baOutputStream.toString();
417         }
418     }
419 }