a0b27462d01fd35c21bc7368d43d03b28a27d6ab
[appc.git] / appc-dispatcher / appc-request-handler / appc-request-handler-core / src / main / java / org / onap / appc / requesthandler / impl / RequestValidatorImpl.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  * Modifications Copyright (C) 2019 Ericsson
10  * =============================================================================
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  *
23  * ============LICENSE_END=========================================================
24  */
25
26 package org.onap.appc.requesthandler.impl;
27
28 import java.io.IOException;
29 import java.net.MalformedURLException;
30 import java.net.URL;
31 import java.util.ArrayList;
32 import java.util.Date;
33 import java.util.List;
34 import java.util.Properties;
35 import java.util.stream.Collectors;
36 import org.apache.commons.io.IOUtils;
37 import org.apache.commons.lang.ObjectUtils;
38 import org.apache.commons.lang.StringUtils;
39 import org.apache.http.HttpResponse;
40 import org.onap.appc.domainmodel.lcm.Flags;
41 import org.onap.appc.domainmodel.lcm.RequestContext;
42 import org.onap.appc.domainmodel.lcm.RuntimeContext;
43 import org.onap.appc.domainmodel.lcm.TransactionRecord;
44 import org.onap.appc.domainmodel.lcm.VNFContext;
45 import org.onap.appc.domainmodel.lcm.VNFOperation;
46 import org.onap.appc.exceptions.APPCException;
47 import org.onap.appc.executor.objects.LCMCommandStatus;
48 import org.onap.appc.executor.objects.Params;
49 import org.onap.appc.i18n.Msg;
50 import org.onap.appc.lockmanager.api.LockException;
51 import org.onap.appc.lockmanager.api.LockManager;
52 import org.onap.appc.logging.LoggingConstants;
53 import org.onap.appc.logging.LoggingUtils;
54 import org.onap.appc.requesthandler.exceptions.DGWorkflowNotFoundException;
55 import org.onap.appc.requesthandler.exceptions.LCMOperationsDisabledException;
56 import org.onap.appc.requesthandler.exceptions.MissingVNFDataInAAIException;
57 import org.onap.appc.requesthandler.exceptions.RequestValidationException;
58 import org.onap.appc.requesthandler.exceptions.VNFNotFoundException;
59 import org.onap.appc.requesthandler.exceptions.WorkflowNotFoundException;
60 import org.onap.appc.requesthandler.model.ActionIdentifierModel;
61 import org.onap.appc.requesthandler.model.Input;
62 import org.onap.appc.requesthandler.model.Request;
63 import org.onap.appc.requesthandler.model.RequestData;
64 import org.onap.appc.requesthandler.model.RequestModel;
65 import org.onap.appc.requesthandler.model.ScopeOverlapModel;
66 import org.onap.appc.rest.client.RestClientInvoker;
67 import org.onap.appc.validationpolicy.RequestValidationPolicy;
68 import org.onap.appc.validationpolicy.executors.RuleExecutor;
69 import org.onap.appc.validationpolicy.objects.RuleResult;
70 import org.onap.appc.workflow.WorkFlowManager;
71 import org.onap.appc.workflow.objects.WorkflowExistsOutput;
72 import org.onap.appc.workflow.objects.WorkflowRequest;
73 import org.onap.ccsdk.sli.adaptors.aai.AAIService;
74 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
75 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
76 import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
77 import org.osgi.framework.BundleContext;
78 import org.osgi.framework.FrameworkUtil;
79 import org.osgi.framework.ServiceReference;
80 import com.att.eelf.i18n.EELFResourceManager;
81 import com.fasterxml.jackson.databind.JsonNode;
82 import com.fasterxml.jackson.databind.ObjectMapper;
83
84 public class RequestValidatorImpl extends AbstractRequestValidatorImpl {
85
86     private WorkFlowManager workflowManager;
87     private LockManager lockManager;
88     private AAIService aaiService;
89     private RequestValidationPolicy requestValidationPolicy;
90     private RestClientInvoker client;
91     private String path;
92     private int transactionWindowInterval=0;
93
94     static final String SCOPE_OVERLAP_ENDPOINT = "appc.LCM.scopeOverlap.endpoint";
95     static final String ODL_USER = "appc.LCM.provider.user";
96     static final String ODL_PASS = "appc.LCM.provider.pass";
97     static final String TRANSACTION_WINDOW_HOURS = "appc.inProgressTransactionWindow.hours";
98
99     public void initialize() throws APPCException {
100         logger.info("Initializing RequestValidatorImpl.");
101         String endpoint = null;
102         String user = null;
103         String pass = null;
104         String transactionWindow = null;
105
106         Properties properties = configuration.getProperties();
107         if (properties != null) {
108             endpoint = properties.getProperty(SCOPE_OVERLAP_ENDPOINT);
109             user = properties.getProperty(ODL_USER);
110             pass = properties.getProperty(ODL_PASS);
111             transactionWindow = properties.getProperty(TRANSACTION_WINDOW_HOURS);
112         }
113         if (endpoint == null) {
114             String message = "End point is not defined for scope over lap service in appc.properties.";
115             logger.error(message);
116             // TODO throw following exception (and remove the "return") when
117             // entry in appc.properties file is made for scope overlap service
118             // endpoint
119             // and remove @Ignore in unit tests:
120             // testInitializeWithNullConfigProps,
121             // testInitializeWithoutEndpointProp
122             // throw new APPCException(message);
123             return;
124         }
125
126         if (StringUtils.isNotBlank(transactionWindow)) {
127             logger.info("RequestValidatorImpl::TransactionWindow defined !!!");
128             try {
129                 transactionWindowInterval = Integer.parseInt(transactionWindow);
130             }
131             catch (NumberFormatException e) {
132                 String message = "RequestValidatorImpl:::Error parsing transaction window interval!";
133                 logger.error(message, e);
134                 throw new APPCException(message);
135             }
136         }
137
138         try {
139             URL url = new URL(endpoint);
140             client = new RestClientInvoker(url);
141             client.setAuthentication(user, pass);
142             path = url.getPath();
143
144         } catch (MalformedURLException e) {
145             String message = "Invalid endpoint " + endpoint;
146             logger.error(message, e);
147             // TODO throw following exception when entry in appc.properties file
148             // is made for scope overlap service endpoint
149             // and remove @Ignore in unit test:
150             // testInitializeWithMalFormatEndpoint
151             // throw new APPCException(message);
152         }
153     }
154
155     private void getAAIservice() {
156         BundleContext bctx = FrameworkUtil.getBundle(AAIService.class).getBundleContext();
157         // Get AAIadapter reference
158         ServiceReference sref = bctx.getServiceReference(AAIService.class.getName());
159         if (sref != null) {
160             logger.info("AAIService from bundlecontext");
161             aaiService = (AAIService) bctx.getService(sref);
162
163         } else {
164             logger.error("Cannot find service reference for org.onap.ccsdk.sli.adaptors.aai.AAIService");
165
166         }
167     }
168
169     public void setLockManager(LockManager lockManager) {
170         this.lockManager = lockManager;
171     }
172
173     public void setClient(RestClientInvoker client) {
174         this.client = client;
175     }
176
177     public void setWorkflowManager(WorkFlowManager workflowManager) {
178         this.workflowManager = workflowManager;
179     }
180
181     public void setRequestValidationPolicy(RequestValidationPolicy requestValidationPolicy) {
182         this.requestValidationPolicy = requestValidationPolicy;
183     }
184
185     public void validateRequest(RuntimeContext runtimeContext) throws Exception {
186         if (logger.isTraceEnabled()) {
187             logger.trace(
188                     "Entering to validateRequest with RequestHandlerInput = " + ObjectUtils.toString(runtimeContext));
189         }
190         if (!lcmStateManager.isLCMOperationEnabled()) {
191             LoggingUtils.logErrorMessage(LoggingConstants.TargetNames.REQUEST_VALIDATOR,
192                     EELFResourceManager.format(Msg.LCM_OPERATIONS_DISABLED), this.getClass().getCanonicalName());
193             throw new LCMOperationsDisabledException("APPC LCM operations have been administratively disabled");
194         }
195
196         getAAIservice();
197         validateInput(runtimeContext);
198         String vnfId = runtimeContext.getRequestContext().getActionIdentifiers().getVnfId();
199         VNFContext vnfContext = queryAAI(vnfId);
200         runtimeContext.setVnfContext(vnfContext);
201         runtimeContext.getTransactionRecord().setTargetType(vnfContext.getType());
202
203         VNFOperation operation = runtimeContext.getRequestContext().getAction();
204         if (operation.isBuiltIn()) {
205             return;
206         }
207
208         validateVNFLock(runtimeContext);
209         checkWorkflowExists(vnfContext, runtimeContext.getRequestContext());
210
211         if (runtimeContext.getRequestContext().getCommonHeader().getFlags().isForce()) {
212             return;
213         }
214
215         List<TransactionRecord> inProgressTransactionsAll = transactionRecorder
216                 .getInProgressRequests(runtimeContext.getTransactionRecord(),0);
217         List<TransactionRecord> inProgressTransactions = transactionRecorder
218                 .getInProgressRequests(runtimeContext.getTransactionRecord(),transactionWindowInterval);
219
220         long inProgressTransactionsAllCount = inProgressTransactionsAll.size();
221         long inProgressTransactionsRelevant = inProgressTransactions.size();
222         logger.debug("In progress requests " + inProgressTransactions.toString());
223
224         if ( inProgressTransactions.isEmpty()){ //No need to check for scope overlap
225             return;
226         }
227
228         logInProgressTransactions(inProgressTransactions,inProgressTransactionsAllCount,
229             inProgressTransactionsRelevant );
230
231         Long exclusiveRequestCount = inProgressTransactions.stream()
232                 .filter(record -> record.getMode().equals(Flags.Mode.EXCLUSIVE.name())).count();
233         if (exclusiveRequestCount > 0) {
234             String message = "Request rejected - Existing request in progress with exclusive mode for VNF: " + vnfId;
235             throw new RequestValidationException(message, LCMCommandStatus.EXLCUSIVE_REQUEST_IN_PROGRESS,
236                     (new Params()).addParam("errorMsg", message));
237         }
238
239         Boolean scopeOverLap = checkScopeOverLap(runtimeContext.getRequestContext(), inProgressTransactions);
240         logger.debug("Scope overlap " + scopeOverLap);
241         if (scopeOverLap) {
242             List<VNFOperation> inProgressActions = inProgressTransactions.stream().map(TransactionRecord::getOperation)
243                     .collect(Collectors.toList());
244
245             RuleExecutor ruleExecutor = requestValidationPolicy.getInProgressRuleExecutor();
246             RuleResult result = ruleExecutor.executeRule(operation.name(), inProgressActions);
247             logger.debug("Policy validation result " + result);
248             if (RuleResult.REJECT == result) {
249                 String message = "Request rejected as per the request validation policy";
250                 throw new RequestValidationException(message, LCMCommandStatus.POLICY_VALIDATION_FAILURE,
251                         (new Params()).addParam("errorMsg", message));
252             }
253         }
254     }
255
256     private void validateVNFLock(RuntimeContext runtimeContext) throws LockException {
257         String vnfId = runtimeContext.getRequestContext().getActionIdentifiers().getVnfId();
258         String lockOwner = lockManager.getLockOwner(vnfId);
259         logger.debug("Current lock owner is " + lockOwner + " for vnf " + vnfId);
260         if (lockOwner != null
261                 && !lockOwner.equals(runtimeContext.getRequestContext().getCommonHeader().getRequestId())) {
262             String message = new StringBuilder("VNF : ").append(vnfId).append(" is locked by request id :")
263                     .append(lockOwner).toString();
264             throw new LockException(message);
265         }
266     }
267
268     /*
269      * Do not remove this method, this is actual method for invoking scope
270      * overlap service When the service becomes available, its dummy
271      * implementation should be removed and this implementation should be used.
272      */
273     private Boolean checkScopeOverLap(RequestContext requestContext, List<TransactionRecord> inProgressTransactions)
274             throws APPCException {
275         Boolean scopeOverlap = null;
276         try {
277             JsonNode inputJSON = convertToJsonInput(requestContext, inProgressTransactions);
278             logger.debug("Input to scope overlap service " + inputJSON.toString());
279             HttpResponse response = client.doPost(path, inputJSON.toString());
280             int httpCode = response.getStatusLine().getStatusCode();
281             if (httpCode < 200 || httpCode >= 300) {
282                 logger.debug("http error code " + httpCode);
283                 throw new APPCException("Exception occurred on invoking check scope overlap api");
284             }
285             String respBody = IOUtils.toString(response.getEntity().getContent());
286             logger.debug("response body " + respBody);
287             ObjectMapper mapper = new ObjectMapper();
288             JsonNode outputJSON = mapper.readTree(respBody);
289             scopeOverlap = readScopeOverlap(outputJSON);
290         } catch (IOException e) {
291             String message = "Error accessing check scope overlap service";
292             logger.error(message, e);
293             throw new APPCException(message);
294         }
295         return scopeOverlap;
296     }
297
298     private Boolean readScopeOverlap(JsonNode outputJSON) throws APPCException {
299         logger.debug("Response JSON " + outputJSON.toString());
300         String message = "Error reading response JSON from scope overlap service ";
301         JsonNode outputNode = outputJSON.get("output");
302         JsonNode statusNode = outputNode.get("status");
303         if (statusNode == null) {
304             throw new APPCException(message);
305         }
306
307         if (null == statusNode.get("message"))
308             throw new APPCException(message + "Status message is null.");
309         String responseStatusMessage = statusNode.get("message").textValue();
310
311         if (null == statusNode.get("code"))
312             throw new APPCException(message + "Status code is null.");
313         String code = statusNode.get("code").textValue();
314
315         JsonNode responseInfoNode = outputNode.get("response-info");
316         JsonNode blockNode = responseInfoNode.get("block");
317         String requestOverlapValue = null;
318
319         if (null != blockNode)
320             requestOverlapValue = blockNode.textValue();
321
322         logger.debug("Response JSON " + requestOverlapValue);
323
324         if (code.equals("400")) {
325             if(null==requestOverlapValue)
326                 throw new APPCException("Response code is 400 but requestOverlapValue is null ");
327             if (requestOverlapValue.contains("true")) {
328                 return Boolean.TRUE;
329             } else if (requestOverlapValue.contains("false")) {
330                 return Boolean.FALSE;
331             } else {
332                 throw new APPCException(
333                         message + "requestOverlap value is other than True and False, it is " + requestOverlapValue);
334             }
335         } else if (code.equals("401")) {
336             throw new APPCException(message + responseStatusMessage);
337         } else {
338             throw new APPCException(message + "Status code is neither 400 nor 401, it is " + code);
339         }
340
341     }
342
343     private JsonNode convertToJsonInput(RequestContext requestContext, List<TransactionRecord> inProgressTransactions) {
344         ObjectMapper objectMapper = new ObjectMapper();
345         ScopeOverlapModel scopeOverlapModel = getScopeOverlapModel(requestContext, inProgressTransactions);
346         // Added for change in interface for action level
347
348         JsonNode jsonObject = objectMapper.valueToTree(scopeOverlapModel);
349
350         return jsonObject;
351     }
352
353     public ScopeOverlapModel getScopeOverlapModel(RequestContext requestContext,
354             List<TransactionRecord> inProgressTransactions) {
355         ScopeOverlapModel scopeOverlapModel = new ScopeOverlapModel();
356         RequestData requestData = new RequestData();
357
358         List<RequestModel> inProgressRequests = new ArrayList<>();
359         RequestModel requestModel = new RequestModel();
360         ActionIdentifierModel actionIdentifierModel = extractActionIdentifierModel(requestContext);
361         requestModel.setAction(requestContext.getAction().toString());
362         requestModel.setActionIdentifier(actionIdentifierModel);
363
364         if (requestModel.getActionIdentifier().getVnfId() != null) {
365             requestData.setVnfID(requestModel.getActionIdentifier().getVnfId());
366         }
367
368         if (requestModel.getActionIdentifier().getVnfcName() != null
369                 || requestModel.getActionIdentifier().getVfModuleId() != null
370                 || requestModel.getActionIdentifier().getVserverId() != null) {
371
372             requestModel.getActionIdentifier().setVnfId(null);
373         }
374
375         requestData.setCurrentRequest(requestModel);
376
377         for (TransactionRecord record : inProgressTransactions) {
378             RequestModel request = new RequestModel();
379             ActionIdentifierModel actionIdentifier = new ActionIdentifierModel();
380
381             actionIdentifier.setServiceInstanceId(record.getServiceInstanceId());
382             actionIdentifier.setVnfId(record.getTargetId());
383             actionIdentifier.setVnfcName(record.getVnfcName());
384             actionIdentifier.setVfModuleId(record.getVfModuleId());
385             actionIdentifier.setVserverId(record.getVserverId());
386
387             request.setAction(record.getOperation().name());
388             request.setActionIdentifier(actionIdentifier);
389             if (request.getActionIdentifier().getVnfcName() != null
390                         || request.getActionIdentifier().getVfModuleId() != null
391                         || request.getActionIdentifier().getVserverId() != null) {
392
393                     request.getActionIdentifier().setVnfId(null);
394             }
395             request.setTargetId(record.getTargetId());
396             inProgressRequests.add(request);
397         }
398
399         requestData.setInProgressRequests(inProgressRequests);
400
401         Request request = new Request();
402
403         Date date = new Date();
404         request.setRequestID("RequestId-ScopeOverlap " + date.toString());
405         request.setAction("isScopeOverlap");
406         ObjectMapper objectMapper = new ObjectMapper();
407         JsonNode json = objectMapper.valueToTree(requestData);
408         request.setRequestData(json.toString());
409         Input input = new Input();
410         input.setRequest(request);
411         scopeOverlapModel.setInput(input);
412
413         return scopeOverlapModel;
414     }
415
416     private ActionIdentifierModel extractActionIdentifierModel(RequestContext requestContext) {
417         ActionIdentifierModel actionIdentifierModel = new ActionIdentifierModel();
418         actionIdentifierModel.setServiceInstanceId(requestContext.getActionIdentifiers().getServiceInstanceId());
419         actionIdentifierModel.setVnfId(requestContext.getActionIdentifiers().getVnfId());
420         actionIdentifierModel.setVnfcName(requestContext.getActionIdentifiers().getVnfcName());
421         actionIdentifierModel.setVfModuleId(requestContext.getActionIdentifiers().getVfModuleId());
422         actionIdentifierModel.setVserverId(requestContext.getActionIdentifiers().getVserverId());
423         return actionIdentifierModel;
424     }
425
426     private VNFContext queryAAI(String vnfId) throws VNFNotFoundException, MissingVNFDataInAAIException {
427         SvcLogicContext ctx = new SvcLogicContext();
428         ctx = getVnfdata(vnfId, "vnf", ctx);
429
430         VNFContext vnfContext = new VNFContext();
431         populateVnfContext(vnfContext, ctx);
432
433         return vnfContext;
434     }
435
436     private SvcLogicContext getVnfdata(String vnf_id, String prefix, SvcLogicContext ctx) throws VNFNotFoundException {
437         if (logger.isTraceEnabled()) {
438             logger.trace("Entering to getVnfdata with vnfid = " + ObjectUtils.toString(vnf_id) + ", prefix = "
439                     + ObjectUtils.toString(prefix) + ", SvcLogicContext" + ObjectUtils.toString(ctx));
440         }
441         String key = "vnf-id = '" + vnf_id + "'";
442         logger.debug("inside getVnfdata=== " + key);
443         try {
444             Date beginTimestamp = new Date();
445             SvcLogicResource.QueryStatus response = aaiService.query("generic-vnf", false, null, key, prefix, null,
446                     ctx);
447             Date endTimestamp = new Date();
448             String status = SvcLogicResource.QueryStatus.SUCCESS.equals(response)
449                     ? LoggingConstants.StatusCodes.COMPLETE : LoggingConstants.StatusCodes.ERROR;
450             LoggingUtils.logMetricsMessage(beginTimestamp.toInstant(), endTimestamp.toInstant(),
451                     LoggingConstants.TargetNames.AAI, LoggingConstants.TargetServiceNames.AAIServiceNames.QUERY, status,
452                     "", response.name(), this.getClass().getCanonicalName());
453             if (SvcLogicResource.QueryStatus.NOT_FOUND.equals(response)) {
454                 throw new VNFNotFoundException("VNF not found for vnf_id = " + vnf_id, vnf_id);
455             } else if (SvcLogicResource.QueryStatus.FAILURE.equals(response)) {
456                 throw new RuntimeException("Error Querying AAI with vnfID = " + vnf_id);
457             }
458             logger.info("AAIResponse: " + response.toString());
459         } catch (SvcLogicException e) {
460
461             LoggingUtils.logErrorMessage(LoggingConstants.TargetServiceNames.AAIServiceNames.GET_VNF_DATA,
462                     "Error in getVnfdata" + e, this.getClass().getCanonicalName());
463
464             throw new RuntimeException(e);
465         }
466         if (logger.isTraceEnabled()) {
467             logger.trace("Exiting from getVnfdata with (SvcLogicContext = " + ObjectUtils.toString(ctx) + ")");
468         }
469         return ctx;
470     }
471
472     private void populateVnfContext(VNFContext vnfContext, SvcLogicContext ctx) throws MissingVNFDataInAAIException {
473         String vnfType = ctx.getAttribute("vnf.vnf-type");
474         if (StringUtils.isEmpty(vnfType)) {
475             throw new MissingVNFDataInAAIException("vnf-type", ctx.getAttribute("vnf.vnf-id"));
476         }
477         vnfContext.setType(vnfType);
478         vnfContext.setId(ctx.getAttribute("vnf.vnf-id"));
479     }
480
481     private void checkWorkflowExists(VNFContext vnfContext, RequestContext requestContext)
482             throws WorkflowNotFoundException, DGWorkflowNotFoundException {
483         WorkflowExistsOutput workflowExistsOutput = workflowManager
484                 .workflowExists(getWorkflowQueryParams(vnfContext, requestContext));
485         if (!workflowExistsOutput.isMappingExist()) {
486             if (logger.isDebugEnabled()) {
487                 logger.debug("WorkflowManager : Workflow mapping not found for vnfType = " + vnfContext.getType()
488                         + ", version = " + vnfContext.getVersion() + ", command = "
489                         + requestContext.getAction().name());
490             }
491             LoggingUtils.logErrorMessage(LoggingConstants.TargetNames.WORKFLOW_MANAGER, EELFResourceManager
492                     .format(Msg.APPC_WORKFLOW_NOT_FOUND, vnfContext.getType(), requestContext.getAction().name()),
493                     this.getClass().getCanonicalName());
494             throw new WorkflowNotFoundException(
495                     "Workflow mapping not found for vnfType = " + vnfContext.getType() + ", command = "
496                             + requestContext.getAction().name(),
497                     vnfContext.getType(), requestContext.getAction().name());
498         }
499         if (!workflowExistsOutput.isDgExist()) {
500             if (logger.isDebugEnabled()) {
501                 logger.debug("WorkflowManager : DG Workflow not found for vnfType = " + vnfContext.getType()
502                         + ", version = " + vnfContext.getVersion() + ", command = " + requestContext.getAction().name()
503                         + " " + workflowExistsOutput);
504             }
505             LoggingUtils.logErrorMessage(LoggingConstants.TargetNames.WORKFLOW_MANAGER, EELFResourceManager
506                     .format(Msg.APPC_WORKFLOW_NOT_FOUND, vnfContext.getType(), requestContext.getAction().name()),
507                     this.getClass().getCanonicalName());
508             throw new DGWorkflowNotFoundException(
509                     "Workflow not found for vnfType = " + vnfContext.getType() + ", command = "
510                             + requestContext.getAction().name(),
511                     workflowExistsOutput.getWorkflowModule(), workflowExistsOutput.getWorkflowName(),
512                     workflowExistsOutput.getWorkflowVersion(), vnfContext.getType(), requestContext.getAction().name());
513         }
514     }
515
516     private WorkflowRequest getWorkflowQueryParams(VNFContext vnfContext, RequestContext requestContext) {
517         WorkflowRequest workflowRequest = new WorkflowRequest();
518         workflowRequest.setVnfContext(vnfContext);
519         workflowRequest.setRequestContext(requestContext);
520         if (logger.isTraceEnabled()) {
521             logger.trace("Exiting from getWorkflowQueryParams with (WorkflowRequest = "
522                     + ObjectUtils.toString(workflowRequest) + ")");
523         }
524         return workflowRequest;
525     }
526
527     public String logInProgressTransactions(List<TransactionRecord> inProgressTransactions,
528             long inProgressTransactionsAllCount, long inProgressTransactionsRelevant) {
529             if (inProgressTransactionsAllCount > inProgressTransactionsRelevant) {
530                 logger.info("Found Stale Transactions! Ignoring Stale Transactions for target, only considering "
531                     + "transactions within the last " + transactionWindowInterval + " hours as transactions in-progress");
532             }
533             String logMsg="";
534             for (TransactionRecord tr: inProgressTransactions) {
535                 logMsg = ("In Progress transaction for Target ID - "+ tr.getTargetId()
536                         + " in state " + tr.getRequestState()
537                         + " with Start time " + tr.getStartTime().toString()
538                         + " for more than configurable time period " + transactionWindowInterval
539                         + " hours [transaction details - Request ID - " + tr.getTransactionId()
540                         + ", Service Instance Id -" + tr.getServiceInstanceId()
541                         + ", Vserver_id - " + tr.getVserverId()
542                         + ", VNFC_name - "+ tr.getVnfcName()
543                         + ", VF module Id - " + tr.getVfModuleId()
544                         + " Start time " + tr.getStartTime().toString()
545                         + "]" );
546             }
547             return logMsg;
548
549     }
550 }