3f360ea9cf833fdf861728a450bf2cdd03f0b934
[policy/apex-pdp.git] / core / core-engine / src / main / java / org / onap / policy / apex / core / engine / executor / TaskSelectExecutor.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  *  Modifications Copyright (C) 2019 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.core.engine.executor;
23
24 import static org.onap.policy.common.utils.validation.Assertions.argumentNotNull;
25
26 import java.util.Properties;
27
28 import lombok.NonNull;
29
30 import org.onap.policy.apex.context.ContextException;
31 import org.onap.policy.apex.core.engine.ExecutorParameters;
32 import org.onap.policy.apex.core.engine.context.ApexInternalContext;
33 import org.onap.policy.apex.core.engine.event.EnEvent;
34 import org.onap.policy.apex.core.engine.executor.context.TaskSelectionExecutionContext;
35 import org.onap.policy.apex.core.engine.executor.exception.StateMachineException;
36 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
37 import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
38 import org.onap.policy.apex.model.policymodel.concepts.AxState;
39 import org.slf4j.ext.XLogger;
40 import org.slf4j.ext.XLoggerFactory;
41
42 /**
43  * This abstract class executes a the task selection logic of a state of an Apex policy and is specialized by classes
44  * that implement execution of task selection logic.
45  *
46  * @author Sven van der Meer (sven.van.der.meer@ericsson.com)
47  * @author Liam Fallon (liam.fallon@ericsson.com)
48  */
49 public abstract class TaskSelectExecutor implements Executor<EnEvent, AxArtifactKey, AxState, ApexInternalContext> {
50     // Logger for this class
51     private static final XLogger LOGGER = XLoggerFactory.getXLogger(TaskSelectExecutor.class);
52
53     // Hold the state and context definitions for this task selector
54     private Executor<?, ?, ?, ?> parent = null;
55     private AxState axState = null;
56     private ApexInternalContext context = null;
57
58     // Holds the incoming event and outgoing task keys
59     private EnEvent incomingEvent = null;
60     private AxArtifactKey outgoingTaskKey = null;
61
62     // The next task selection executor
63     private Executor<EnEvent, AxArtifactKey, AxState, ApexInternalContext> nextExecutor = null;
64
65     // The task selection execution context; contains the facades for events and context to be used
66     // by tasks executed by
67     // this task selection executor
68     private TaskSelectionExecutionContext executionContext;
69
70     /**
71      * Gets the execution context.
72      *
73      * @return the execution context
74      */
75     protected TaskSelectionExecutionContext getExecutionContext() {
76         return executionContext;
77     }
78
79     /**
80      * {@inheritDoc}.
81      */
82     @Override
83     public void setContext(final Executor<?, ?, ?, ?> newParent, final AxState newAxState,
84             final ApexInternalContext newContext) {
85         this.parent = newParent;
86         this.axState = newAxState;
87         this.context = newContext;
88     }
89
90     /**
91      * {@inheritDoc}.
92      */
93     @Override
94     public void prepare() throws StateMachineException {
95         LOGGER.debug("prepare:" + axState.getKey().getId() + "," + axState.getTaskSelectionLogic().getLogicFlavour()
96                 + "," + axState.getTaskSelectionLogic().getLogic());
97         argumentNotNull(axState.getTaskSelectionLogic().getLogic(), "task selection logic cannot be null.");
98     }
99
100     /**
101      * {@inheritDoc}.
102      */
103     @Override
104     public AxArtifactKey execute(final long executionId, final Properties executionProperties,
105             final EnEvent newIncomingEvent) throws StateMachineException, ContextException {
106         throw new StateMachineException("execute() not implemented on class");
107     }
108
109     /**
110      * {@inheritDoc}.
111      */
112     @Override
113     public final void executePre(final long executionId, @NonNull final Properties executionProperties,
114             final EnEvent newIncomingEvent) throws StateMachineException {
115         LOGGER.debug("execute-pre:" + axState.getKey().getId() + "," + axState.getTaskSelectionLogic().getLogicFlavour()
116                 + "," + axState.getTaskSelectionLogic().getLogic());
117
118         this.incomingEvent = newIncomingEvent;
119
120         // Initialize the returned task object so it can be set
121         outgoingTaskKey = new AxArtifactKey();
122
123         // Get task selection context object
124         executionContext = new TaskSelectionExecutionContext(this, executionId, getSubject(), getIncoming(),
125                 getOutgoing(), getContext());
126     }
127
128     /**
129      * {@inheritDoc}.
130      */
131     @Override
132     public final void executePost(final boolean returnValue) throws StateMachineException {
133         if (!returnValue) {
134             String errorMessage = "execute-post: task selection logic failed on state \"" + axState.getKey().getId()
135                     + "\"";
136             if (executionContext.getMessage() != null) {
137                 errorMessage += ", user message: " + executionContext.getMessage();
138             }
139             LOGGER.warn(errorMessage);
140             throw new StateMachineException(errorMessage);
141         }
142
143         if (outgoingTaskKey == null || AxArtifactKey.getNullKey().getName().equals(outgoingTaskKey.getName())) {
144             outgoingTaskKey = axState.getDefaultTask();
145             LOGGER.debug("execute-post:" + axState.getKey().getId() + ", returning default task");
146             return;
147         }
148
149         if (!axState.getTaskReferences().containsKey(outgoingTaskKey)) {
150             LOGGER.error("execute-post: task \"" + outgoingTaskKey.getId()
151                     + "\" returned by task selection logic not defined on state \"" + axState.getKey().getId() + "\"");
152             throw new StateMachineException("task \"" + outgoingTaskKey.getId()
153                     + "\" returned by task selection logic not defined on state \"" + axState.getKey().getId() + "\"");
154         }
155
156         LOGGER.debug("execute-post:" + axState.getKey().getId() + "," + ", returning task " + outgoingTaskKey.getId());
157     }
158
159     /**
160      * {@inheritDoc}.
161      */
162     @Override
163     public void cleanUp() throws StateMachineException {
164         throw new StateMachineException("cleanUp() not implemented on class");
165     }
166
167     /**
168      * {@inheritDoc}.
169      */
170     @Override
171     public AxReferenceKey getKey() {
172         return axState.getKey();
173     }
174
175     /**
176      * {@inheritDoc}.
177      */
178     @Override
179     public Executor<?, ?, ?, ?> getParent() {
180         return parent;
181     }
182
183     /**
184      * {@inheritDoc}.
185      */
186     @Override
187     public AxState getSubject() {
188         return axState;
189     }
190
191     /**
192      * {@inheritDoc}.
193      */
194     @Override
195     public ApexInternalContext getContext() {
196         return context;
197     }
198
199     /**
200      * {@inheritDoc}.
201      */
202     @Override
203     public void setNext(final Executor<EnEvent, AxArtifactKey, AxState, ApexInternalContext> newNextExecutor) {
204         this.nextExecutor = newNextExecutor;
205     }
206
207     /**
208      * {@inheritDoc}.
209      */
210     @Override
211     public Executor<EnEvent, AxArtifactKey, AxState, ApexInternalContext> getNext() {
212         return nextExecutor;
213     }
214
215     /**
216      * {@inheritDoc}.
217      */
218     @Override
219     public EnEvent getIncoming() {
220         return incomingEvent;
221     }
222
223     /**
224      * {@inheritDoc}.
225      */
226     @Override
227     public AxArtifactKey getOutgoing() {
228         return outgoingTaskKey;
229     }
230
231     /**
232      * {@inheritDoc}.
233      */
234     @Override
235     public void setParameters(final ExecutorParameters parameters) {
236         // Not used
237     }
238 }