1f07b277c9acfa16a03211675fca1cf9c2a30da5
[appc.git] / appc-dispatcher / appc-request-handler / appc-request-handler-core / src / main / java / org / openecomp / appc / requesthandler / impl / RequestHandlerImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
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
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  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  * ============LICENSE_END=========================================================
23  */
24
25 package org.onap.appc.requesthandler.impl;
26
27 import com.att.eelf.configuration.EELFLogger;
28 import com.att.eelf.configuration.EELFManager;
29 import com.att.eelf.i18n.EELFResourceManager;
30 import org.onap.appc.requesthandler.constant.Constants;
31 import org.onap.appc.domainmodel.lcm.RuntimeContext;
32 import org.onap.appc.domainmodel.lcm.Status;
33 import org.onap.appc.domainmodel.lcm.VNFOperation;
34 import org.onap.appc.executor.UnstableVNFException;
35 import org.onap.appc.executor.objects.LCMCommandStatus;
36 import org.onap.appc.executor.objects.Params;
37 import org.onap.appc.executor.objects.UniqueRequestIdentifier;
38 import org.onap.appc.i18n.Msg;
39 import org.onap.appc.lockmanager.api.LockException;
40 import org.onap.appc.lockmanager.api.LockManager;
41 import org.onap.appc.logging.LoggingConstants;
42 import org.onap.appc.workingstatemanager.WorkingStateManager;
43 import org.onap.appc.workingstatemanager.objects.VNFWorkingState;
44
45 /**
46  * This class provides application logic for the Request/Response Handler Component.
47  *
48  */
49 public class RequestHandlerImpl extends AbstractRequestHandlerImpl {
50
51     /**
52      * APP-C VNF lock idle timeout in milliseconds. Applied only when locking VNF using northbound API "lock"
53      */
54     private static final String PROP_IDLE_TIMEOUT = "org.onap.appc.lock.idleTimeout";
55
56     private LockManager lockManager;
57
58     private WorkingStateManager workingStateManager;
59
60     public void setLockManager(LockManager lockManager) {
61         this.lockManager = lockManager;
62     }
63
64     public void setWorkingStateManager(WorkingStateManager workingStateManager) {
65         this.workingStateManager = workingStateManager;
66     }
67
68     private static final EELFLogger logger = EELFManager.getInstance().getLogger(RequestHandlerImpl.class);
69
70     protected void handleRequest(RuntimeContext runtimeContext) {
71
72         switch (runtimeContext.getRequestContext().getAction()) {
73             case Lock:
74                 try {
75                     lockWithTimeout(runtimeContext.getVnfContext().getId(), runtimeContext.getRequestContext().getCommonHeader().getRequestId());
76                     fillStatus(runtimeContext, LCMCommandStatus.SUCCESS, null);
77                 } catch (LockException e) {
78                     Params params = new Params().addParam("errorMsg", e.getMessage());
79                     fillStatus(runtimeContext, LCMCommandStatus.LOCKING_FAILURE, params);
80                     storeErrorMessageToLog(runtimeContext,
81                             LoggingConstants.TargetNames.APPC,
82                             LoggingConstants.TargetNames.LOCK_MANAGER,
83                             EELFResourceManager.format(Msg.VF_SERVER_BUSY, runtimeContext.getVnfContext().getId()));
84                 }
85                 break;
86
87             case Unlock:
88                 try {
89                     releaseVNFLock(runtimeContext.getVnfContext().getId(), runtimeContext.getRequestContext().getCommonHeader().getRequestId());
90                     fillStatus(runtimeContext,LCMCommandStatus.SUCCESS, null);
91                 } catch (LockException e) {
92                     //TODO add proper error code and message
93                     //  logger.error(EELFResourceManager.format(Msg.VF_SERVER_BUSY, runtimeContext.getVnfContext().getId()));
94                     Params params = new Params().addParam("errorMsg", e.getMessage());
95                     fillStatus(runtimeContext, LCMCommandStatus.LOCKING_FAILURE, params);
96                 }
97                 break;
98
99             case CheckLock:
100                 boolean isLocked = lockManager.isLocked(runtimeContext.getVnfContext().getId());
101                 fillStatus(runtimeContext,LCMCommandStatus.SUCCESS, null);
102                 runtimeContext.getResponseContext().addKeyValueToAdditionalContext("locked", String.valueOf(isLocked).toUpperCase());
103                 break;
104             default:
105                 try {
106                     boolean lockAcquired = acquireVNFLock(runtimeContext.getVnfContext().getId(), runtimeContext.getRequestContext().getCommonHeader().getRequestId(), 0);
107                     runtimeContext.setIsLockAcquired(lockAcquired);
108                     callWfOperation(runtimeContext);
109                 } catch (LockException e) {
110                     Params params = new Params().addParam("errorMsg", e.getMessage());
111                     fillStatus(runtimeContext, LCMCommandStatus.LOCKING_FAILURE, params);
112                 } finally {
113                     if (runtimeContext.isLockAcquired()) {
114                         final int statusCode = runtimeContext.getResponseContext().getStatus().getCode();
115                         if (statusCode % 100 == 2 || statusCode % 100 == 3) {
116                             try {
117                                 releaseVNFLock(runtimeContext.getVnfContext().getId(), runtimeContext.getRequestContext().getCommonHeader().getRequestId());
118                             } catch (LockException e) {
119                                 logger.error("Error releasing the lock",e);
120                             }
121                         }
122                     }
123                 }
124         }
125     }
126
127     private void releaseVNFLock(String vnfId, String transactionId) throws LockException {
128         lockManager.releaseLock(vnfId, transactionId);
129         logger.info("Lock released for vnfID = " + vnfId);
130     }
131
132     protected void lockWithTimeout(String vnfId, String requestId) throws LockException {
133         long timeout = configuration.getLongProperty(PROP_IDLE_TIMEOUT, Constants.DEFAULT_IDLE_TIMEOUT);
134         acquireVNFLock(vnfId, requestId, timeout);
135     }
136
137     private boolean acquireVNFLock(String vnfID, String requestId, long timeout) throws LockException {
138         if (logger.isTraceEnabled())
139             logger.trace("Entering to acquireVNFLock with vnfID = " + vnfID);
140         boolean lockAcquired = lockManager.acquireLock(vnfID, requestId, timeout);
141         if (lockAcquired) {
142             logger.info("Lock acquired for vnfID = " + vnfID);
143         } else {
144             logger.info("vnfID = " + vnfID + " was already locked");
145         }
146         return lockAcquired;
147     }
148
149     /**
150      * This method perform operations required before execution of workflow starts. It retrieves next state for current operation from Lifecycle manager and update it in AAI.
151      *
152      * @param vnfId String of VNF ID
153      * @param readOnlyActivity boolean indicator
154      * @param  requestIdentifierString - string contains id uniquely represents the request
155      * @param forceFlag boolean indicator
156      * @throws UnstableVNFException when failed
157      */
158     @Override
159     public void onRequestExecutionStart(String vnfId, boolean readOnlyActivity, String requestIdentifierString, boolean forceFlag) throws UnstableVNFException {
160         if (logger.isTraceEnabled()) {
161             logger.trace("Entering to onRequestExecutionStart with vnfId = " + vnfId + "and requestIdentifierString = " + requestIdentifierString);
162         }
163
164         if(!readOnlyActivity || !forceFlag || workingStateManager.isVNFStable(vnfId)) {
165             boolean updated = false;
166             try {
167                 updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, requestIdentifierString, forceFlag);
168             }  catch (Exception e) {
169                 logger.error("Error updating working state for vnf " + vnfId + e);
170                 throw new RuntimeException(e);
171             }
172             if (!updated) {
173                 throw new UnstableVNFException("VNF is not stable for vnfID = " + vnfId);
174             }
175         }
176
177         if (logger.isTraceEnabled())
178             logger.trace("Exiting from onRequestExecutionStart ");
179     }
180
181     private boolean isReadOnlyAction(VNFOperation action) {
182         if (VNFOperation.Sync.toString().equals(action) ||
183                 VNFOperation.Audit.toString().equals(action) ||
184                 VNFOperation.ConfigBackup.toString().equals(action) ||
185                 VNFOperation.ConfigBackupDelete.toString().equals(action) ||
186                 VNFOperation.ConfigExport.toString().equals(action)){
187             return true;
188         }
189         return false;
190     }
191
192     @Override
193     public void onRequestExecutionEnd(RuntimeContext runtimeContext, boolean isAAIUpdated) {
194         super.onRequestExecutionEnd(runtimeContext,isAAIUpdated);
195         VNFWorkingState workingState;
196         Status status = runtimeContext.getResponseContext().getStatus();
197         if (status.getCode() == LCMCommandStatus.SUCCESS.getResponseCode() || isReadOnlyAction(runtimeContext.getRequestContext().getAction())) {
198             workingState = VNFWorkingState.STABLE;
199         } else {
200             workingState = VNFWorkingState.UNKNOWN;
201         }
202
203         UniqueRequestIdentifier requestIdentifier = new UniqueRequestIdentifier(runtimeContext.getResponseContext().getCommonHeader().getOriginatorId(),
204                 runtimeContext.getResponseContext().getCommonHeader().getRequestId(),
205                 runtimeContext.getResponseContext().getCommonHeader().getSubRequestId());
206
207         String requestIdentifierString = requestIdentifier.toIdentifierString();
208         workingStateManager.setWorkingState(runtimeContext.getVnfContext().getId(), workingState, requestIdentifierString, false);
209         logger.debug("Reset lock for vnfId " + runtimeContext.getVnfContext().getId());
210         resetLock(runtimeContext.getVnfContext().getId(), runtimeContext.getResponseContext().getCommonHeader().getRequestId(), runtimeContext.isLockAcquired(), true);
211     }
212
213     private void resetLock(String vnfId, String requestId, boolean lockAcquired, boolean resetLockTimeout) {
214         if (lockAcquired) {
215             try {
216                 releaseVNFLock(vnfId, requestId);
217             } catch (LockException e) {
218                 logger.error("Unlock VNF [" + vnfId + "] failed. Request id: [" + requestId + "]", e);
219             }
220         } else if (resetLockTimeout) {
221             try {
222                 // reset timeout to previous value
223                 lockWithTimeout(vnfId, requestId);
224             } catch (LockException e) {
225                 logger.error("Reset lock idle timeout for VNF [" + vnfId + "] failed. Request id: [" + requestId + "]", e);
226             }
227         }
228     }
229
230     @Override
231     public void onRequestTTLEnd(RuntimeContext runtimeContext, boolean updateAAI) {
232         super.onRequestTTLEnd(runtimeContext,updateAAI);
233         resetLock(runtimeContext.getVnfContext().getId(), runtimeContext.getResponseContext().getCommonHeader().getRequestId(), runtimeContext.isLockAcquired(), true);
234     }
235 }