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