2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 * ============LICENSE_END=========================================================
25 package org.openecomp.appc.oam.processor;
27 import org.openecomp.appc.i18n.Msg;
28 import org.openecomp.appc.oam.OAMCommandStatus;
29 import org.openecomp.appc.statemachine.impl.readers.AppcOamStates;
31 import java.util.HashMap;
33 import java.util.concurrent.Future;
36 * Base runnable actions for OAM APIs, such as maintenance mode, restart, start and stop API.
38 * <p>This class holds the general action async handling methods for all OAM APIs.
39 * <p>Specific API action runnable will overwrite the general methods to add specific behaviors.
41 * <p>Subclass constructor must set the following class variables:
46 abstract class BaseActionRunnable extends BaseCommon implements Runnable {
47 final String OAM_OPERATION_TIMEOUT_SECOND = "appc.OAM.api.timeout";
48 /** Default operation tiemout set to 1 minute */
49 final int DEFAULT_OAM_OPERATION_TIMEOUT = 60;
50 /** Abort message format with flexible operation name */
51 final String ABORT_MESSAGE_FORMAT = "Aborting %s operation.";
52 /** Timeout message format with flexible operation name */
53 final String TIMEOUT_MESSAGE_FORMAT = "%s operation has reached timeout %d milliseconds.";
54 /** Failure message format with flexible number of bundles */
55 final String BUNDLE_OPERATION_FAILED_FORMAT = "%d bundle(s) failed, see logs for details.";
57 private boolean isWaiting = false;
58 private AppcOamStates currentState;
61 boolean doTimeoutChecking = false;
63 String actionName = "Need to be reset";
65 AppcOamStates finalState;
67 BaseProcessor myParent;
68 Map<String, Future<?>> bundleNameToFuture = new HashMap<>();
73 * @param parent BaseProcessor who has called this constructor.
75 BaseActionRunnable(BaseProcessor parent) {
76 super(parent.logger, parent.configurationHelper, parent.stateHelper, parent.operationHelper);
79 commonHeader = parent.commonHeader;
80 startTime = parent.startTime;
87 * Set timeout in milliseconds
89 void setTimeoutValues() {
90 Integer timeoutSeconds = myParent.timeoutSeconds;
91 if (timeoutSeconds == null) {
92 timeoutMs = configurationHelper.getConfig().getIntegerProperty(
93 OAM_OPERATION_TIMEOUT_SECOND, DEFAULT_OAM_OPERATION_TIMEOUT) * 1000;
95 timeoutMs = timeoutSeconds.longValue() * 1000;
98 doTimeoutChecking = timeoutMs != 0;
99 if (doTimeoutChecking) {
100 startTimeMs = startTime.getTime();
102 logDebug("%s action runnable check timeout (%s) with timeout (%d)ms, and startMs (%d)",
103 rpc.name(), Boolean.toString(doTimeoutChecking), timeoutMs, startTimeMs);
109 setInitialLogProperties();
110 logDebug(String.format("===========in %s run (waiting: %s)=======",
111 actionName, Boolean.toString(isWaiting)));
119 isWaiting = !checkState();
124 } catch (Exception e) {
125 logDebug(String.format("%s got exception %s", actionName, e.getMessage()));
126 logger.error(actionName + " exception", e);
129 clearRequestLogProperties();
134 * Keep waiting to be override by children classes for different behaviors.
135 * Timeout is validated here.
138 logDebug(String.format("%s runnable waiting, current state is %s.",
139 actionName, currentState == null ? "null" : currentState.toString()));
141 isTimeout("keepWaiting");
145 * Check if the timeout milliseconds has reached.
147 * @param parentName String of the caller, for logging purpose.
148 * @return true if the timeout has reached, otherwise false.
150 boolean isTimeout(String parentName) {
151 logDebug(String.format("%s task isTimeout called from %s", actionName, parentName));
152 if (doTimeoutChecking
153 && System.currentTimeMillis() - startTimeMs > timeoutMs) {
154 logger.error(String.format("%s operation timeout (%d) ms has reached, abort with error state.",
155 actionName, timeoutMs));
157 setStatus(OAMCommandStatus.TIMEOUT, String.format(TIMEOUT_MESSAGE_FORMAT, rpc.name(), timeoutMs));
158 postAction(AppcOamStates.Error);
165 * Check if all bundle operations are successful through BundleHelper.
166 * If there's failed bundler operation, set error status and trigger postAction with Error state.
168 * @return true if bundler operations have failure, otherwise false.
170 boolean hasBundleOperationFailure() {
171 long failedTask = myParent.bundleHelper.getFailedMetrics(bundleNameToFuture);
172 if (failedTask == 0) {
176 setStatus(OAMCommandStatus.UNEXPECTED_ERROR, String.format(BUNDLE_OPERATION_FAILED_FORMAT, failedTask));
177 postAction(AppcOamStates.Error);
182 * Set class <b>status</b> to REJECTED with abort message.
184 void setAbortStatus() {
185 setStatus(OAMCommandStatus.REJECTED, String.format(ABORT_MESSAGE_FORMAT, rpc.name()));
189 * Final handling. The thread is cancelled.
191 * @param setState boolean to indicate if set OAM state or not
193 void postDoAction(boolean setState) {
194 logDebug(String.format("Finished %s task", actionName));
198 * Handling for after doAction. does post notification, issue audit log and set OAM state based on input.
200 * @param state of AppcOamState to be set as OAM state when it is not null.
202 void postAction(AppcOamStates state) {
203 operationHelper.sendNotificationMessage(rpc, commonHeader, status);
206 stateHelper.setState(state);
209 auditInfoLog(auditMsg);
211 myParent.cancelAsyncTask();
217 * @return true if final state reached, otherwise return false
219 boolean checkState() {
220 if (isTimeout("checkState")) {
221 myParent.bundleHelper.cancelUnfinished(bundleNameToFuture);
225 if (!myParent.bundleHelper.isAllTaskDone(bundleNameToFuture)) {
229 if (hasBundleOperationFailure()) {
233 currentState = stateHelper.getBundlesState();
234 if (currentState == finalState) {
235 setStatus(OAMCommandStatus.SUCCESS);
242 abstract boolean doAction();