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