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