Update license header in appc oam and outbound
[appc.git] / appc-oam / appc-oam-bundle / src / main / java / org / onap / appc / oam / processor / BaseProcessor.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Copyright (C) 2017 Amdocs
8  * =============================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * 
21  * ============LICENSE_END=========================================================
22  */
23
24 package org.onap.appc.oam.processor;
25
26 import com.att.eelf.configuration.EELFLogger;
27 import org.opendaylight.yang.gen.v1.org.onap.appc.oam.rev170303.status.Status;
28 import org.onap.appc.exceptions.APPCException;
29 import org.onap.appc.exceptions.InvalidInputException;
30 import org.onap.appc.exceptions.InvalidStateException;
31 import org.onap.appc.i18n.Msg;
32 import org.onap.appc.oam.OAMCommandStatus;
33 import org.onap.appc.oam.util.AsyncTaskHelper;
34 import org.onap.appc.oam.util.BundleHelper;
35 import org.onap.appc.oam.util.ConfigurationHelper;
36 import org.onap.appc.oam.util.OperationHelper;
37 import org.onap.appc.oam.util.StateHelper;
38 import org.onap.appc.statemachine.impl.readers.AppcOamStates;
39
40 import java.util.Date;
41 import java.util.concurrent.Future;
42 import java.util.concurrent.TimeUnit;
43 import java.util.concurrent.TimeoutException;
44
45 /**
46  * Base processor for OAM APIs, such as maintenance mode, restart, start and stop API.
47  *
48  * <p>This class holds the general API request sync handling methods for all OAM APIs.
49  * <p>Specific API processor will overwrite the general methods to add specific behaviors.
50  */
51 public abstract class BaseProcessor extends BaseCommon {
52     /** lock to serialize incoming OAM operations.  */
53     private static final Object LOCK = new Object();
54
55     final AsyncTaskHelper asyncTaskHelper;
56     final BundleHelper bundleHelper;
57
58     /** the requestTimeoutSeconds to use for this OAM operation */
59     private Integer requestTimeoutSeconds;
60     Msg auditMsg;
61     BaseActionRunnable runnable;
62     private Future<?> scheduledRunnable = null;
63
64     /**
65      * Constructor
66      *
67      * @param eelfLogger for logging
68      * @param configurationHelperIn for property reading
69      * @param stateHelperIn for APP-C OAM state checking
70      * @param asyncTaskHelperIn for scheduling async task
71      * @param operationHelperIn for operational helper
72      */
73     BaseProcessor(EELFLogger eelfLogger,
74                   ConfigurationHelper configurationHelperIn,
75                   StateHelper stateHelperIn,
76                   AsyncTaskHelper asyncTaskHelperIn,
77                   OperationHelper operationHelperIn) {
78         super(eelfLogger, configurationHelperIn, stateHelperIn, operationHelperIn);
79
80         asyncTaskHelper = asyncTaskHelperIn;
81         bundleHelper = new BundleHelper(eelfLogger, configurationHelper, stateHelper);
82     }
83
84     /**
85      * Process synch handling and schedule asynch task
86      *
87      * @param requestInput of REST API request
88      * @return Status of new APP-C OAM state
89      */
90     public Status processRequest(final Object requestInput) {
91         startTime = new Date();
92         commonHeader = operationHelper.getCommonHeader(requestInput);
93         setStatus(OAMCommandStatus.ACCEPTED);
94
95         try {
96             preProcess(requestInput);
97             scheduleAsyncTask();
98         } catch (Exception e) {
99             setErrorStatus(e);
100         } finally {
101             postProcess();
102         }
103
104         return status;
105     }
106
107     /**
108      * Preprocess before actual handling of the REST API call. Does:
109      * <p> - commonHeader validation
110      * <p> - get NextState as well as validate if next state is valid
111      * <p> - set logging properties
112      * <p> - set appcCurrentState to next state
113      *
114      * @throws InvalidInputException when commonHeader validation failed
115      * @throws APPCException         when state validation failed
116      */
117     protected void preProcess(final Object requestInput)
118         throws InvalidInputException, APPCException, InvalidStateException,InterruptedException,TimeoutException {
119         setInitialLogProperties();
120         operationHelper.isInputValid(requestInput);
121
122         //The OAM request may specify timeout value
123         requestTimeoutSeconds = operationHelper.getParamRequestTimeout(requestInput);
124
125         //All OAM operation pass through here first to validate if an OAM state change is allowed.
126         //If a state change is allowed cancel the occurring OAM (if any) before starting this one.
127         //we will synchronized so that only one can do this at any given time.
128         synchronized(LOCK) {
129             AppcOamStates currentOamState = stateHelper.getCurrentOamState();
130
131             //make sure this OAM operation can transition to the desired OAM operation
132             AppcOamStates nextState = operationHelper.getNextState(
133                     rpc.getAppcOperation(), currentOamState);
134
135             stateHelper.setState(nextState);
136
137
138             try {
139                 //cancel the  BaseActionRunnable currently executing
140                 //it got to be completely terminated before proceeding
141                 asyncTaskHelper.cancelBaseActionRunnable(
142                         rpc,
143                         currentOamState,
144                         getTimeoutMilliseconds(),
145                         TimeUnit.MILLISECONDS
146                 );
147             } catch (TimeoutException e) {
148                 stateHelper.setState(AppcOamStates.Error);
149                 throw e;
150             }
151
152
153         }
154     }
155
156     /**
157      * Post process includes audit logging as well as clear MDC properties.
158      */
159     private void postProcess() {
160         auditInfoLog(auditMsg);
161         clearRequestLogProperties();
162     }
163
164     /**
165      * Schedule async task through AsyncTaskHelper.
166      */
167     protected void scheduleAsyncTask() {
168         if (runnable == null) {
169             logger.error(String.format(
170                 "Skipped schedule async task for rpc(%s) due to runnable is null", rpc.name()));
171             return;
172         }
173
174         scheduledRunnable = asyncTaskHelper.scheduleBaseRunnable(
175             runnable, runnable::abortRunnable, getInitialDelayMillis(), getDelayMillis());
176     }
177
178
179     /**
180      * The timeout for this OAM operation. The timeout source is chosen in the following order:
181      * request, config file, default value
182      * @return  - the timeout for this OAM operation.
183      */
184     long getTimeoutMilliseconds() {
185         return configurationHelper.getOAMOperationTimeoutValue(this.requestTimeoutSeconds);
186     }
187
188
189     /**
190      * @return initialDelayMillis - the time to delay first execution of {@link BaseActionRunnable}
191      */
192     protected long getInitialDelayMillis(){
193         return 0L;
194     }
195
196     /**
197      * @return delayMillis the delay between the consecutive executions of  {@link BaseActionRunnable}
198      */
199     private long getDelayMillis(){
200         return 1000L;
201     }
202
203     /**
204      * Cancel the scheduled {@link BaseActionRunnable}  through AsyncTaskHelper
205      */
206     void cancelAsyncTask() {
207         if (scheduledRunnable == null) {
208             logger.error(String.format(
209                 "Skipped cancel schedule async task for rpc(%s) due to scheduledRunnable is null", rpc.name()));
210             return;
211         }
212         scheduledRunnable.cancel(true);
213     }
214
215 }