Changes for checkstyle 8.32
[policy/apex-pdp.git] / examples / examples-adaptive / src / test / java / org / onap / policy / apex / examples / adaptive / AutoLearnTslUseCaseTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  *  Modifications Copyright (C) 2019-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.examples.adaptive;
23
24 import static org.awaitility.Awaitility.await;
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.IOException;
30 import java.util.Random;
31 import java.util.concurrent.TimeUnit;
32 import org.junit.After;
33 import org.junit.Before;
34 import org.junit.Test;
35 import org.onap.policy.apex.context.impl.schema.java.JavaSchemaHelperParameters;
36 import org.onap.policy.apex.context.parameters.ContextParameterConstants;
37 import org.onap.policy.apex.context.parameters.ContextParameters;
38 import org.onap.policy.apex.context.parameters.SchemaParameters;
39 import org.onap.policy.apex.core.engine.EngineParameters;
40 import org.onap.policy.apex.core.engine.engine.ApexEngine;
41 import org.onap.policy.apex.core.engine.engine.impl.ApexEngineFactory;
42 import org.onap.policy.apex.core.engine.event.EnEvent;
43 import org.onap.policy.apex.examples.adaptive.model.AdaptiveDomainModelFactory;
44 import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
45 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
46 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
47 import org.onap.policy.apex.model.enginemodel.concepts.AxEngineState;
48 import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
49 import org.onap.policy.apex.plugins.executor.java.JavaExecutorParameters;
50 import org.onap.policy.apex.plugins.executor.mvel.MvelExecutorParameters;
51 import org.onap.policy.common.parameters.ParameterService;
52 import org.slf4j.ext.XLogger;
53 import org.slf4j.ext.XLoggerFactory;
54
55 // TODO: Auto-generated Javadoc
56 /**
57  * Test Auto learning in TSL.
58  *
59  * @author John Keeney (John.Keeney@ericsson.com)
60  */
61 public class AutoLearnTslUseCaseTest {
62     private static final XLogger LOGGER = XLoggerFactory.getXLogger(AutoLearnTslUseCaseTest.class);
63
64     private static final int MAXITERATIONS = 1000;
65     private static final Random rand = new Random(System.currentTimeMillis());
66
67     private SchemaParameters schemaParameters;
68     private ContextParameters contextParameters;
69     private EngineParameters engineParameters;
70
71     /**
72      * Before test.
73      */
74     @Before
75     public void beforeTest() {
76         schemaParameters = new SchemaParameters();
77         
78         schemaParameters.setName(ContextParameterConstants.SCHEMA_GROUP_NAME);
79         schemaParameters.getSchemaHelperParameterMap().put("JAVA", new JavaSchemaHelperParameters());
80
81         ParameterService.register(schemaParameters);
82         
83         contextParameters = new ContextParameters();
84
85         contextParameters.setName(ContextParameterConstants.MAIN_GROUP_NAME);
86         contextParameters.getDistributorParameters().setName(ContextParameterConstants.DISTRIBUTOR_GROUP_NAME);
87         contextParameters.getLockManagerParameters().setName(ContextParameterConstants.LOCKING_GROUP_NAME);
88         contextParameters.getPersistorParameters().setName(ContextParameterConstants.PERSISTENCE_GROUP_NAME);
89
90         ParameterService.register(contextParameters);
91         ParameterService.register(contextParameters.getDistributorParameters());
92         ParameterService.register(contextParameters.getLockManagerParameters());
93         ParameterService.register(contextParameters.getPersistorParameters());
94         
95         engineParameters = new EngineParameters();
96         engineParameters.getExecutorParameterMap().put("MVEL", new MvelExecutorParameters());
97         engineParameters.getExecutorParameterMap().put("JAVA", new JavaExecutorParameters());
98         ParameterService.register(engineParameters);
99     }
100
101     /**
102      * After test.
103      */
104     @After
105     public void afterTest() {
106         ParameterService.deregister(engineParameters);
107         
108         ParameterService.deregister(contextParameters.getDistributorParameters());
109         ParameterService.deregister(contextParameters.getLockManagerParameters());
110         ParameterService.deregister(contextParameters.getPersistorParameters());
111         ParameterService.deregister(contextParameters);
112
113         ParameterService.deregister(schemaParameters);
114     }
115
116     /**
117      * Test auto learn tsl.
118      *
119      * @throws ApexException the apex exception
120      * @throws InterruptedException the interrupted exception
121      * @throws IOException Signals that an I/O exception has occurred.
122      */
123     @Test
124     // once through the long running test below
125     public void testAutoLearnTsl() throws ApexException, InterruptedException, IOException {
126         final AxPolicyModel apexPolicyModel = new AdaptiveDomainModelFactory().getAutoLearnPolicyModel();
127         assertNotNull(apexPolicyModel);
128
129         final AxValidationResult validationResult = new AxValidationResult();
130         apexPolicyModel.validate(validationResult);
131         assertTrue(validationResult.isValid());
132
133         final AxArtifactKey key = new AxArtifactKey("AADMApexEngine", "0.0.1");
134
135         final ApexEngine apexEngine1 = new ApexEngineFactory().createApexEngine(key);
136
137         final TestApexActionListener listener1 = new TestApexActionListener("TestListener1");
138         apexEngine1.addEventListener("listener", listener1);
139         apexEngine1.updateModel(apexPolicyModel, false);
140         apexEngine1.start();
141         final EnEvent triggerEvent = apexEngine1.createEvent(new AxArtifactKey("AutoLearnTriggerEvent", "0.0.1"));
142         final double rval = rand.nextGaussian();
143         triggerEvent.put("MonitoredValue", rval);
144         triggerEvent.put("LastMonitoredValue", 0D);
145         LOGGER.info("Triggering policy in Engine 1 with " + triggerEvent);
146         apexEngine1.handleEvent(triggerEvent);
147         final EnEvent result = listener1.getResult();
148         LOGGER.info("Receiving action event {} ", result);
149         assertEquals("ExecutionIDs are different", triggerEvent.getExecutionId(), result.getExecutionId());
150         triggerEvent.clear();
151         result.clear();
152         await().atLeast(10, TimeUnit.MILLISECONDS).until(() -> triggerEvent.isEmpty() && result.isEmpty());
153         apexEngine1.stop();
154     }
155
156     /**
157      * This policy passes, and receives a Double event context filed called "EVCDouble"<br>
158      * The policy tries to keep the value at 50, with a Min -100, Max 100 (These should probably be set using
159      * TaskParameters!)<br>
160      * The policy has 7 Decide Tasks that manipulate the value of this field in unknown ways.<br>
161      * The Decide TSL learns the effect of each task, and then selects the appropriate task to get the value back to
162      * 50<br>
163      * After the value settles close to 50 for a while, the test Rests the value to to random number and then
164      * continues<br>
165      * To plot the results grep stdout debug results for the string "*******", paste into excel and delete non-relevant
166      * columns<br>
167      *
168      * @throws ApexException the apex exception
169      * @throws InterruptedException the interrupted exception
170      * @throws IOException Signals that an I/O exception has occurred.
171      */
172     // @Test
173     public void testAutoLearnTslMain() throws ApexException, InterruptedException, IOException {
174
175         final double dwant = 50.0;
176         final double toleranceTileJump = 3.0;
177
178         final AxPolicyModel apexPolicyModel = new AdaptiveDomainModelFactory().getAutoLearnPolicyModel();
179         assertNotNull(apexPolicyModel);
180
181         final AxValidationResult validationResult = new AxValidationResult();
182         apexPolicyModel.validate(validationResult);
183         assertTrue(validationResult.isValid());
184
185         final AxArtifactKey key = new AxArtifactKey("AADMApexEngine", "0.0.1");
186         final EngineParameters parameters = new EngineParameters();
187         parameters.getExecutorParameterMap().put("MVEL", new MvelExecutorParameters());
188         parameters.getExecutorParameterMap().put("JAVA", new JavaExecutorParameters());
189
190         final ApexEngine apexEngine1 = new ApexEngineFactory().createApexEngine(key);
191
192         final TestApexActionListener listener1 = new TestApexActionListener("TestListener1");
193         apexEngine1.addEventListener("listener1", listener1);
194         apexEngine1.updateModel(apexPolicyModel, false);
195         apexEngine1.start();
196
197         final EnEvent triggerEvent = apexEngine1.createEvent(new AxArtifactKey("AutoLearnTriggerEvent", "0.0.1"));
198         assertNotNull(triggerEvent);
199         final double dmin = -100;
200         final double dmax = 100;
201
202         double rval = (((rand.nextGaussian() + 1) / 2) * (dmax - dmin)) + dmin;
203         triggerEvent.put("MonitoredValue", rval);
204         triggerEvent.put("LastMonitoredValue", 0);
205
206         double avval = 0;
207         double distance;
208         double avcount = 0;
209
210         for (int iteration = 0; iteration < MAXITERATIONS; iteration++) {
211             // Trigger the policy in engine 1
212             LOGGER.info("Triggering policy in Engine 1 with " + triggerEvent);
213             apexEngine1.handleEvent(triggerEvent);
214             final EnEvent result = listener1.getResult();
215             LOGGER.info("Receiving action event {} ", result);
216             triggerEvent.clear();
217
218             double val = (Double) result.get("MonitoredValue");
219             final double prevval = (Double) result.get("LastMonitoredValue");
220
221             triggerEvent.put("MonitoredValue", prevval);
222             triggerEvent.put("LastMonitoredValue", val);
223
224             avcount = Math.min((avcount + 1), 20); // maintain average of only the last 20 values
225             avval = ((avval * (avcount - 1)) + val) / (avcount);
226
227             distance = Math.abs(dwant - avval);
228             if (distance < toleranceTileJump) {
229                 rval = (((rand.nextGaussian() + 1) / 2) * (dmax - dmin)) + dmin;
230                 val = rval;
231                 triggerEvent.put("MonitoredValue", val);
232                 LOGGER.info("Iteration " + iteration + ": Average " + avval + " has become closer (" + distance
233                         + ") than " + toleranceTileJump + " to " + dwant + " so reseting val:\t\t\t\t\t\t\t\t" + val);
234                 avval = 0;
235                 avcount = 0;
236             }
237             LOGGER.info("Iteration " + iteration + ": \tpreval\t" + prevval + "\tval\t" + val + "\tavval\t" + avval);
238
239             result.clear();
240             await().atLeast(10, TimeUnit.MILLISECONDS).until(() -> !result.isEmpty());
241         }
242
243         apexEngine1.stop();
244         await().atMost(1000, TimeUnit.MILLISECONDS).until(() -> apexEngine1.getState().equals(AxEngineState.STOPPED));
245     }
246
247     /**
248      * The main method.
249      *
250      * @param args the arguments
251      * @throws ApexException the apex exception
252      * @throws InterruptedException the interrupted exception
253      * @throws IOException Signals that an I/O exception has occurred.
254      */
255     public static void main(final String[] args) throws ApexException, InterruptedException, IOException {
256         new AutoLearnTslUseCaseTest().testAutoLearnTslMain();
257     }
258 }