2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2016-2018 Ericsson. All rights reserved.
4 * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
5 * Modifications Copyright (c) 2021 Nordix Foundation.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * SPDX-License-Identifier: Apache-2.0
20 * ============LICENSE_END=========================================================
23 package org.onap.policy.apex.examples.adaptive.model.java;
25 import java.util.Arrays;
26 import java.util.List;
27 import java.util.Random;
28 import org.onap.policy.apex.context.ContextException;
29 import org.onap.policy.apex.core.engine.executor.context.TaskSelectionExecutionContext;
30 import org.onap.policy.apex.examples.adaptive.concepts.AutoLearn;
33 * The Class AutoLearnPolicyDecideTaskSelectionLogic.
35 public class AutoLearnPolicyDecideTaskSelectionLogic {
36 // Recurring string constants
37 private static final String AUTO_LEARN_ALBUM = "AutoLearnAlbum";
38 private static final String AUTO_LEARN = "AutoLearn";
41 * This is not used for encryption/security, thus disabling sonar.
43 private static final Random RAND = new Random(System.currentTimeMillis()); // NOSONAR
45 private static final double WANT = 50.0;
51 * @param executor the executor
54 public boolean getTask(final TaskSelectionExecutionContext executor) {
55 var idString = executor.subject.getId();
56 executor.logger.debug(idString);
58 var inFieldsString = executor.inFields.toString();
59 executor.logger.debug(inFieldsString);
61 final List<String> tasks = executor.subject.getTaskNames();
65 executor.getContextAlbum(AUTO_LEARN_ALBUM).lockForWriting(AUTO_LEARN);
66 } catch (final ContextException e) {
67 executor.logger.error("Failed to acquire write lock on \"autoLearn\" context", e);
71 // Get the context object
72 var autoLearn = (AutoLearn) executor.getContextAlbum(AUTO_LEARN_ALBUM).get(AUTO_LEARN);
73 if (autoLearn == null) {
74 autoLearn = new AutoLearn();
77 // Check the lists are initialized
78 if (!autoLearn.isInitialized()) {
82 final double now = (Double) (executor.inFields.get("MonitoredValue"));
83 final double diff = now - WANT;
84 final int option = getOption(diff, autoLearn);
85 learn(option, diff, autoLearn);
87 executor.getContextAlbum(AUTO_LEARN_ALBUM).put(AUTO_LEARN_ALBUM, autoLearn);
90 executor.getContextAlbum(AUTO_LEARN_ALBUM).unlockForWriting(AUTO_LEARN);
91 } catch (final ContextException e) {
92 executor.logger.error("Failed to acquire write lock on \"autoLearn\" context", e);
96 executor.subject.getTaskKey(tasks.get(option)).copyTo(executor.selectedTask);
103 * @param diff the diff
104 * @param autoLearn the auto learn
107 private int getOption(final double diff, final AutoLearn autoLearn) {
108 final Double[] avdiffs = autoLearn.getAvDiffs().toArray(new Double[autoLearn.getAvDiffs().size()]);
109 final var r = RAND.nextInt(size);
111 int closestdowni = -1;
112 double closestup = Double.MAX_VALUE;
113 double closestdown = Double.MIN_VALUE;
114 for (var i = 0; i < size; i++) {
115 if (Double.isNaN(avdiffs[i])) {
118 if (avdiffs[i] >= diff && avdiffs[i] <= closestup) {
119 closestup = avdiffs[i];
122 if (avdiffs[i] <= diff && avdiffs[i] >= closestdown) {
123 closestdown = avdiffs[i];
127 return calculateReturnValue(diff, r, closestupi, closestdowni, closestup, closestdown);
133 * @param option the option
134 * @param diff the diff
135 * @param autoLearn the auto learn
137 private void learn(final int option, final double diff, final AutoLearn autoLearn) {
138 final Double[] avdiffs = autoLearn.getAvDiffs().toArray(new Double[autoLearn.getAvDiffs().size()]);
139 final Long[] counts = autoLearn.getCounts().toArray(new Long[autoLearn.getCounts().size()]);
140 if (option < 0 || option >= avdiffs.length) {
141 throw new IllegalArgumentException("Error: option" + option);
144 if (Double.isNaN(avdiffs[option])) {
145 avdiffs[option] = diff;
147 avdiffs[option] = (avdiffs[option] * (counts[option] - 1) + diff) / counts[option];
149 autoLearn.setAvDiffs(Arrays.asList(avdiffs));
150 autoLearn.setCounts(Arrays.asList(counts));
154 * Calculate the return value of the learning.
156 * @param diff the difference
157 * @param random the random value
158 * @param closestupi closest to i upwards
159 * @param closestdowni closest to i downwards
160 * @param closestup closest up value
161 * @param closestdown closest down value
162 * @return the return value
164 private int calculateReturnValue(final double diff, final int random, int closestupi, int closestdowni,
165 double closestup, double closestdown) {
166 if (closestupi == -1 || closestdowni == -1) {
169 if (closestupi == closestdowni) {
172 if (Math.abs(closestdown - diff) > Math.abs(closestup - diff)) {