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 tenantId = cloudConfiguration.tenantId
147 execution.setVariable('tenantId', tenantId)
149 execution.setVariable("UpdateVnfInfraSuccessIndicator", false)
153 def source = reqMap.requestDetails?.requestInfo?.source
154 execution.setVariable("source", source)
156 //For Completion Handler & Fallout Handler
158 """<request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
159 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
160 <action>UPDATE</action>
161 <source>${MsoUtils.xmlEscape(source)}</source>
164 execution.setVariable("requestInfo", requestInfo)
166 msoLogger.debug('RequestInfo: ' + execution.getVariable("requestInfo"))
168 msoLogger.trace('Exited ' + method)
171 catch(groovy.json.JsonException je) {
172 msoLogger.debug(" Request is not in JSON format.")
173 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, "Invalid request format")
176 String restFaultMessage = e.getMessage()
177 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, " Exception Encountered - " + "\n" + restFaultMessage, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
178 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, restFaultMessage)
183 * Prepare and send the sychronous response for this flow.
185 * @param execution The flow's execution instance.
187 public void sendSynchResponse(DelegateExecution execution) {
188 def method = getClass().getSimpleName() + '.sendSynchResponse(' +
189 'execution=' + execution.getId() +
192 msoLogger.trace('Entered ' + method)
196 def requestInfo = execution.getVariable('requestInfo')
197 def requestId = execution.getVariable('requestId')
198 def source = execution.getVariable('source')
199 def progress = getNodeTextForce(requestInfo, 'progress')
200 if (progress.isEmpty()) {
203 def startTime = getNodeTextForce(requestInfo, 'start-time')
204 if (startTime.isEmpty()) {
205 startTime = System.currentTimeMillis()
208 // RESTResponse (for API Handler (APIH) Reply Task)
209 def vnfId = execution.getVariable("vnfId")
210 String synchResponse = """{"requestReferences":{"instanceId":"${vnfId}","requestId":"${requestId}"}}""".trim()
212 sendWorkflowResponse(execution, 200, synchResponse)
214 msoLogger.trace('Exited ' + method)
215 } catch (BpmnError e) {
217 } catch (Exception e) {
218 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
219 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in sendResponse(): ' + e.getMessage())
225 * Check if this VNF is already in maintenance in A&AI.
228 * @param execution The flow's execution instance.
230 public void checkIfVnfInMaintInAAI(DelegateExecution execution) {
231 def method = getClass().getSimpleName() + '.checkIfVnfInMaintInAAI(' +
232 'execution=' + execution.getId() +
235 execution.setVariable('errorCode', "0")
236 execution.setVariable("workStep", "checkIfVnfInMaintInAAI")
237 execution.setVariable("failedActivity", "AAI")
238 msoLogger.trace('Entered ' + method)
241 def transactionLoggingUuid = UUID.randomUUID().toString()
242 AAIRestClientImpl client = new AAIRestClientImpl()
243 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
244 aaiValidator.setClient(client)
245 def vnfId = execution.getVariable("vnfId")
246 boolean isInMaint = aaiValidator.isVNFLocked(vnfId, transactionLoggingUuid)
247 msoLogger.debug("isInMaint result: " + isInMaint)
248 execution.setVariable('isVnfInMaintenance', isInMaint)
251 execution.setVariable("errorCode", "1003")
252 execution.setVariable("errorText", "VNF is in maintenance in A&AI")
256 msoLogger.trace('Exited ' + method)
257 } catch (BpmnError e) {
259 } catch (Exception e) {
260 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
261 execution.setVariable("errorCode", "1002")
262 execution.setVariable("errorText", e.getMessage())
263 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfVnfInMaintInAAI(): ' + e.getMessage())
269 * Check if this VNF's pservers are locked in A&AI.
272 * @param execution The flow's execution instance.
274 public void checkIfPserversInMaintInAAI(DelegateExecution execution) {
275 def method = getClass().getSimpleName() + '.checkIfPserversInMaintInAAI(' +
276 'execution=' + execution.getId() +
279 execution.setVariable('errorCode', "0")
280 msoLogger.trace('Entered ' + method)
281 execution.setVariable("workStep", "checkIfPserversInMaintInAAI")
282 execution.setVariable("failedActivity", "AAI")
285 def transactionLoggingUuid = UUID.randomUUID().toString()
286 AAIRestClientImpl client = new AAIRestClientImpl()
287 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
288 aaiValidator.setClient(client)
289 def vnfId = execution.getVariable("vnfId")
290 boolean areLocked = aaiValidator.isPhysicalServerLocked(vnfId, transactionLoggingUuid)
291 msoLogger.debug("areLocked result: " + areLocked)
292 execution.setVariable('arePserversLocked', areLocked)
295 execution.setVariable("errorCode", "1003")
296 execution.setVariable("errorText", "pServers are locked in A&AI")
299 msoLogger.trace('Exited ' + method)
300 } catch (BpmnError e) {
302 } catch (Exception e) {
303 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
304 execution.setVariable("errorCode", "1002")
305 execution.setVariable("errorText", e.getMessage())
306 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfPserversInMaintInAAI(): ' + e.getMessage())
311 * Set inMaint flag for this VNF to the specified value in A&AI.
314 * @param execution The flow's execution instance.
315 * @param inMaint The boolean value of the flag to set
317 public void setVnfInMaintFlagInAAI(DelegateExecution execution, boolean inMaint) {
318 def method = getClass().getSimpleName() + '.setVnfInMaintFlagInAAI(' +
319 'execution=' + execution.getId() +
322 execution.setVariable('errorCode', "0")
323 msoLogger.trace('Entered ' + method)
325 execution.setVariable("workStep", "setVnfInMaintFlagInAAI")
328 execution.setVariable("workStep", "unsetVnfInMaintFlagInAAI")
330 execution.setVariable("failedActivity", "AAI")
333 def transactionLoggingUuid = UUID.randomUUID().toString()
334 AAIRestClientImpl client = new AAIRestClientImpl()
335 AAIUpdatorImpl aaiUpdator = new AAIUpdatorImpl()
336 aaiUpdator.setClient(client)
337 def vnfId = execution.getVariable("vnfId")
339 aaiUpdator.updateVnfToLocked(vnfId, transactionLoggingUuid)
340 execution.setVariable("rollbackSetVnfInMaintenanceFlag", true)
343 aaiUpdator.updateVnfToUnLocked(vnfId, transactionLoggingUuid)
346 msoLogger.trace('Exited ' + method)
347 } catch (BpmnError e) {
349 } catch (Exception e) {
350 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
351 execution.setVariable("errorCode", "1002")
352 execution.setVariable("errorText", e.getMessage())
353 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in setVnfInMaintFlagInAAI(): ' + e.getMessage())
358 * Check if VF Closed Loop Disabled in A&AI.
361 * @param execution The flow's execution instance.
363 public void checkIfClosedLoopDisabledInAAI(DelegateExecution execution) {
364 def method = getClass().getSimpleName() + '.checkIfClosedLoopDisabledInAAI(' +
365 'execution=' + execution.getId() +
368 execution.setVariable('errorCode', "0")
369 execution.setVariable("workStep", "checkClosedLoopDisabledFlagInAAI")
370 execution.setVariable("failedActivity", "AAI")
371 msoLogger.trace('Entered ' + method)
374 def transactionLoggingUuid = UUID.randomUUID().toString()
375 def vnfId = execution.getVariable("vnfId")
376 msoLogger.debug("vnfId is: " + vnfId)
377 AAIResourcesClient client = new AAIResourcesClient()
378 AAIUri genericVnfUri = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId)
379 AAIResultWrapper aaiRW = client.get(genericVnfUri)
380 Map<String, Object> result = aaiRW.asMap()
381 boolean isClosedLoopDisabled = result.getOrDefault("is-closed-loop-disabled", false)
383 msoLogger.debug("isClosedLoopDisabled result: " + isClosedLoopDisabled)
384 execution.setVariable('isClosedLoopDisabled', isClosedLoopDisabled)
386 if (isClosedLoopDisabled) {
387 execution.setVariable("errorCode", "1004")
388 execution.setVariable("errorText", "closedLoop is disabled in A&AI")
391 msoLogger.trace('Exited ' + method)
392 } catch (BpmnError e) {
394 } catch (Exception e) {
395 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
396 execution.setVariable("errorCode", "1002")
397 execution.setVariable("errorText", e.getMessage())
402 * Set VF Closed Loop Disabled Flag in A&AI.
405 * @param execution The flow's execution instance.
407 public void setClosedLoopDisabledInAAI(DelegateExecution execution, boolean setDisabled) {
408 def method = getClass().getSimpleName() + '.setClosedLoopDisabledInAAI(' +
409 'execution=' + execution.getId() +
412 execution.setVariable('errorCode', "0")
414 execution.setVariable("workStep", "setClosedLoopDisabledFlagInAAI")
415 execution.setVariable("rollbackSetClosedLoopDisabledFlag", true)
418 execution.setVariable("workStep", "unsetClosedLoopDisabledFlagInAAI")
421 execution.setVariable("failedActivity", "AAI")
422 msoLogger.trace('Entered ' + method)
425 def transactionLoggingUuid = UUID.randomUUID().toString()
426 def vnfId = execution.getVariable("vnfId")
427 AAIResourcesClient client = new AAIResourcesClient()
428 AAIUri genericVnfUri = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId)
430 Map<String, Boolean> request = new HashMap<>()
431 request.put("is-closed-loop-disabled", setDisabled)
432 client.update(genericVnfUri, request)
433 msoLogger.debug("set isClosedLoop to: " + setDisabled)
435 msoLogger.trace('Exited ' + method)
436 } catch (BpmnError e) {
438 } catch (Exception e) {
439 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
440 execution.setVariable("errorCode", "1002")
441 execution.setVariable("errorText", e.getMessage())
449 * Call APP-C client to execute specified APP-C command for this VNF.
452 * @param execution The flow's execution instance.
453 * @param action The action to take in APP-C.
455 public void runAppcCommand(DelegateExecution execution, Action action) {
456 def method = getClass().getSimpleName() + '.runAppcCommand(' +
457 'execution=' + execution.getId() +
460 execution.setVariable('errorCode', "0")
461 msoLogger.trace('Entered ' + method)
463 ApplicationControllerClient appcClient = null
466 msoLogger.debug("Running APP-C action: " + action.toString())
467 String vnfId = execution.getVariable('vnfId')
468 String msoRequestId = execution.getVariable('requestId')
469 execution.setVariable('msoRequestId', msoRequestId)
470 execution.setVariable("failedActivity", "APP-C")
472 appcClient = new ApplicationControllerClient()
473 ApplicationControllerSupport support = new ApplicationControllerSupport()
474 appcClient.appCSupport=support
475 org.springframework.test.util.ReflectionTestUtils.setField(support, "lcmModelPackage", "org.onap.appc.client.lcm.model");
476 Flags flags = new Flags();
477 ActionIdentifiers actionIdentifiers = new ActionIdentifiers();
478 actionIdentifiers.setVnfId(vnfId);
482 execution.setVariable('workStep', "LockVNF")
483 appcStatus = appcClient.runCommand(Action.Lock,actionIdentifiers,null,msoRequestId)
486 execution.setVariable('workStep', "UnlockVNF")
487 appcStatus = appcClient.runCommand(Action.Unlock,actionIdentifiers,null,msoRequestId)
489 case Action.HealthCheck:
490 def healthCheckIndex = execution.getVariable('healthCheckIndex')
491 execution.setVariable('workStep', "HealthCheckVNF" + healthCheckIndex)
492 execution.setVariable('healthCheckIndex', healthCheckIndex + 1)
493 appcStatus = appcClient.runCommand(Action.HealthCheck,actionIdentifiers,null,msoRequestId)
496 execution.setVariable('workStep', "StartVNF")
497 appcStatus = appcClient.runCommand(Action.Start,actionIdentifiers,null,msoRequestId)
500 execution.setVariable('workStep', "StopVNF")
501 appcStatus = appcClient.runCommand(Action.Stop,actionIdentifiers,null,msoRequestId)
506 msoLogger.debug("Completed AppC request")
507 int appcCode = appcStatus.getCode()
508 msoLogger.debug("AppC status code is: " + appcCode)
509 msoLogger.debug("AppC status message is: " + appcStatus.getMessage())
510 if (support.getCategoryOf(appcStatus) == ApplicationControllerSupport.StatusCategory.ERROR) {
511 execution.setVariable("errorCode", Integer.toString(appcCode))
512 execution.setVariable("errorText", appcStatus.getMessage())
515 msoLogger.trace('Exited ' + method)
516 } catch (BpmnError e) {
517 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
518 execution.setVariable("errorCode", "1002")
519 execution.setVariable("errorText", e.getMessage())
520 } catch (java.lang.NoSuchMethodError e) {
521 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
522 execution.setVariable("errorCode", "1002")
523 execution.setVariable("errorText", e.getMessage())
524 } catch (Exception e) {
525 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
526 execution.setVariable("errorCode", "1002")
527 execution.setVariable("errorText", e.getMessage())
532 * Placeholder for a call to APP-C client to execute specified APP-C command for this VNF.
535 * @param execution The flow's execution instance.
536 * @param action The action to take in APP-C.
538 public void runAppcCommandPlaceholder(DelegateExecution execution, String action) {
539 def method = getClass().getSimpleName() + '.runAppcCommandPlaceholder(' +
540 'execution=' + execution.getId() +
543 execution.setVariable('errorCode', "0")
544 msoLogger.trace('Entered ' + method)
545 execution.setVariable("failedActivity", "APP-C")
546 execution.setVariable("workStep", action)
552 * Handle Abort disposition from RainyDayHandler
554 * @param execution The flow's execution instance.
556 public void abortProcessing(DelegateExecution execution) {
557 def method = getClass().getSimpleName() + '.abortProcessing(' +
558 'execution=' + execution.getId() +
561 msoLogger.trace('Entered ' + method)
563 def errorText = execution.getVariable("errorText")
564 def errorCode = execution.getVariable("errorCode")
566 exceptionUtil.buildAndThrowWorkflowException(execution, errorCode as Integer, errorText)
570 * Increment Retry Count for Current Work Step
572 * @param execution The flow's execution instance.
574 public void incrementRetryCount(DelegateExecution execution) {
575 def method = getClass().getSimpleName() + '.incrementRetryCount(' +
576 'execution=' + execution.getId() +
579 msoLogger.trace('Entered ' + method)
581 String retryCountVariableName = execution.getVariable("workStep") + "RetryCount"
582 execution.setVariable("retryCountVariableName", retryCountVariableName)
584 def retryCountVariable = execution.getVariable(retryCountVariableName)
587 if (retryCountVariable != null) {
588 retryCount = (int) retryCountVariable
593 execution.setVariable(retryCountVariableName, retryCount)
595 msoLogger.debug("value of " + retryCountVariableName + " is " + retryCount)
596 msoLogger.trace('Exited ' + method)