Refactor CommandTask classes to be immutable
[appc.git] / appc-dispatcher / appc-command-executor / appc-command-executor-core / src / main / java / org / openecomp / appc / executor / impl / LCMCommandTask.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : APP-C
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                                              reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.openecomp.appc.executor.impl;
23
24
25 import java.util.HashMap;
26 import java.util.Map;
27
28 import org.apache.commons.lang3.StringUtils;
29 import org.openecomp.appc.domainmodel.lcm.CommonHeader;
30 import org.openecomp.appc.domainmodel.lcm.RuntimeContext;
31 import org.openecomp.appc.domainmodel.lcm.VNFOperation;
32 import org.openecomp.appc.executor.UnstableVNFException;
33 import org.openecomp.appc.executor.objects.CommandResponse;
34 import org.openecomp.appc.executor.objects.LCMCommandStatus;
35 import org.openecomp.appc.executor.objects.Params;
36 import org.openecomp.appc.executor.objects.UniqueRequestIdentifier;
37 import org.openecomp.appc.lifecyclemanager.LifecycleManager;
38 import org.openecomp.appc.lifecyclemanager.objects.LifecycleException;
39 import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException;
40 import org.openecomp.appc.lifecyclemanager.objects.VNFOperationOutcome;
41 import org.openecomp.appc.requesthandler.RequestHandler;
42 import org.openecomp.appc.workflow.WorkFlowManager;
43 import org.openecomp.appc.workflow.objects.WorkflowResponse;
44 import org.openecomp.sdnc.sli.SvcLogicContext;
45 import org.openecomp.sdnc.sli.SvcLogicException;
46 import org.openecomp.sdnc.sli.SvcLogicResource;
47 import org.openecomp.sdnc.sli.aai.AAIService;
48 import org.osgi.framework.BundleContext;
49 import org.osgi.framework.FrameworkUtil;
50 import org.osgi.framework.ServiceReference;
51
52 import com.att.eelf.configuration.EELFLogger;
53 import com.att.eelf.configuration.EELFManager;
54
55
56 public class LCMCommandTask extends CommandTask {
57
58         private final AAIService aaiService;
59         private final LifecycleManager lifecyclemanager;
60
61         private static final EELFLogger logger = EELFManager.getInstance().getLogger(LCMCommandTask.class);
62
63     public LCMCommandTask(RuntimeContext commandRequest, RequestHandler requestHandler, WorkFlowManager workflowManager,
64             LifecycleManager lifecyclemanager) {
65         super(commandRequest, requestHandler, workflowManager);
66         this.lifecyclemanager = lifecyclemanager;
67
68                 BundleContext bctx = FrameworkUtil.getBundle(AAIService.class).getBundleContext();
69                 // Get AAIadapter reference
70                 ServiceReference sref = bctx.getServiceReference(AAIService.class.getName());
71                 if (sref != null) {
72                         logger.info("AAIService from bundlecontext");
73                         aaiService = (AAIService) bctx.getService(sref);
74
75                 } else {
76                         logger.info("AAIService error from bundlecontext");
77                         logger.warn("Cannot find service reference for org.openecomp.sdnc.sli.aai.AAIService");
78                         aaiService = null;
79                 }
80         }
81
82
83         @Override
84         public void onRequestCompletion(CommandResponse response) {
85         final RuntimeContext request = commandRequest;
86         boolean isAAIUpdated = false;
87                 try {
88
89                         final int statusCode = request.getResponseContext().getStatus().getCode();
90
91                         if (logger.isDebugEnabled()) {
92                                 logger.debug("Workflow Execution Status = "+ statusCode);
93                         }
94
95                         boolean isSuccess = statusCode == 100 || statusCode == 400;
96
97                         if (isSuccess && VNFOperation.Terminate ==  request.getRequestContext().getAction()) {
98                                 SvcLogicContext ctx = new SvcLogicContext();
99                                 ctx = getVnfdata(request.getVnfContext().getId(), "vnf", ctx);
100                                 isAAIUpdated = aaiService.deleteGenericVnfData(request.getVnfContext().getId(), ctx.getAttribute("vnf.resource-version"));
101                         }
102                         else{
103                                 isAAIUpdated = updateAAI(request.getVnfContext().getId() , false, isSuccess);
104                         }
105                         logger.debug("isAAIUpdated = " + isAAIUpdated);
106                 }
107                 catch(Exception e1) {
108                         logger.error("Exception = " + e1);
109                         throw new RuntimeException(e1);
110                 }
111                 finally {
112                         super.onRequestCompletion(response, isAAIUpdated);
113                 }
114         }
115
116         @Override
117         public void run() {
118         final RuntimeContext request = commandRequest;
119         boolean isAAIUpdated = false;
120                 final String vnfId = request.getVnfContext().getId();
121                 final String vnfType = request.getVnfContext().getType();
122                 try {
123                         final CommonHeader commonHeader = request.getRequestContext().getCommonHeader();
124                         final boolean forceFlag = commonHeader.getFlags().isForce();
125                         UniqueRequestIdentifier requestIdentifier = new UniqueRequestIdentifier(commonHeader.getOriginatorId(),
126                                         commonHeader.getRequestId(), commonHeader.getSubRequestId());
127                         String requestIdentifierString = requestIdentifier.toIdentifierString();
128                         requestHandler.onRequestExecutionStart(vnfId,false, requestIdentifierString, forceFlag);
129
130                         final String currentStatus = request.getVnfContext().getStatus();
131                         final VNFOperation action = request.getRequestContext().getAction();
132
133                         final String nextState = lifecyclemanager.getNextState(vnfType, currentStatus, action.name());
134
135                         SvcLogicContext ctx = new SvcLogicContext();
136                         ctx=getVnfdata(vnfId, "onRequestExecutionStart", ctx);
137                         isAAIUpdated= postVnfdata(vnfId, nextState,"onRequestExecutionStart",ctx);
138                 } catch (NoTransitionDefinedException e) {
139                         logger.error("Error getting Next State for AAI Update:  " + e.getMessage(), e);
140                         Params params = new Params().addParam("actionName",e.event).addParam("currentState",e.currentState);
141                         request.getResponseContext().setStatus(LCMCommandStatus.NO_TRANSITION_DEFINE_FAILURE.toStatus(params));
142                         isAAIUpdated = false;
143                 } catch (UnstableVNFException e) {
144                         logger.error(e.getMessage(), e);
145                         Params params = new Params().addParam("vnfId",vnfId);
146                         request.getResponseContext().setStatus(LCMCommandStatus.UNSTABLE_VNF_FAILURE.toStatus(params));
147                         isAAIUpdated = false;
148                 }catch (Exception e) {
149                         logger.error("Error before Request Execution starts.", e);
150                         String errorMsg = StringUtils.isEmpty(e.getMessage()) ? e.toString() : e.getMessage();
151                         Params params = new Params().addParam("errorMsg",errorMsg);
152                         request.getResponseContext().setStatus(LCMCommandStatus.UNEXPECTED_FAILURE.toStatus(params));
153                         isAAIUpdated =  false;
154                 }
155
156                 if (isAAIUpdated){
157                         super.execute();
158                 }else{
159                         String errorMsg = "Error updating A& AI before Workflow execution";
160                         logger.error(errorMsg);
161                         WorkflowResponse response = new WorkflowResponse();
162                         response.setResponseContext(request.getResponseContext());
163                         CommandResponse commandResponse = super.buildCommandResponse(response);
164                         this.onRequestCompletion(commandResponse);
165                 }
166         }
167
168
169
170         private boolean updateAAI(String vnf_id , boolean isTTLEnd , boolean executionStatus)
171         {
172                 String orchestrationStatus = null;
173                 String nextState;
174                 boolean callbackResponse;
175                 VNFOperationOutcome outcome;
176                 SvcLogicContext ctx = new SvcLogicContext();
177                 try {
178                         ctx=getVnfdata(vnf_id, "onRequestExecutionEnd",ctx);
179                         orchestrationStatus=ctx.getAttribute("onRequestExecutionEnd.orchestration-status");
180
181                         if(isTTLEnd){
182                                 outcome = VNFOperationOutcome.FAILURE;
183                         }
184                         else if(executionStatus){
185                                 outcome = VNFOperationOutcome.SUCCESS;
186                         }
187                         else{
188                                 outcome = VNFOperationOutcome.FAILURE;
189                         }
190                         nextState = lifecyclemanager.getNextState(null,orchestrationStatus, outcome.toString()) ;
191                         callbackResponse= postVnfdata(vnf_id, nextState,"onRequestExecutionEnd",ctx);
192                         logger.debug("AAI posting  status: " + callbackResponse);
193
194                 } catch (NoTransitionDefinedException e) {
195                         logger.debug("Transition not defined for State = " + orchestrationStatus);
196                         callbackResponse =false;
197                 } catch (LifecycleException e) {
198                         logger.debug("State or command not registered with State Machine. State = " + orchestrationStatus);
199                         callbackResponse =false;
200                 }
201                 return callbackResponse;
202         }
203
204
205         private SvcLogicContext getVnfdata(String vnf_id, String prefix,SvcLogicContext ctx) {
206                 String key="vnf-id = '"+ vnf_id+"'";
207                 logger.debug("inside getVnfdata=== "+key);
208                 try {
209                         SvcLogicResource.QueryStatus response = aaiService.query("generic-vnf", false, null, key,prefix, null, ctx);
210                         if(SvcLogicResource.QueryStatus.NOT_FOUND.equals(response)){
211                                 logger.warn("VNF " + vnf_id + " not found while updating A&AI");
212                                 throw new RuntimeException("VNF not found for vnf_id = "+ vnf_id);
213                         }
214                         else if(SvcLogicResource.QueryStatus.FAILURE.equals(response)){
215                                 throw new RuntimeException("Error Querying AAI with vnfID = " +vnf_id);
216                         }
217                         logger.info("AAIResponse: " + response.toString());
218                 } catch (SvcLogicException e) {
219                         logger.error("Error in getVnfdata "+ e);
220                         throw new RuntimeException(e);
221                 }
222                 return ctx;
223         }
224
225         private boolean postVnfdata(String vnf_id, String status,String prefix,SvcLogicContext ctx) {
226                 String key="vnf-id = '"+ vnf_id+"'";
227                 logger.debug("inside postVnfdata=== "+key);
228                 Map<String, String> data = new HashMap<>();
229                 data.put("orchestration-status", status);
230                 try {
231                         SvcLogicResource.QueryStatus response = aaiService.update("generic-vnf", key, data, prefix,  ctx);
232                         if(SvcLogicResource.QueryStatus.NOT_FOUND.equals(response)){
233                                 logger.warn("VNF " + vnf_id + " not found while updating A&AI");
234                                 return false;
235                         }
236                         logger.info("AAIResponse: " + response.toString());
237                         if(response.toString().equals("SUCCESS"))
238                         {
239                                 return true;
240                         }
241                 } catch (SvcLogicException e) {
242                         logger.error("Error in postVnfdata "+ e);
243                         throw new RuntimeException(e);
244                 }
245                 return false;
246         }
247
248 }