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 AAIRestClientImpl client = new AAIRestClientImpl()
244 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
245 aaiValidator.setClient(client)
246 def vnfId = execution.getVariable("vnfId")
247 boolean isInMaint = aaiValidator.isVNFLocked(vnfId)
248 msoLogger.debug("isInMaint result: " + isInMaint)
249 execution.setVariable('isVnfInMaintenance', isInMaint)
252 execution.setVariable("errorCode", "1003")
253 execution.setVariable("errorText", "VNF is in maintenance in A&AI")
257 msoLogger.trace('Exited ' + method)
258 } catch (BpmnError e) {
260 } catch (Exception e) {
261 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
262 execution.setVariable("errorCode", "1002")
263 execution.setVariable("errorText", e.getMessage())
264 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfVnfInMaintInAAI(): ' + e.getMessage())
270 * Check if this VNF's pservers are locked in A&AI.
273 * @param execution The flow's execution instance.
275 public void checkIfPserversInMaintInAAI(DelegateExecution execution) {
276 def method = getClass().getSimpleName() + '.checkIfPserversInMaintInAAI(' +
277 'execution=' + execution.getId() +
280 execution.setVariable('errorCode', "0")
281 msoLogger.trace('Entered ' + method)
282 execution.setVariable("workStep", "checkIfPserversInMaintInAAI")
283 execution.setVariable("failedActivity", "AAI")
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)
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 AAIRestClientImpl client = new AAIRestClientImpl()
334 AAIUpdatorImpl aaiUpdator = new AAIUpdatorImpl()
335 aaiUpdator.setClient(client)
336 def vnfId = execution.getVariable("vnfId")
338 aaiUpdator.updateVnfToLocked(vnfId)
339 execution.setVariable("rollbackSetVnfInMaintenanceFlag", true)
342 aaiUpdator.updateVnfToUnLocked(vnfId)
345 msoLogger.trace('Exited ' + method)
346 } catch (BpmnError e) {
348 } catch (Exception e) {
349 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
350 execution.setVariable("errorCode", "1002")
351 execution.setVariable("errorText", e.getMessage())
356 * Check if VF Closed Loop Disabled in A&AI.
359 * @param execution The flow's execution instance.
361 public void checkIfClosedLoopDisabledInAAI(DelegateExecution execution) {
362 def method = getClass().getSimpleName() + '.checkIfClosedLoopDisabledInAAI(' +
363 'execution=' + execution.getId() +
366 execution.setVariable('errorCode', "0")
367 execution.setVariable("workStep", "checkClosedLoopDisabledFlagInAAI")
368 execution.setVariable("failedActivity", "AAI")
369 msoLogger.trace('Entered ' + method)
372 def transactionLoggingUuid = UUID.randomUUID().toString()
373 def vnfId = execution.getVariable("vnfId")
374 msoLogger.debug("vnfId is: " + vnfId)
375 AAIResourcesClient client = new AAIResourcesClient()
376 AAIUri genericVnfUri = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId)
377 AAIResultWrapper aaiRW = client.get(genericVnfUri)
378 Map<String, Object> result = aaiRW.asMap()
379 boolean isClosedLoopDisabled = result.getOrDefault("is-closed-loop-disabled", false)
381 msoLogger.debug("isClosedLoopDisabled result: " + isClosedLoopDisabled)
382 execution.setVariable('isClosedLoopDisabled', isClosedLoopDisabled)
384 if (isClosedLoopDisabled) {
385 execution.setVariable("errorCode", "1004")
386 execution.setVariable("errorText", "closedLoop is disabled in A&AI")
389 msoLogger.trace('Exited ' + method)
390 } catch (BpmnError e) {
392 } catch (Exception e) {
393 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
394 execution.setVariable("errorCode", "1002")
395 execution.setVariable("errorText", e.getMessage())
400 * Set VF Closed Loop Disabled Flag in A&AI.
403 * @param execution The flow's execution instance.
405 public void setClosedLoopDisabledInAAI(DelegateExecution execution, boolean setDisabled) {
406 def method = getClass().getSimpleName() + '.setClosedLoopDisabledInAAI(' +
407 'execution=' + execution.getId() +
410 execution.setVariable('errorCode', "0")
412 execution.setVariable("workStep", "setClosedLoopDisabledFlagInAAI")
413 execution.setVariable("rollbackSetClosedLoopDisabledFlag", true)
416 execution.setVariable("workStep", "unsetClosedLoopDisabledFlagInAAI")
419 execution.setVariable("failedActivity", "AAI")
420 msoLogger.trace('Entered ' + method)
423 def transactionLoggingUuid = UUID.randomUUID().toString()
424 def vnfId = execution.getVariable("vnfId")
425 AAIResourcesClient client = new AAIResourcesClient()
426 AAIUri genericVnfUri = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId)
428 Map<String, Boolean> request = new HashMap<>()
429 request.put("is-closed-loop-disabled", setDisabled)
430 client.update(genericVnfUri, request)
431 msoLogger.debug("set isClosedLoop to: " + setDisabled)
433 msoLogger.trace('Exited ' + method)
434 } catch (BpmnError e) {
436 } catch (Exception e) {
437 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
438 execution.setVariable("errorCode", "1002")
439 execution.setVariable("errorText", e.getMessage())
447 * Call APP-C client to execute specified APP-C command for this VNF.
450 * @param execution The flow's execution instance.
451 * @param action The action to take in APP-C.
453 public void runAppcCommand(DelegateExecution execution, Action action) {
454 def method = getClass().getSimpleName() + '.runAppcCommand(' +
455 'execution=' + execution.getId() +
458 execution.setVariable('errorCode', "0")
459 msoLogger.trace('Entered ' + method)
461 ApplicationControllerClient appcClient = null
464 msoLogger.debug("Running APP-C action: " + action.toString())
465 String vnfId = execution.getVariable('vnfId')
466 String msoRequestId = execution.getVariable('requestId')
467 execution.setVariable('msoRequestId', msoRequestId)
468 execution.setVariable("failedActivity", "APP-C")
470 appcClient = new ApplicationControllerClient()
471 ApplicationControllerSupport support = new ApplicationControllerSupport()
472 appcClient.appCSupport=support
473 org.springframework.test.util.ReflectionTestUtils.setField(support, "lcmModelPackage", "org.onap.appc.client.lcm.model");
474 Flags flags = new Flags();
475 ActionIdentifiers actionIdentifiers = new ActionIdentifiers();
476 actionIdentifiers.setVnfId(vnfId);
480 execution.setVariable('workStep', "LockVNF")
481 appcStatus = appcClient.runCommand(Action.Lock,actionIdentifiers,null,msoRequestId)
484 execution.setVariable('workStep', "UnlockVNF")
485 appcStatus = appcClient.runCommand(Action.Unlock,actionIdentifiers,null,msoRequestId)
487 case Action.HealthCheck:
488 def healthCheckIndex = execution.getVariable('healthCheckIndex')
489 execution.setVariable('workStep', "HealthCheckVNF" + healthCheckIndex)
490 execution.setVariable('healthCheckIndex', healthCheckIndex + 1)
491 appcStatus = appcClient.runCommand(Action.HealthCheck,actionIdentifiers,null,msoRequestId)
494 execution.setVariable('workStep', "StartVNF")
495 appcStatus = appcClient.runCommand(Action.Start,actionIdentifiers,null,msoRequestId)
498 execution.setVariable('workStep', "StopVNF")
499 appcStatus = appcClient.runCommand(Action.Stop,actionIdentifiers,null,msoRequestId)
504 msoLogger.debug("Completed AppC request")
505 int appcCode = appcStatus.getCode()
506 msoLogger.debug("AppC status code is: " + appcCode)
507 msoLogger.debug("AppC status message is: " + appcStatus.getMessage())
508 if (support.getCategoryOf(appcStatus) == ApplicationControllerSupport.StatusCategory.ERROR) {
509 execution.setVariable("errorCode", Integer.toString(appcCode))
510 execution.setVariable("errorText", appcStatus.getMessage())
513 msoLogger.trace('Exited ' + method)
514 } catch (BpmnError e) {
515 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
516 execution.setVariable("errorCode", "1002")
517 execution.setVariable("errorText", e.getMessage())
518 } catch (java.lang.NoSuchMethodError 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 (Exception 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())
530 * Placeholder for a call to APP-C client to execute specified APP-C command for this VNF.
533 * @param execution The flow's execution instance.
534 * @param action The action to take in APP-C.
536 public void runAppcCommandPlaceholder(DelegateExecution execution, String action) {
537 def method = getClass().getSimpleName() + '.runAppcCommandPlaceholder(' +
538 'execution=' + execution.getId() +
541 execution.setVariable('errorCode', "0")
542 msoLogger.trace('Entered ' + method)
543 execution.setVariable("failedActivity", "APP-C")
544 execution.setVariable("workStep", action)
550 * Handle Abort disposition from RainyDayHandler
552 * @param execution The flow's execution instance.
554 public void abortProcessing(DelegateExecution execution) {
555 def method = getClass().getSimpleName() + '.abortProcessing(' +
556 'execution=' + execution.getId() +
559 msoLogger.trace('Entered ' + method)
561 def errorText = execution.getVariable("errorText")
562 def errorCode = execution.getVariable("errorCode")
564 exceptionUtil.buildAndThrowWorkflowException(execution, errorCode as Integer, errorText)
568 * Increment Retry Count for Current Work Step
570 * @param execution The flow's execution instance.
572 public void incrementRetryCount(DelegateExecution execution) {
573 def method = getClass().getSimpleName() + '.incrementRetryCount(' +
574 'execution=' + execution.getId() +
577 msoLogger.trace('Entered ' + method)
579 String retryCountVariableName = execution.getVariable("workStep") + "RetryCount"
580 execution.setVariable("retryCountVariableName", retryCountVariableName)
582 def retryCountVariable = execution.getVariable(retryCountVariableName)
585 if (retryCountVariable != null) {
586 retryCount = (int) retryCountVariable
591 execution.setVariable(retryCountVariableName, retryCount)
593 msoLogger.debug("value of " + retryCountVariableName + " is " + retryCount)
594 msoLogger.trace('Exited ' + method)