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
 
  10  *      http://www.apache.org/licenses/LICENSE-2.0
 
  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.
 
  18  * SPDX-License-Identifier: Apache-2.0
 
  19  * ============LICENSE_END=========================================================
 
  22 package org.onap.policy.apex.examples.adaptive;
 
  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;
 
  29 import java.io.IOException;
 
  30 import java.util.Random;
 
  31 import java.util.concurrent.TimeUnit;
 
  33 import org.junit.After;
 
  34 import org.junit.Before;
 
  35 import org.junit.Test;
 
  36 import org.onap.policy.apex.context.impl.schema.java.JavaSchemaHelperParameters;
 
  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.SchemaParameters;
 
  40 import org.onap.policy.apex.core.engine.EngineParameters;
 
  41 import org.onap.policy.apex.core.engine.engine.ApexEngine;
 
  42 import org.onap.policy.apex.core.engine.engine.impl.ApexEngineFactory;
 
  43 import org.onap.policy.apex.core.engine.event.EnEvent;
 
  44 import org.onap.policy.apex.examples.adaptive.model.AdaptiveDomainModelFactory;
 
  45 import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
 
  46 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
 
  47 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
 
  48 import org.onap.policy.apex.model.enginemodel.concepts.AxEngineState;
 
  49 import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
 
  50 import org.onap.policy.apex.plugins.executor.java.JavaExecutorParameters;
 
  51 import org.onap.policy.apex.plugins.executor.mvel.MvelExecutorParameters;
 
  52 import org.onap.policy.common.parameters.ParameterService;
 
  53 import org.slf4j.ext.XLogger;
 
  54 import org.slf4j.ext.XLoggerFactory;
 
  57  * This policy passes, and recieves a Double event context filed called "EVCDouble".<br>
 
  58  * The policy tries to detect anomalies in the pattern of values for EVCDouble<br>
 
  59  * See the 2 test cases below (1 short, 1 long)
 
  61  * @author John Keeney (John.Keeney@ericsson.com)
 
  63 public class AnomalyDetectionTslUseCaseTest {
 
  64     private static final XLogger LOGGER = XLoggerFactory.getXLogger(AnomalyDetectionTslUseCaseTest.class);
 
  66     private static final int MAXITERATIONS = 3660;
 
  67     private static final Random RAND = new Random(System.currentTimeMillis());
 
  69     private SchemaParameters schemaParameters;
 
  70     private ContextParameters contextParameters;
 
  71     private EngineParameters engineParameters;
 
  77     public void beforeTest() {
 
  78         schemaParameters = new SchemaParameters();
 
  80         schemaParameters.setName(ContextParameterConstants.SCHEMA_GROUP_NAME);
 
  81         schemaParameters.getSchemaHelperParameterMap().put("JAVA", new JavaSchemaHelperParameters());
 
  83         ParameterService.register(schemaParameters);
 
  85         contextParameters = new ContextParameters();
 
  87         contextParameters.setName(ContextParameterConstants.MAIN_GROUP_NAME);
 
  88         contextParameters.getDistributorParameters().setName(ContextParameterConstants.DISTRIBUTOR_GROUP_NAME);
 
  89         contextParameters.getLockManagerParameters().setName(ContextParameterConstants.LOCKING_GROUP_NAME);
 
  90         contextParameters.getPersistorParameters().setName(ContextParameterConstants.PERSISTENCE_GROUP_NAME);
 
  92         ParameterService.register(contextParameters);
 
  93         ParameterService.register(contextParameters.getDistributorParameters());
 
  94         ParameterService.register(contextParameters.getLockManagerParameters());
 
  95         ParameterService.register(contextParameters.getPersistorParameters());
 
  97         engineParameters = new EngineParameters();
 
  98         engineParameters.getExecutorParameterMap().put("MVEL", new MvelExecutorParameters());
 
  99         engineParameters.getExecutorParameterMap().put("JAVA", new JavaExecutorParameters());
 
 100         ParameterService.register(engineParameters);
 
 107     public void afterTest() {
 
 108         ParameterService.deregister(engineParameters);
 
 110         ParameterService.deregister(contextParameters.getDistributorParameters());
 
 111         ParameterService.deregister(contextParameters.getLockManagerParameters());
 
 112         ParameterService.deregister(contextParameters.getPersistorParameters());
 
 113         ParameterService.deregister(contextParameters);
 
 115         ParameterService.deregister(schemaParameters);
 
 119      * Test anomaly detection tsl.
 
 121      * @throws ApexException the apex exception
 
 122      * @throws InterruptedException the interrupted exception
 
 123      * @throws IOException Signals that an I/O exception has occurred.
 
 126     // once through the long running test below
 
 127     public void testAnomalyDetectionTsl() throws ApexException, InterruptedException, IOException {
 
 128         final AxPolicyModel apexPolicyModel = new AdaptiveDomainModelFactory().getAnomalyDetectionPolicyModel();
 
 129         assertNotNull(apexPolicyModel);
 
 131         final AxValidationResult validationResult = new AxValidationResult();
 
 132         apexPolicyModel.validate(validationResult);
 
 133         assertTrue(validationResult.isValid());
 
 135         final AxArtifactKey key = new AxArtifactKey("AnomalyTSLApexEngine", "0.0.1");
 
 137         final ApexEngine apexEngine1 = new ApexEngineFactory().createApexEngine(key);
 
 139         final TestApexActionListener listener1 = new TestApexActionListener("TestListener1");
 
 140         apexEngine1.addEventListener("listener", listener1);
 
 141         apexEngine1.updateModel(apexPolicyModel, false);
 
 143         final EnEvent triggerEvent =
 
 144                 apexEngine1.createEvent(new AxArtifactKey("AnomalyDetectionTriggerEvent", "0.0.1"));
 
 145         final double rval = RAND.nextGaussian();
 
 146         triggerEvent.put("Iteration", 0);
 
 147         triggerEvent.put("MonitoredValue", rval);
 
 148         LOGGER.info("Triggering policy in Engine 1 with " + triggerEvent);
 
 149         apexEngine1.handleEvent(triggerEvent);
 
 150         final EnEvent result = listener1.getResult();
 
 151         LOGGER.info("Receiving action event {} ", result);
 
 152         assertEquals("ExecutionIDs are different", triggerEvent.getExecutionId(), result.getExecutionId());
 
 153         triggerEvent.clear();
 
 155         await().atLeast(1, TimeUnit.MILLISECONDS).until(() -> result.isEmpty());
 
 160      * This policy passes, and recieves a Double event context filed called "EVCDouble"<br>
 
 161      * The policy tries to detect anomalies in the pattern of values for EVCDouble <br>
 
 162      * This test case generates a SineWave-like pattern for the parameter, repeating every 360 iterations. (These Period
 
 163      * should probably be set using TaskParameters!) Every 361st value is a random number!, so should be identified as
 
 164      * an Anomaly. The policy has 3 Decide Tasks, and the Decide TaskSelectionLogic picks one depending on the
 
 165      * 'Anomaliness' of the input data. <br>
 
 166      * To plot the results grep debug results for the string "************", paste into excel and delete non-relevant
 
 169      * @throws ApexException the apex exception
 
 170      * @throws InterruptedException the interrupted exception
 
 171      * @throws IOException Signals that an I/O exception has occurred.
 
 173     // Test is disabled by default. uncomment below, or execute using the main() method
 
 175     // EG Dos command: apex-core.engine> mvn
 
 176     // -Dtest=org.onap.policy.apex.core.engine.ml.TestAnomalyDetectionTslUseCase test | findstr /L /C:"Apex [main] DEBUG
 
 177     // c.e.a.e.TaskSelectionExecutionLogging -
 
 178     // TestAnomalyDetectionTSL_Policy0000DecideStateTaskSelectionLogic.getTask():"
 
 179     public void testAnomalyDetectionTslmain() throws ApexException, InterruptedException, IOException {
 
 181         final AxPolicyModel apexPolicyModel = new AdaptiveDomainModelFactory().getAnomalyDetectionPolicyModel();
 
 182         assertNotNull(apexPolicyModel);
 
 184         final AxValidationResult validationResult = new AxValidationResult();
 
 185         apexPolicyModel.validate(validationResult);
 
 186         assertTrue(validationResult.isValid());
 
 188         final AxArtifactKey key = new AxArtifactKey("AnomalyTSLApexEngine", "0.0.1");
 
 189         final EngineParameters parameters = new EngineParameters();
 
 190         parameters.getExecutorParameterMap().put("MVEL", new MvelExecutorParameters());
 
 191         parameters.getExecutorParameterMap().put("JAVA", new JavaExecutorParameters());
 
 193         final ApexEngine apexEngine1 = new ApexEngineFactory().createApexEngine(key);
 
 195         final TestApexActionListener listener1 = new TestApexActionListener("TestListener1");
 
 196         apexEngine1.addEventListener("listener1", listener1);
 
 197         apexEngine1.updateModel(apexPolicyModel, false);
 
 200         final EnEvent triggerEvent =
 
 201                 apexEngine1.createEvent(new AxArtifactKey("AnomalyDetectionTriggerEvent", "0.0.1"));
 
 202         assertNotNull(triggerEvent);
 
 204         for (int iteration = 0; iteration < MAXITERATIONS; iteration++) {
 
 205             // Trigger the policy in engine 1
 
 207             double value = (Math.sin(Math.toRadians(iteration))) + (RAND.nextGaussian() / 25.0);
 
 208             // lets make every 361st number a random value to perhaps flag as an anomaly
 
 209             if (((iteration + 45) % 361) == 0) {
 
 210                 value = (RAND.nextGaussian() * 2.0);
 
 212             triggerEvent.put("Iteration", iteration);
 
 213             triggerEvent.put("MonitoredValue", value);
 
 214             LOGGER.info("Iteration " + iteration + ":\tTriggering policy in Engine 1 with " + triggerEvent);
 
 215             apexEngine1.handleEvent(triggerEvent);
 
 216             final EnEvent result = listener1.getResult();
 
 217             LOGGER.info("Iteration " + iteration + ":\tReceiving action event {} ", result);
 
 218             triggerEvent.clear();
 
 222         await().atLeast(1000, TimeUnit.MILLISECONDS).until(() -> apexEngine1.getState().equals(AxEngineState.STOPPED));
 
 228      * @param args the arguments
 
 229      * @throws ApexException the apex exception
 
 230      * @throws InterruptedException the interrupted exception
 
 231      * @throws IOException Signals that an I/O exception has occurred.
 
 233     public static void main(final String[] args) throws ApexException, InterruptedException, IOException {
 
 234         new AnomalyDetectionTslUseCaseTest().testAnomalyDetectionTslmain();