2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Modifications Copyright (c) 2019 Samsung
8 * ================================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.so.bpmn.infrastructure.scripts
24 import com.google.common.base.Strings
25 import org.camunda.bpm.engine.delegate.BpmnError
26 import org.camunda.bpm.engine.delegate.DelegateExecution
27 import org.onap.appc.client.lcm.model.Action;
28 import org.onap.appc.client.lcm.model.Status
29 import org.onap.so.bpmn.common.scripts.ExceptionUtil
30 import org.onap.so.bpmn.common.scripts.MsoUtils
31 import org.onap.so.bpmn.core.domain.ModelInfo
32 import org.onap.so.bpmn.core.domain.ServiceDecomposition
33 import org.onap.so.bpmn.core.domain.VnfResource
34 import org.onap.so.bpmn.core.json.JsonUtils
35 import org.onap.so.client.aai.*
36 import org.onap.so.client.appc.ApplicationControllerOrchestrator
37 import org.onap.so.client.appc.ApplicationControllerSupport
38 import org.onap.so.logger.ErrorCode
39 import org.onap.so.logger.MessageEnum
40 import org.slf4j.Logger
41 import org.slf4j.LoggerFactory
43 import groovy.json.JsonOutput
44 import groovy.json.JsonSlurper
46 public class ReplaceVnfInfra extends VnfCmBase {
47 private static final Logger logger = LoggerFactory.getLogger( ReplaceVnfInfra.class);
49 ExceptionUtil exceptionUtil = new ExceptionUtil()
50 JsonUtils jsonUtils = new JsonUtils()
51 def prefix = "RPLVnfI_"
54 * Initialize the flow's variables.
56 * @param execution The flow's execution instance.
58 public void initProcessVariables(DelegateExecution execution) {
59 execution.setVariable('prefix', 'RPLVnfI_')
60 execution.setVariable('Request', null)
61 execution.setVariable('requestInfo', null)
62 execution.setVariable('source', null)
63 execution.setVariable('vnfInputs', null)
64 execution.setVariable('tenantId', null)
65 execution.setVariable('vnfParams', null)
66 execution.setVariable('controllerType', null)
67 execution.setVariable('cloudConfiguration', null)
68 execution.setVariable('ReplaceVnfSuccessIndicator', false)
69 execution.setVariable('serviceType', null)
70 execution.setVariable('nfRole', null)
71 execution.setVariable('currentActivity', 'RPLVnfI')
72 execution.setVariable('workStep', null)
73 execution.setVariable('failedActivity', null)
74 execution.setVariable('errorCode', "0")
75 execution.setVariable('errorText', null)
76 execution.setVariable('healthCheckIndex', 1)
77 execution.setVariable('retainResources', true)
78 execution.setVariable('productFamilyId', null)
79 execution.setVariable('healthCheckIndex0', 0)
80 execution.setVariable('healthCheckIndex1', 1)
81 execution.setVariable("rollbackSetClosedLoopDisabledFlag", false)
82 execution.setVariable("rollbackVnfStop", false)
83 execution.setVariable("rollbackVnfLock", false)
84 execution.setVariable("rollbackQuiesceTraffic", false)
85 execution.setVariable("rollbackSetVnfInMaintenanceFlag", false)
86 execution.setVariable("platform", null)
87 execution.setVariable("lineOfBusiness", null)
91 * Check for missing elements in the received request.
93 * @param execution The flow's execution instance.
95 public void preProcessRequest(DelegateExecution execution) {
96 def method = getClass().getSimpleName() + '.preProcessRequest(' +
97 'execution=' + execution.getId() +
99 initProcessVariables(execution)
101 logger.trace('Entered ' + method)
103 initProcessVariables(execution)
105 def incomingRequest = execution.getVariable('bpmnRequest')
107 logger.debug("Incoming Infra Request: " + incomingRequest)
109 def jsonSlurper = new JsonSlurper()
110 def jsonOutput = new JsonOutput()
111 Map reqMap = jsonSlurper.parseText(incomingRequest)
112 logger.debug(" Request is in JSON format.")
114 def serviceInstanceId = execution.getVariable('serviceInstanceId')
115 def vnfId = execution.getVariable('vnfId')
117 execution.setVariable('serviceInstanceId', serviceInstanceId)
118 execution.setVariable("isVidRequest", "true")
119 execution.setVariable('serviceType', 'Mobility')
120 execution.setVariable('retainResources', true)
121 execution.setVariable('disableRollback', true)
122 execution.setVariable('payload', "")
123 execution.setVariable('actionLock', Action.Lock)
124 execution.setVariable('actionUnlock', Action.Unlock)
125 execution.setVariable('actionHealthCheck', Action.HealthCheck)
126 execution.setVariable('actionStart', Action.Start)
127 execution.setVariable('actionStop', Action.Stop)
129 def asdcServiceModelVersion = ''
130 def serviceModelInfo = null
132 def relatedInstanceList = reqMap.requestDetails?.relatedInstanceList
134 if (relatedInstanceList != null) {
135 relatedInstanceList.each {
136 if (it.relatedInstance.modelInfo?.modelType == 'service') {
137 logger.debug("PROCESSING SERVICE INFO")
138 asdcServiceModelVersion = it.relatedInstance.modelInfo?.modelVersion
139 serviceModelInfo = jsonOutput.toJson(it.relatedInstance.modelInfo)
140 logger.debug("ServiceModelInfo: " + serviceModelInfo)
141 def modelInvariant = jsonUtils.getJsonValue(serviceModelInfo, "modelInvariantUuid")
142 logger.debug("modelInvariant: " + modelInvariant)
148 execution.setVariable('asdcServiceModelVersion', asdcServiceModelVersion)
149 execution.setVariable('serviceModelInfo', serviceModelInfo)
150 def vnfModelInfo = jsonOutput.toJson(reqMap.requestDetails?.modelInfo)
151 execution.setVariable('vnfModelInfo', vnfModelInfo)
152 def vnfModelInvariantUuid = jsonUtils.getJsonValue(vnfModelInfo, "modelInvariantUuid")
153 execution.setVariable('vnfModelInvariantUuid', vnfModelInvariantUuid)
154 logger.debug("vnfModelInvariantUuid: " + vnfModelInvariantUuid)
156 def vnfType = execution.getVariable('vnfType')
157 execution.setVariable('vnfType', vnfType)
160 def controllerType = reqMap.requestDetails?.requestParameters?.controllerType
161 execution.setVariable('controllerType', controllerType)
163 logger.debug('Controller Type: ' + controllerType)
165 def userParams = reqMap.requestDetails?.requestParameters?.userParams
167 Map<String, String> userParamsMap = [:]
168 if (userParams != null) {
169 userParams.each { userParam ->
170 userParamsMap.put(userParam.name, userParam.value.toString())
174 logger.debug('Processed user params: ' + userParamsMap)
176 execution.setVariable('vfModuleInputParams', userParamsMap)
178 def requestId = execution.getVariable("requestId")
179 execution.setVariable('msoRequestId', requestId)
180 logger.debug("requestId is: " + requestId)
182 def vnfName = reqMap.requestDetails?.requestInfo?.instanceName ?: null
183 execution.setVariable('vnfName', vnfName)
185 def requestorId = reqMap.requestDetails?.requestInfo?.requestorId ?: null
186 execution.setVariable('requestorId', requestorId)
188 def usePreload = reqMap.requestDetails?.requestParameters?.usePreload
189 execution.setVariable('usePreload', usePreload)
191 def productFamilyId = reqMap.requestDetails?.requestInfo?.productFamilyId ?: null
192 execution.setVariable('productFamilyId', productFamilyId)
194 def cloudConfiguration = jsonOutput.toJson(reqMap.requestDetails?.cloudConfiguration)
195 execution.setVariable('cloudConfiguration', cloudConfiguration)
196 def lcpCloudRegionId = jsonUtils.getJsonValue(cloudConfiguration, "lcpCloudRegionId")
197 execution.setVariable('lcpCloudRegionId', lcpCloudRegionId)
198 def cloudOwner = jsonUtils.getJsonValue(cloudConfiguration, "cloudOwner")
199 execution.setVariable('cloudOwner', cloudOwner)
200 def tenantId = jsonUtils.getJsonValue(cloudConfiguration, "tenantId")
201 execution.setVariable('tenantId', tenantId)
203 def globalSubscriberId = reqMap.requestDetails?.subscriberInfo?.globalSubscriberId ?: ''
204 execution.setVariable('globalSubscriberId', globalSubscriberId)
206 execution.setVariable('sdncVersion', '1702')
208 execution.setVariable("ReplaceVnfInfraSuccessIndicator", false)
212 def source = reqMap.requestDetails?.requestInfo?.source
213 execution.setVariable("source", source)
215 //For Completion Handler & Fallout Handler
217 """<request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
218 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
219 <action>REPLACE</action>
220 <source>${MsoUtils.xmlEscape(source)}</source>
223 execution.setVariable("requestInfo", requestInfo)
225 logger.debug('RequestInfo: ' + execution.getVariable("requestInfo"))
227 logger.trace('Exited ' + method)
230 catch(groovy.json.JsonException je) {
231 logger.debug(" Request is not in JSON format.")
232 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, "Invalid request format")
236 String restFaultMessage = e.getMessage()
237 logger.error(Strings.repeat("{} ", 5), MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
238 "Exception Encountered - " + "\n" + restFaultMessage, "BPMN",
239 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e);
240 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, restFaultMessage)
245 * Prepare and send the sychronous response for this flow.
247 * @param execution The flow's execution instance.
249 public void sendSynchResponse(DelegateExecution execution) {
250 def method = getClass().getSimpleName() + '.sendSynchResponse(' +
251 'execution=' + execution.getId() +
254 logger.trace('Entered ' + method)
258 def requestInfo = execution.getVariable('requestInfo')
259 def requestId = execution.getVariable('requestId')
260 def source = execution.getVariable('source')
261 def progress = getNodeTextForce(requestInfo, 'progress')
262 if (progress.isEmpty()) {
265 def startTime = getNodeTextForce(requestInfo, 'start-time')
266 if (startTime.isEmpty()) {
267 startTime = System.currentTimeMillis()
270 // RESTResponse (for API Handler (APIH) Reply Task)
271 def vnfId = execution.getVariable("vnfId")
272 String synchResponse = """{"requestReferences":{"instanceId":"${vnfId}","requestId":"${requestId}"}}""".trim()
274 sendWorkflowResponse(execution, 200, synchResponse)
276 logger.trace('Exited ' + method)
277 } catch (BpmnError e) {
279 } catch (Exception e) {
280 logger.error(Strings.repeat("{} ", 5), MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
281 'Caught exception in ' + method, "BPMN",
282 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e);
283 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in sendResponse(): ' + e.getMessage())
290 * Get VnfResource decomposition object for this VNF.
293 * @param execution The flow's execution instance.
295 public void getVnfResourceDecomposition(DelegateExecution execution) {
296 def method = getClass().getSimpleName() + '.getVnfResourceDecomposition(' +
297 'execution=' + execution.getId() +
300 logger.trace('Entered ' + method)
303 ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
304 String vnfModelInvariantUuid = execution.getVariable('vnfModelInvariantUuid')
305 logger.debug("vnfModelInvariantUuid: " + vnfModelInvariantUuid)
306 List<VnfResource> vnfResources = serviceDecomposition.getVnfResources()
308 for (i in 0..vnfResources.size()-1) {
309 ModelInfo modelInfo = vnfResources[i].getModelInfo()
310 String modelInvariantUuidFromDecomposition = modelInfo.getModelInvariantUuid()
311 logger.debug("modelInvariantUuidFromDecomposition: " + modelInvariantUuidFromDecomposition)
313 if (vnfModelInvariantUuid.equals(modelInvariantUuidFromDecomposition)) {
314 VnfResource vnfResourceDecomposition = vnfResources[i]
315 execution.setVariable('vnfResourceDecomposition', vnfResourceDecomposition)
316 def nfRole = vnfResourceDecomposition.getNfRole()
317 execution.setVariable('nfRole', nfRole)
318 logger.debug("vnfResourceDecomposition: " + vnfResourceDecomposition.toJsonString())
327 logger.trace('Exited ' + method)
328 } catch (BpmnError e) {
330 } catch (Exception e) {
331 logger.error(Strings.repeat("{} ", 5), MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
332 'Caught exception in ' + method, "BPMN",
333 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e);
334 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in getVnfResourceDecomposition(): ' + e.getMessage())
339 * Check if this VNF is already in maintenance in A&AI.
342 * @param execution The flow's execution instance.
344 public void checkIfVnfInMaintInAAI(DelegateExecution execution) {
345 def method = getClass().getSimpleName() + '.checkIfVnfInMaintInAAI(' +
346 'execution=' + execution.getId() +
349 execution.setVariable('errorCode', "0")
350 execution.setVariable("workStep", "checkIfVnfInMaintInAAI")
351 execution.setVariable("failedActivity", "AAI")
352 logger.trace('Entered ' + method)
355 AAIRestClientImpl client = new AAIRestClientImpl()
356 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
357 aaiValidator.setClient(client)
358 def vnfId = execution.getVariable("vnfId")
359 boolean isInMaint = aaiValidator.isVNFLocked(vnfId)
360 logger.debug("isInMaint result: " + isInMaint)
361 execution.setVariable('isVnfInMaintenance', isInMaint)
364 execution.setVariable("errorCode", "1003")
365 execution.setVariable("errorText", "VNF is in maintenance in A&AI")
369 logger.trace('Exited ' + method)
370 } catch (BpmnError e) {
372 } catch (Exception e) {
373 logger.error(Strings.repeat("{} ", 5), MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
374 'Caught exception in ' + method, "BPMN",
375 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e);
376 execution.setVariable("errorCode", "1002")
377 execution.setVariable("errorText", e.getMessage())
378 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfVnfInMaintInAAI(): ' + e.getMessage())
384 * Check if this VNF's pservers are locked in A&AI.
387 * @param execution The flow's execution instance.
389 public void checkIfPserversInMaintInAAI(DelegateExecution execution) {
390 def method = getClass().getSimpleName() + '.checkIfPserversInMaintInAAI(' +
391 'execution=' + execution.getId() +
394 execution.setVariable('errorCode', "0")
395 logger.trace('Entered ' + method)
396 execution.setVariable("workStep", "checkIfPserversInMaintInAAI")
397 execution.setVariable("failedActivity", "AAI")
400 AAIRestClientImpl client = new AAIRestClientImpl()
401 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
402 aaiValidator.setClient(client)
403 def vnfId = execution.getVariable("vnfId")
404 boolean areLocked = aaiValidator.isPhysicalServerLocked(vnfId)
405 logger.debug("areLocked result: " + areLocked)
406 execution.setVariable('arePserversLocked', areLocked)
409 execution.setVariable("errorCode", "1003")
410 execution.setVariable("errorText", "pServers are locked in A&AI")
413 logger.trace('Exited ' + method)
414 } catch (BpmnError e) {
416 } catch (Exception e) {
417 logger.error(Strings.repeat("{} ", 5), MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
418 'Caught exception in ' + method, "BPMN",
419 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e);
420 execution.setVariable("errorCode", "1002")
421 execution.setVariable("errorText", e.getMessage())
422 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfPserversInMaintInAAI(): ' + e.getMessage())
427 * Set inMaint flag for this VNF to the specified value in A&AI.
430 * @param execution The flow's execution instance.
431 * @param inMaint The boolean value of the flag to set
433 public void setVnfInMaintFlagInAAI(DelegateExecution execution, boolean inMaint) {
434 def method = getClass().getSimpleName() + '.setVnfInMaintFlagInAAI(' +
435 'execution=' + execution.getId() +
438 execution.setVariable('errorCode', "0")
439 logger.trace('Entered ' + method)
441 execution.setVariable("workStep", "setVnfInMaintFlagInAAI")
444 execution.setVariable("workStep", "unsetVnfInMaintFlagInAAI")
446 execution.setVariable("failedActivity", "AAI")
449 AAIRestClientImpl client = new AAIRestClientImpl()
450 AAIUpdatorImpl aaiUpdator = new AAIUpdatorImpl()
451 aaiUpdator.setClient(client)
452 def vnfId = execution.getVariable("vnfId")
454 aaiUpdator.updateVnfToLocked(vnfId)
455 execution.setVariable("rollbackSetVnfInMaintenanceFlag", true)
458 aaiUpdator.updateVnfToUnLocked(vnfId)
461 logger.trace('Exited ' + method)
462 } catch (BpmnError e) {
464 } catch (Exception e) {
465 logger.error(Strings.repeat("{} ", 5), MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
466 'Caught exception in ' + method, "BPMN",
467 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e);
468 execution.setVariable("errorCode", "1002")
469 execution.setVariable("errorText", e.getMessage())
474 * Call APP-C client to execute specified APP-C command for this VNF.
477 * @param execution The flow's execution instance.
478 * @param action The action to take in APP-C.
480 public void runAppcCommand(DelegateExecution execution, Action action) {
481 def method = getClass().getSimpleName() + '.runAppcCommand(' +
482 'execution=' + execution.getId() +
485 execution.setVariable('errorCode', "0")
486 logger.trace('Entered ' + method)
489 logger.debug("Running APP-C action: " + action.toString())
490 String vnfId = execution.getVariable('vnfId')
491 String msoRequestId = execution.getVariable('requestId')
492 execution.setVariable('msoRequestId', msoRequestId)
493 execution.setVariable("failedActivity", "APP-C")
494 execution.setVariable("workStep", action.toString() + "VNF")
496 ApplicationControllerOrchestrator appcClient = new ApplicationControllerOrchestrator()
497 Status appcStatus = null
500 execution.setVariable('workStep', "LockVNF")
501 appcStatus = appcClient.runCommand(Action.Lock,msoRequestId,vnfId,null)
504 execution.setVariable('workStep', "UnlockVNF")
505 appcStatus = appcClient.runCommand(Action.Unlock,msoRequestId,vnfId,null)
507 case Action.HealthCheck:
508 def healthCheckIndex = execution.getVariable('healthCheckIndex')
509 execution.setVariable('workStep', "HealthCheckVNF" + healthCheckIndex)
510 execution.setVariable('healthCheckIndex', healthCheckIndex + 1)
511 appcStatus = appcClient.runCommand(Action.HealthCheck,msoRequestId,vnfId,null)
514 execution.setVariable('workStep', "StartVNF")
515 appcStatus = appcClient.runCommand(Action.Start,msoRequestId,vnfId,null)
518 execution.setVariable('workStep', "StopVNF")
519 appcStatus = appcClient.runCommand(Action.Stop,msoRequestId,vnfId,null)
524 logger.debug("Completed AppC request")
525 int appcCode = appcStatus.getCode()
526 logger.debug("AppC status code is: " + appcCode)
527 logger.debug("AppC status message is: " + appcStatus.getMessage())
528 if (support.getCategoryOf(appcStatus) == ApplicationControllerSupport.StatusCategory.ERROR) {
529 execution.setVariable("errorCode", Integer.toString(appcCode))
530 execution.setVariable("errorText", appcStatus.getMessage())
533 logger.trace('Exited ' + method)
534 } catch (BpmnError e) {
535 logger.error(Strings.repeat("{} ", 5), MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
536 'Caught exception in ' + method, "BPMN",
537 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e);
538 execution.setVariable("errorCode", "1002")
539 execution.setVariable("errorText", e.getMessage())
540 } catch (java.lang.NoSuchMethodError e) {
541 logger.error(Strings.repeat("{} ", 5), MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
542 'Caught exception in ' + method, "BPMN",
543 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e);
544 execution.setVariable("errorCode", "1002")
545 execution.setVariable("errorText", e.getMessage())
546 } catch (Exception e) {
547 logger.error(Strings.repeat("{} ", 5), MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
548 'Caught exception in ' + method, "BPMN",
549 ErrorCode.UnknownError.getValue(), "Exception is:\n" + e);
550 execution.setVariable("errorCode", "1002")
551 execution.setVariable("errorText", e.getMessage())
558 * Prepare DoDeleteVnfAndModules call.
561 * @param execution The flow's execution instance.
563 public void prepDoDeleteVnfAndModules(DelegateExecution execution) {
564 def method = getClass().getSimpleName() + '.prepDoDeleteVnfAndModules(' +
565 'execution=' + execution.getId() +
568 execution.setVariable('errorCode', "0")
569 logger.trace('Entered ' + method)
570 execution.setVariable("workStep", "doDeleteVnfAndModules")
571 execution.setVariable("failedActivity", "MSO Delete VNF")
572 logger.trace('Exited ' + method)
577 * Prepare DoCreateVnfAndModules call.
580 * @param execution The flow's execution instance.
582 public void prepDoCreateVnfAndModules(DelegateExecution execution) {
583 def method = getClass().getSimpleName() + '.prepDoReplaceVnfAndModules(' +
584 'execution=' + execution.getId() +
587 execution.setVariable('errorCode', "0")
588 logger.trace('Entered ' + method)
589 execution.setVariable("workStep", "doCreateVnfAndModules")
590 execution.setVariable("failedActivity", "MSO Create VNF")
591 logger.trace('Exited ' + method)
597 * Handle Abort disposition from RainyDayHandler
599 * @param execution The flow's execution instance.
601 public void abortProcessing(DelegateExecution execution) {
602 def method = getClass().getSimpleName() + '.abortProcessing(' +
603 'execution=' + execution.getId() +
606 logger.trace('Entered ' + method)
608 def errorText = execution.getVariable("errorText")
609 def errorCode = execution.getVariable("errorCode")
611 exceptionUtil.buildAndThrowWorkflowException(execution, errorCode as Integer, errorText)
615 * Handle Manual disposition from RainyDayHandler
617 * @param execution The flow's execution instance.
619 public void manualProcessing(DelegateExecution execution) {
620 def method = getClass().getSimpleName() + '.manualProcessing(' +
621 'execution=' + execution.getId() +
624 logger.trace('Entered ' + method)
626 def taskId = execution.getVariable("taskId")
628 exceptionUtil.buildAndThrowWorkflowException(execution, 2000, "Processing halted - manual task created: " + taskId)