b13db033a8937343023689b2df281b441ecdded0
[policy/apex-pdp.git] / core / core-engine / src / main / java / org / onap / policy / apex / core / engine / executor / StateFinalizerExecutor.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.argumentOfClassNotNull;
25
26 import java.util.Map;
27 import java.util.Properties;
28
29 import lombok.NonNull;
30
31 import org.onap.policy.apex.context.ContextException;
32 import org.onap.policy.apex.core.engine.ExecutorParameters;
33 import org.onap.policy.apex.core.engine.context.ApexInternalContext;
34 import org.onap.policy.apex.core.engine.executor.context.StateFinalizerExecutionContext;
35 import org.onap.policy.apex.core.engine.executor.exception.StateMachineException;
36 import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
37 import org.onap.policy.apex.model.policymodel.concepts.AxState;
38 import org.onap.policy.apex.model.policymodel.concepts.AxStateFinalizerLogic;
39 import org.slf4j.ext.XLogger;
40 import org.slf4j.ext.XLoggerFactory;
41
42 /**
43  * This abstract class executes state finalizer logic in a state of an Apex policy and is specialized by classes that
44  * implement execution of state finalizer 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 StateFinalizerExecutor
50         implements Executor<Map<String, Object>, String, AxStateFinalizerLogic, ApexInternalContext> {
51     // Logger for this class
52     private static final XLogger LOGGER = XLoggerFactory.getXLogger(StateFinalizerExecutor.class);
53
54     // Repeated string constants
55     private static final String EXECUTE_POST_SFL = "execute-post: state finalizer logic \"";
56
57     // Hold the state and context definitions
58     private Executor<?, ?, ?, ?> parent = null;
59     private AxState axState = null;
60     private AxStateFinalizerLogic finalizerLogic = null;
61     private ApexInternalContext internalContext = null;
62
63     // Holds the incoming and outgoing fields
64     private Map<String, Object> incomingFields = null;
65
66     // The next state finalizer executor
67     private Executor<Map<String, Object>, String, AxStateFinalizerLogic, ApexInternalContext> nextExecutor = null;
68
69     // The execution context; contains the facades for events and context to be used by tasks
70     // executed by this task
71     // executor
72     private StateFinalizerExecutionContext executionContext = null;
73
74     /**
75      * Gets the execution internalContext.
76      *
77      * @return the execution context
78      */
79     protected StateFinalizerExecutionContext getExecutionContext() {
80         return executionContext;
81     }
82
83     /**
84      * {@inheritDoc}.
85      */
86     @Override
87     public void setContext(final Executor<?, ?, ?, ?> incomingParent,
88             final AxStateFinalizerLogic incomingFinalizerLogic, final ApexInternalContext incomingInternalContext) {
89         this.parent = incomingParent;
90         axState = (AxState) parent.getSubject();
91         this.finalizerLogic = incomingFinalizerLogic;
92         this.internalContext = incomingInternalContext;
93     }
94
95     /**
96      * {@inheritDoc}.
97      */
98     @Override
99     public void prepare() throws StateMachineException {
100         LOGGER.debug("prepare:" + finalizerLogic.getId() + "," + finalizerLogic.getLogicFlavour() + ","
101                 + finalizerLogic.getLogic());
102         argumentOfClassNotNull(finalizerLogic.getLogic(), StateMachineException.class,
103                 "state finalizer logic cannot be null.");
104     }
105
106     /**
107      * {@inheritDoc}.
108      */
109     @Override
110     public String execute(final long executionId, final Properties executionProperties,
111             final Map<String, Object> newIncomingFields) throws StateMachineException, ContextException {
112         throw new StateMachineException("execute() not implemented on abstract StateFinalizerExecutionContext class, "
113                 + "only on its subclasses");
114     }
115
116     /**
117      * {@inheritDoc}.
118      */
119     @Override
120     public final void executePre(final long executionId, @NonNull final Properties executionProperties,
121             final Map<String, Object> newIncomingFields) throws StateMachineException, ContextException {
122         LOGGER.debug("execute-pre:" + finalizerLogic.getLogicFlavour() + "," + getSubject().getId() + ","
123                 + finalizerLogic.getLogic());
124
125         // Record the incoming fields
126         this.incomingFields = newIncomingFields;
127
128         // Get state finalizer context object
129         executionContext = new StateFinalizerExecutionContext(this, executionId, executionProperties, axState,
130                 getIncoming(), axState.getStateOutputs().keySet(), getContext());
131     }
132
133     /**
134      * {@inheritDoc}.
135      */
136     @Override
137     public final void executePost(final boolean returnValue) throws StateMachineException, ContextException {
138         if (!returnValue) {
139             String errorMessage = "execute-post: state finalizer logic execution failure on state \"" + axState.getId()
140                     + "\" on finalizer logic " + finalizerLogic.getId();
141             if (executionContext.getMessage() != null) {
142                 errorMessage += ", user message: " + executionContext.getMessage();
143             }
144             LOGGER.warn(errorMessage);
145             throw new StateMachineException(errorMessage);
146         }
147
148         // Check a state output has been selected
149         if (getOutgoing() == null) {
150             String message = EXECUTE_POST_SFL + finalizerLogic.getId() + "\" did not select an output state";
151             LOGGER.warn(message);
152             throw new StateMachineException(message);
153         }
154
155         if (!axState.getStateOutputs().keySet().contains(getOutgoing())) {
156             LOGGER.warn(EXECUTE_POST_SFL + finalizerLogic.getId() + "\" selected output state \"" + getOutgoing()
157                     + "\" that does not exsist on state \"" + axState.getId() + "\"");
158             throw new StateMachineException(EXECUTE_POST_SFL + finalizerLogic.getId() + "\" selected output state \""
159                     + getOutgoing() + "\" that does not exsist on state \"" + axState.getId() + "\"");
160         }
161
162         LOGGER.debug("execute-post:{}, returning  state output \"{}\" and fields {}", finalizerLogic.getId(),
163                 getOutgoing(), incomingFields);
164     }
165
166     /**
167      * {@inheritDoc}.
168      */
169     @Override
170     public void cleanUp() throws StateMachineException {
171         throw new StateMachineException("cleanUp() not implemented on class");
172     }
173
174     /**
175      * {@inheritDoc}.
176      */
177     @Override
178     public AxReferenceKey getKey() {
179         return finalizerLogic.getKey();
180     }
181
182     /**
183      * {@inheritDoc}.
184      */
185     @Override
186     public Executor<?, ?, ?, ?> getParent() {
187         return parent;
188     }
189
190     /**
191      * {@inheritDoc}.
192      */
193     @Override
194     public AxStateFinalizerLogic getSubject() {
195         return finalizerLogic;
196     }
197
198     /**
199      * {@inheritDoc}.
200      */
201     @Override
202     public ApexInternalContext getContext() {
203         return internalContext;
204     }
205
206     /**
207      * {@inheritDoc}.
208      */
209     @Override
210     public Map<String, Object> getIncoming() {
211         return incomingFields;
212     }
213
214     /**
215      * {@inheritDoc}.
216      */
217     @Override
218     public String getOutgoing() {
219         if (executionContext != null) {
220             return executionContext.getSelectedStateOutputName();
221         } else {
222             return null;
223         }
224     }
225
226     /**
227      * {@inheritDoc}.
228      */
229     @Override
230     public void setNext(
231             final Executor<Map<String, Object>, String, AxStateFinalizerLogic, ApexInternalContext> inNextEx) {
232         this.nextExecutor = inNextEx;
233     }
234
235     /**
236      * {@inheritDoc}.
237      */
238     @Override
239     public Executor<Map<String, Object>, String, AxStateFinalizerLogic, ApexInternalContext> getNext() {
240         return nextExecutor;
241     }
242
243     /**
244      * {@inheritDoc}.
245      */
246     @Override
247     public void setParameters(final ExecutorParameters parameters) {
248         // Not used
249     }
250 }