2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 * ============LICENSE_END=========================================================
20 package org.onap.so.bpmn.infrastructure.scripts
22 import org.camunda.bpm.engine.delegate.BpmnError
23 import org.camunda.bpm.engine.delegate.DelegateExecution
24 import org.onap.appc.client.lcm.model.Action
25 import org.onap.appc.client.lcm.model.ActionIdentifiers
26 import org.onap.appc.client.lcm.model.Flags
27 import org.onap.appc.client.lcm.model.Status
28 import org.onap.so.bpmn.common.scripts.ExceptionUtil
29 import org.onap.so.bpmn.common.scripts.MsoUtils
30 import org.onap.so.bpmn.core.json.JsonUtils
31 import org.onap.so.client.aai.*
32 import org.onap.so.client.aai.entities.AAIResultWrapper
33 import org.onap.so.client.aai.entities.uri.AAIUri
34 import org.onap.so.client.aai.entities.uri.AAIUriFactory
35 import org.onap.so.client.appc.ApplicationControllerClient;
36 import org.onap.so.client.appc.ApplicationControllerSupport;
37 import org.onap.so.logger.MessageEnum
38 import org.onap.so.logger.MsoLogger
40 import groovy.json.JsonOutput
41 import groovy.json.JsonSlurper
43 public class VnfInPlaceUpdate extends VnfCmBase {
44 private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, VnfInPlaceUpdate.class);
46 ExceptionUtil exceptionUtil = new ExceptionUtil()
47 JsonUtils jsonUtils = new JsonUtils()
48 def prefix = "VnfIPU_"
51 * Initialize the flow's variables.
53 * @param execution The flow's execution instance.
55 public void initProcessVariables(DelegateExecution execution) {
56 execution.setVariable('prefix', 'VnfIPU_')
57 execution.setVariable('Request', null)
58 execution.setVariable('requestInfo', null)
59 execution.setVariable('source', null)
60 execution.setVariable('vnfInputs', null)
61 execution.setVariable('tenantId', null)
62 execution.setVariable('vnfParams', null)
63 execution.setVariable('controllerType', null)
64 execution.setVariable('UpdateVnfSuccessIndicator', false)
65 execution.setVariable('serviceType', null)
66 execution.setVariable('nfRole', null)
67 execution.setVariable('currentActivity', 'VnfIPU')
68 execution.setVariable('workStep', null)
69 execution.setVariable('failedActivity', null)
70 execution.setVariable('errorCode', "0")
71 execution.setVariable('errorText', null)
72 execution.setVariable('healthCheckIndex0', 0)
73 execution.setVariable('healthCheckIndex1', 1)
74 execution.setVariable('maxRetryCount', 3)
75 execution.setVariable("rollbackSetClosedLoopDisabledFlag", false)
76 execution.setVariable("rollbackVnfStop", false)
77 execution.setVariable("rollbackVnfLock", false)
78 execution.setVariable("rollbackQuiesceTraffic", false)
79 execution.setVariable("rollbackSetVnfInMaintenanceFlag", false)
83 * Check for missing elements in the received request.
85 * @param execution The flow's execution instance.
87 public void preProcessRequest(DelegateExecution execution) {
88 def method = getClass().getSimpleName() + '.preProcessRequest(' +
89 'execution=' + execution.getId() +
91 initProcessVariables(execution)
93 msoLogger.trace('Entered ' + method)
95 initProcessVariables(execution)
97 def incomingRequest = execution.getVariable('bpmnRequest')
99 msoLogger.debug("Incoming Infra Request: " + incomingRequest)
101 def jsonSlurper = new JsonSlurper()
102 def jsonOutput = new JsonOutput()
103 Map reqMap = jsonSlurper.parseText(incomingRequest)
104 msoLogger.debug(" Request is in JSON format.")
106 def serviceInstanceId = execution.getVariable('serviceInstanceId')
107 def vnfId = execution.getVariable('vnfId')
109 execution.setVariable('serviceInstanceId', serviceInstanceId)
110 execution.setVariable('vnfId', vnfId)
111 execution.setVariable("isVidRequest", "true")
112 execution.setVariable('serviceType', 'Mobility')
113 execution.setVariable('payload', "")
114 execution.setVariable('actionSnapshot', Action.Snapshot)
115 execution.setVariable('actionLock', Action.Lock)
116 execution.setVariable('actionUnlock', Action.Unlock)
117 execution.setVariable('actionUpgradePreCheck', Action.UpgradePreCheck)
118 execution.setVariable('actionUpgradePostCheck', Action.UpgradePostCheck)
119 execution.setVariable('actionQuiesceTraffic', Action.QuiesceTraffic)
120 execution.setVariable('actionUpgradeBackup', Action.UpgradeBackup)
121 execution.setVariable('actionUpgradeSoftware', Action.UpgradeSoftware)
122 execution.setVariable('actionResumeTraffic', Action.ResumeTraffic)
125 def controllerType = reqMap.requestDetails?.requestParameters?.controllerType
126 execution.setVariable('controllerType', controllerType)
128 msoLogger.debug('Controller Type: ' + controllerType)
130 def payload = reqMap.requestDetails?.requestParameters?.payload
131 execution.setVariable('payload', payload)
133 msoLogger.debug('Processed payload: ' + payload)
136 def requestId = execution.getVariable("mso-request-id")
137 execution.setVariable('requestId', requestId)
138 execution.setVariable('msoRequestId', requestId)
140 def requestorId = reqMap.requestDetails?.requestInfo?.requestorId ?: null
141 execution.setVariable('requestorId', requestorId)
143 def cloudConfiguration = reqMap.requestDetails?.cloudConfiguration
144 def lcpCloudRegionId = cloudConfiguration.lcpCloudRegionId
145 execution.setVariable('lcpCloudRegionId', lcpCloudRegionId)
146 def cloudOwner = cloudConfiguration.cloudOwner
147 execution.setVariable('cloudOwner', cloudOwner)
148 def tenantId = cloudConfiguration.tenantId
149 execution.setVariable('tenantId', tenantId)
151 execution.setVariable("UpdateVnfInfraSuccessIndicator", false)
155 def source = reqMap.requestDetails?.requestInfo?.source
156 execution.setVariable("source", source)
158 //For Completion Handler & Fallout Handler
160 """<request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
161 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
162 <action>UPDATE</action>
163 <source>${MsoUtils.xmlEscape(source)}</source>
166 execution.setVariable("requestInfo", requestInfo)
168 msoLogger.debug('RequestInfo: ' + execution.getVariable("requestInfo"))
170 msoLogger.trace('Exited ' + method)
173 catch(groovy.json.JsonException je) {
174 msoLogger.debug(" Request is not in JSON format.")
175 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, "Invalid request format")
178 String restFaultMessage = e.getMessage()
179 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, " Exception Encountered - " + "\n" + restFaultMessage, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
180 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, restFaultMessage)
185 * Prepare and send the sychronous response for this flow.
187 * @param execution The flow's execution instance.
189 public void sendSynchResponse(DelegateExecution execution) {
190 def method = getClass().getSimpleName() + '.sendSynchResponse(' +
191 'execution=' + execution.getId() +
194 msoLogger.trace('Entered ' + method)
198 def requestInfo = execution.getVariable('requestInfo')
199 def requestId = execution.getVariable('requestId')
200 def source = execution.getVariable('source')
201 def progress = getNodeTextForce(requestInfo, 'progress')
202 if (progress.isEmpty()) {
205 def startTime = getNodeTextForce(requestInfo, 'start-time')
206 if (startTime.isEmpty()) {
207 startTime = System.currentTimeMillis()
210 // RESTResponse (for API Handler (APIH) Reply Task)
211 def vnfId = execution.getVariable("vnfId")
212 String synchResponse = """{"requestReferences":{"instanceId":"${vnfId}","requestId":"${requestId}"}}""".trim()
214 sendWorkflowResponse(execution, 200, synchResponse)
216 msoLogger.trace('Exited ' + method)
217 } catch (BpmnError e) {
219 } catch (Exception e) {
220 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
221 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in sendResponse(): ' + e.getMessage())
227 * Check if this VNF is already in maintenance in A&AI.
230 * @param execution The flow's execution instance.
232 public void checkIfVnfInMaintInAAI(DelegateExecution execution) {
233 def method = getClass().getSimpleName() + '.checkIfVnfInMaintInAAI(' +
234 'execution=' + execution.getId() +
237 execution.setVariable('errorCode', "0")
238 execution.setVariable("workStep", "checkIfVnfInMaintInAAI")
239 execution.setVariable("failedActivity", "AAI")
240 msoLogger.trace('Entered ' + method)
243 def transactionLoggingUuid = UUID.randomUUID().toString()
244 AAIRestClientImpl client = new AAIRestClientImpl()
245 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
246 aaiValidator.setClient(client)
247 def vnfId = execution.getVariable("vnfId")
248 boolean isInMaint = aaiValidator.isVNFLocked(vnfId, transactionLoggingUuid)
249 msoLogger.debug("isInMaint result: " + isInMaint)
250 execution.setVariable('isVnfInMaintenance', isInMaint)
253 execution.setVariable("errorCode", "1003")
254 execution.setVariable("errorText", "VNF is in maintenance in A&AI")
258 msoLogger.trace('Exited ' + method)
259 } catch (BpmnError e) {
261 } catch (Exception e) {
262 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
263 execution.setVariable("errorCode", "1002")
264 execution.setVariable("errorText", e.getMessage())
265 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfVnfInMaintInAAI(): ' + e.getMessage())
271 * Check if this VNF's pservers are locked in A&AI.
274 * @param execution The flow's execution instance.
276 public void checkIfPserversInMaintInAAI(DelegateExecution execution) {
277 def method = getClass().getSimpleName() + '.checkIfPserversInMaintInAAI(' +
278 'execution=' + execution.getId() +
281 execution.setVariable('errorCode', "0")
282 msoLogger.trace('Entered ' + method)
283 execution.setVariable("workStep", "checkIfPserversInMaintInAAI")
284 execution.setVariable("failedActivity", "AAI")
287 def transactionLoggingUuid = UUID.randomUUID().toString()
288 AAIRestClientImpl client = new AAIRestClientImpl()
289 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
290 aaiValidator.setClient(client)
291 def vnfId = execution.getVariable("vnfId")
292 boolean areLocked = aaiValidator.isPhysicalServerLocked(vnfId, transactionLoggingUuid)
293 msoLogger.debug("areLocked result: " + areLocked)
294 execution.setVariable('arePserversLocked', areLocked)
297 execution.setVariable("errorCode", "1003")
298 execution.setVariable("errorText", "pServers are locked in A&AI")
301 msoLogger.trace('Exited ' + method)
302 } catch (BpmnError e) {
304 } catch (Exception e) {
305 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
306 execution.setVariable("errorCode", "1002")
307 execution.setVariable("errorText", e.getMessage())
308 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfPserversInMaintInAAI(): ' + e.getMessage())
313 * Set inMaint flag for this VNF to the specified value in A&AI.
316 * @param execution The flow's execution instance.
317 * @param inMaint The boolean value of the flag to set
319 public void setVnfInMaintFlagInAAI(DelegateExecution execution, boolean inMaint) {
320 def method = getClass().getSimpleName() + '.setVnfInMaintFlagInAAI(' +
321 'execution=' + execution.getId() +
324 execution.setVariable('errorCode', "0")
325 msoLogger.trace('Entered ' + method)
327 execution.setVariable("workStep", "setVnfInMaintFlagInAAI")
330 execution.setVariable("workStep", "unsetVnfInMaintFlagInAAI")
332 execution.setVariable("failedActivity", "AAI")
335 def transactionLoggingUuid = UUID.randomUUID().toString()
336 AAIRestClientImpl client = new AAIRestClientImpl()
337 AAIUpdatorImpl aaiUpdator = new AAIUpdatorImpl()
338 aaiUpdator.setClient(client)
339 def vnfId = execution.getVariable("vnfId")
341 aaiUpdator.updateVnfToLocked(vnfId, transactionLoggingUuid)
342 execution.setVariable("rollbackSetVnfInMaintenanceFlag", true)
345 aaiUpdator.updateVnfToUnLocked(vnfId, transactionLoggingUuid)
348 msoLogger.trace('Exited ' + method)
349 } catch (BpmnError e) {
351 } catch (Exception e) {
352 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
353 execution.setVariable("errorCode", "1002")
354 execution.setVariable("errorText", e.getMessage())
355 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in setVnfInMaintFlagInAAI(): ' + e.getMessage())
360 * Check if VF Closed Loop Disabled in A&AI.
363 * @param execution The flow's execution instance.
365 public void checkIfClosedLoopDisabledInAAI(DelegateExecution execution) {
366 def method = getClass().getSimpleName() + '.checkIfClosedLoopDisabledInAAI(' +
367 'execution=' + execution.getId() +
370 execution.setVariable('errorCode', "0")
371 execution.setVariable("workStep", "checkClosedLoopDisabledFlagInAAI")
372 execution.setVariable("failedActivity", "AAI")
373 msoLogger.trace('Entered ' + method)
376 def transactionLoggingUuid = UUID.randomUUID().toString()
377 def vnfId = execution.getVariable("vnfId")
378 msoLogger.debug("vnfId is: " + vnfId)
379 AAIResourcesClient client = new AAIResourcesClient()
380 AAIUri genericVnfUri = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId)
381 AAIResultWrapper aaiRW = client.get(genericVnfUri)
382 Map<String, Object> result = aaiRW.asMap()
383 boolean isClosedLoopDisabled = result.getOrDefault("is-closed-loop-disabled", false)
385 msoLogger.debug("isClosedLoopDisabled result: " + isClosedLoopDisabled)
386 execution.setVariable('isClosedLoopDisabled', isClosedLoopDisabled)
388 if (isClosedLoopDisabled) {
389 execution.setVariable("errorCode", "1004")
390 execution.setVariable("errorText", "closedLoop is disabled in A&AI")
393 msoLogger.trace('Exited ' + method)
394 } catch (BpmnError e) {
396 } catch (Exception e) {
397 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
398 execution.setVariable("errorCode", "1002")
399 execution.setVariable("errorText", e.getMessage())
404 * Set VF Closed Loop Disabled Flag in A&AI.
407 * @param execution The flow's execution instance.
409 public void setClosedLoopDisabledInAAI(DelegateExecution execution, boolean setDisabled) {
410 def method = getClass().getSimpleName() + '.setClosedLoopDisabledInAAI(' +
411 'execution=' + execution.getId() +
414 execution.setVariable('errorCode', "0")
416 execution.setVariable("workStep", "setClosedLoopDisabledFlagInAAI")
417 execution.setVariable("rollbackSetClosedLoopDisabledFlag", true)
420 execution.setVariable("workStep", "unsetClosedLoopDisabledFlagInAAI")
423 execution.setVariable("failedActivity", "AAI")
424 msoLogger.trace('Entered ' + method)
427 def transactionLoggingUuid = UUID.randomUUID().toString()
428 def vnfId = execution.getVariable("vnfId")
429 AAIResourcesClient client = new AAIResourcesClient()
430 AAIUri genericVnfUri = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId)
432 Map<String, Boolean> request = new HashMap<>()
433 request.put("is-closed-loop-disabled", setDisabled)
434 client.update(genericVnfUri, request)
435 msoLogger.debug("set isClosedLoop to: " + setDisabled)
437 msoLogger.trace('Exited ' + method)
438 } catch (BpmnError e) {
440 } catch (Exception e) {
441 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
442 execution.setVariable("errorCode", "1002")
443 execution.setVariable("errorText", e.getMessage())
451 * Call APP-C client to execute specified APP-C command for this VNF.
454 * @param execution The flow's execution instance.
455 * @param action The action to take in APP-C.
457 public void runAppcCommand(DelegateExecution execution, Action action) {
458 def method = getClass().getSimpleName() + '.runAppcCommand(' +
459 'execution=' + execution.getId() +
462 execution.setVariable('errorCode', "0")
463 msoLogger.trace('Entered ' + method)
465 ApplicationControllerClient appcClient = null
468 msoLogger.debug("Running APP-C action: " + action.toString())
469 String vnfId = execution.getVariable('vnfId')
470 String msoRequestId = execution.getVariable('requestId')
471 execution.setVariable('msoRequestId', msoRequestId)
472 execution.setVariable("failedActivity", "APP-C")
474 appcClient = new ApplicationControllerClient()
475 ApplicationControllerSupport support = new ApplicationControllerSupport()
476 appcClient.appCSupport=support
477 org.springframework.test.util.ReflectionTestUtils.setField(support, "lcmModelPackage", "org.onap.appc.client.lcm.model");
478 Flags flags = new Flags();
479 ActionIdentifiers actionIdentifiers = new ActionIdentifiers();
480 actionIdentifiers.setVnfId(vnfId);
484 execution.setVariable('workStep', "LockVNF")
485 appcStatus = appcClient.runCommand(Action.Lock,actionIdentifiers,null,msoRequestId)
488 execution.setVariable('workStep', "UnlockVNF")
489 appcStatus = appcClient.runCommand(Action.Unlock,actionIdentifiers,null,msoRequestId)
491 case Action.HealthCheck:
492 def healthCheckIndex = execution.getVariable('healthCheckIndex')
493 execution.setVariable('workStep', "HealthCheckVNF" + healthCheckIndex)
494 execution.setVariable('healthCheckIndex', healthCheckIndex + 1)
495 appcStatus = appcClient.runCommand(Action.HealthCheck,actionIdentifiers,null,msoRequestId)
498 execution.setVariable('workStep', "StartVNF")
499 appcStatus = appcClient.runCommand(Action.Start,actionIdentifiers,null,msoRequestId)
502 execution.setVariable('workStep', "StopVNF")
503 appcStatus = appcClient.runCommand(Action.Stop,actionIdentifiers,null,msoRequestId)
508 msoLogger.debug("Completed AppC request")
509 int appcCode = appcStatus.getCode()
510 msoLogger.debug("AppC status code is: " + appcCode)
511 msoLogger.debug("AppC status message is: " + appcStatus.getMessage())
512 if (support.getCategoryOf(appcStatus) == ApplicationControllerSupport.StatusCategory.ERROR) {
513 execution.setVariable("errorCode", Integer.toString(appcCode))
514 execution.setVariable("errorText", appcStatus.getMessage())
517 msoLogger.trace('Exited ' + method)
518 } catch (BpmnError e) {
519 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
520 execution.setVariable("errorCode", "1002")
521 execution.setVariable("errorText", e.getMessage())
522 } catch (java.lang.NoSuchMethodError e) {
523 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
524 execution.setVariable("errorCode", "1002")
525 execution.setVariable("errorText", e.getMessage())
526 } catch (Exception e) {
527 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
528 execution.setVariable("errorCode", "1002")
529 execution.setVariable("errorText", e.getMessage())
534 * Placeholder for a call to APP-C client to execute specified APP-C command for this VNF.
537 * @param execution The flow's execution instance.
538 * @param action The action to take in APP-C.
540 public void runAppcCommandPlaceholder(DelegateExecution execution, String action) {
541 def method = getClass().getSimpleName() + '.runAppcCommandPlaceholder(' +
542 'execution=' + execution.getId() +
545 execution.setVariable('errorCode', "0")
546 msoLogger.trace('Entered ' + method)
547 execution.setVariable("failedActivity", "APP-C")
548 execution.setVariable("workStep", action)
554 * Handle Abort disposition from RainyDayHandler
556 * @param execution The flow's execution instance.
558 public void abortProcessing(DelegateExecution execution) {
559 def method = getClass().getSimpleName() + '.abortProcessing(' +
560 'execution=' + execution.getId() +
563 msoLogger.trace('Entered ' + method)
565 def errorText = execution.getVariable("errorText")
566 def errorCode = execution.getVariable("errorCode")
568 exceptionUtil.buildAndThrowWorkflowException(execution, errorCode as Integer, errorText)
572 * Increment Retry Count for Current Work Step
574 * @param execution The flow's execution instance.
576 public void incrementRetryCount(DelegateExecution execution) {
577 def method = getClass().getSimpleName() + '.incrementRetryCount(' +
578 'execution=' + execution.getId() +
581 msoLogger.trace('Entered ' + method)
583 String retryCountVariableName = execution.getVariable("workStep") + "RetryCount"
584 execution.setVariable("retryCountVariableName", retryCountVariableName)
586 def retryCountVariable = execution.getVariable(retryCountVariableName)
589 if (retryCountVariable != null) {
590 retryCount = (int) retryCountVariable
595 execution.setVariable(retryCountVariableName, retryCount)
597 msoLogger.debug("value of " + retryCountVariableName + " is " + retryCount)
598 msoLogger.trace('Exited ' + method)