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.Status
26 import org.onap.so.bpmn.common.scripts.ExceptionUtil
27 import org.onap.so.bpmn.common.scripts.MsoUtils
28 import org.onap.so.bpmn.core.domain.ModelInfo
29 import org.onap.so.bpmn.core.domain.ServiceDecomposition
30 import org.onap.so.bpmn.core.domain.VnfResource
31 import org.onap.so.bpmn.core.json.JsonUtils
32 import org.onap.so.client.aai.*
33 import org.onap.so.client.appc.ApplicationControllerOrchestrator
34 import org.onap.so.client.appc.ApplicationControllerSupport
35 import org.onap.so.logger.MessageEnum
36 import org.onap.so.logger.MsoLogger
38 import groovy.json.JsonOutput
39 import groovy.json.JsonSlurper
41 public class ReplaceVnfInfra extends VnfCmBase {
42 private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, ReplaceVnfInfra.class);
44 ExceptionUtil exceptionUtil = new ExceptionUtil()
45 JsonUtils jsonUtils = new JsonUtils()
46 def prefix = "RPLVnfI_"
49 * Initialize the flow's variables.
51 * @param execution The flow's execution instance.
53 public void initProcessVariables(DelegateExecution execution) {
54 execution.setVariable('prefix', 'RPLVnfI_')
55 execution.setVariable('Request', null)
56 execution.setVariable('requestInfo', null)
57 execution.setVariable('source', null)
58 execution.setVariable('vnfInputs', null)
59 execution.setVariable('tenantId', null)
60 execution.setVariable('vnfParams', null)
61 execution.setVariable('controllerType', null)
62 execution.setVariable('cloudConfiguration', null)
63 execution.setVariable('ReplaceVnfSuccessIndicator', false)
64 execution.setVariable('serviceType', null)
65 execution.setVariable('nfRole', null)
66 execution.setVariable('currentActivity', 'RPLVnfI')
67 execution.setVariable('workStep', null)
68 execution.setVariable('failedActivity', null)
69 execution.setVariable('errorCode', "0")
70 execution.setVariable('errorText', null)
71 execution.setVariable('healthCheckIndex', 1)
72 execution.setVariable('retainResources', true)
73 execution.setVariable('productFamilyId', null)
74 execution.setVariable('healthCheckIndex0', 0)
75 execution.setVariable('healthCheckIndex1', 1)
76 execution.setVariable("rollbackSetClosedLoopDisabledFlag", false)
77 execution.setVariable("rollbackVnfStop", false)
78 execution.setVariable("rollbackVnfLock", false)
79 execution.setVariable("rollbackQuiesceTraffic", false)
80 execution.setVariable("rollbackSetVnfInMaintenanceFlag", false)
81 execution.setVariable("platform", null)
82 execution.setVariable("lineOfBusiness", null)
86 * Check for missing elements in the received request.
88 * @param execution The flow's execution instance.
90 public void preProcessRequest(DelegateExecution execution) {
91 def method = getClass().getSimpleName() + '.preProcessRequest(' +
92 'execution=' + execution.getId() +
94 initProcessVariables(execution)
96 msoLogger.trace('Entered ' + method)
98 initProcessVariables(execution)
100 def incomingRequest = execution.getVariable('bpmnRequest')
102 msoLogger.debug("Incoming Infra Request: " + incomingRequest)
104 def jsonSlurper = new JsonSlurper()
105 def jsonOutput = new JsonOutput()
106 Map reqMap = jsonSlurper.parseText(incomingRequest)
107 msoLogger.debug(" Request is in JSON format.")
109 def serviceInstanceId = execution.getVariable('serviceInstanceId')
110 def vnfId = execution.getVariable('vnfId')
112 execution.setVariable('serviceInstanceId', serviceInstanceId)
113 execution.setVariable("isVidRequest", "true")
114 execution.setVariable('serviceType', 'Mobility')
115 execution.setVariable('retainResources', true)
116 execution.setVariable('disableRollback', true)
117 execution.setVariable('payload', "")
118 execution.setVariable('actionLock', Action.Lock)
119 execution.setVariable('actionUnlock', Action.Unlock)
120 execution.setVariable('actionHealthCheck', Action.HealthCheck)
121 execution.setVariable('actionStart', Action.Start)
122 execution.setVariable('actionStop', Action.Stop)
124 def asdcServiceModelVersion = ''
125 def serviceModelInfo = null
127 def relatedInstanceList = reqMap.requestDetails?.relatedInstanceList
129 if (relatedInstanceList != null) {
130 relatedInstanceList.each {
131 if (it.relatedInstance.modelInfo?.modelType == 'service') {
132 msoLogger.debug("PROCESSING SERVICE INFO")
133 asdcServiceModelVersion = it.relatedInstance.modelInfo?.modelVersion
134 serviceModelInfo = jsonOutput.toJson(it.relatedInstance.modelInfo)
135 msoLogger.debug("ServiceModelInfo: " + serviceModelInfo)
136 def modelInvariant = jsonUtils.getJsonValue(serviceModelInfo, "modelInvariantUuid")
137 msoLogger.debug("modelInvariant: " + modelInvariant)
143 execution.setVariable('asdcServiceModelVersion', asdcServiceModelVersion)
144 execution.setVariable('serviceModelInfo', serviceModelInfo)
145 def vnfModelInfo = jsonOutput.toJson(reqMap.requestDetails?.modelInfo)
146 execution.setVariable('vnfModelInfo', vnfModelInfo)
147 def vnfModelInvariantUuid = jsonUtils.getJsonValue(vnfModelInfo, "modelInvariantUuid")
148 execution.setVariable('vnfModelInvariantUuid', vnfModelInvariantUuid)
149 msoLogger.debug("vnfModelInvariantUuid: " + vnfModelInvariantUuid)
151 def vnfType = execution.getVariable('vnfType')
152 execution.setVariable('vnfType', vnfType)
155 def controllerType = reqMap.requestDetails?.requestParameters?.controllerType
156 execution.setVariable('controllerType', controllerType)
158 msoLogger.debug('Controller Type: ' + controllerType)
160 def userParams = reqMap.requestDetails?.requestParameters?.userParams
162 Map<String, String> userParamsMap = [:]
163 if (userParams != null) {
164 userParams.each { userParam ->
165 userParamsMap.put(userParam.name, userParam.value.toString())
169 msoLogger.debug('Processed user params: ' + userParamsMap)
171 execution.setVariable('vfModuleInputParams', userParamsMap)
173 def requestId = execution.getVariable("requestId")
174 execution.setVariable('msoRequestId', requestId)
175 msoLogger.debug("requestId is: " + requestId)
177 def vnfName = reqMap.requestDetails?.requestInfo?.instanceName ?: null
178 execution.setVariable('vnfName', vnfName)
180 def requestorId = reqMap.requestDetails?.requestInfo?.requestorId ?: null
181 execution.setVariable('requestorId', requestorId)
183 def usePreload = reqMap.requestDetails?.requestParameters?.usePreload
184 execution.setVariable('usePreload', usePreload)
186 def productFamilyId = reqMap.requestDetails?.requestInfo?.productFamilyId ?: null
187 execution.setVariable('productFamilyId', productFamilyId)
189 def cloudConfiguration = jsonOutput.toJson(reqMap.requestDetails?.cloudConfiguration)
190 execution.setVariable('cloudConfiguration', cloudConfiguration)
191 def lcpCloudRegionId = jsonUtils.getJsonValue(cloudConfiguration, "lcpCloudRegionId")
192 execution.setVariable('lcpCloudRegionId', lcpCloudRegionId)
193 def cloudOwner = jsonUtils.getJsonValue(cloudConfiguration, "cloudOwner")
194 execution.setVariable('cloudOwner', cloudOwner)
195 def tenantId = jsonUtils.getJsonValue(cloudConfiguration, "tenantId")
196 execution.setVariable('tenantId', tenantId)
198 def globalSubscriberId = reqMap.requestDetails?.subscriberInfo?.globalSubscriberId ?: ''
199 execution.setVariable('globalSubscriberId', globalSubscriberId)
201 execution.setVariable('sdncVersion', '1702')
203 execution.setVariable("ReplaceVnfInfraSuccessIndicator", false)
207 def source = reqMap.requestDetails?.requestInfo?.source
208 execution.setVariable("source", source)
210 //For Completion Handler & Fallout Handler
212 """<request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
213 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
214 <action>REPLACE</action>
215 <source>${MsoUtils.xmlEscape(source)}</source>
218 execution.setVariable("requestInfo", requestInfo)
220 msoLogger.debug('RequestInfo: ' + execution.getVariable("requestInfo"))
222 msoLogger.trace('Exited ' + method)
225 catch(groovy.json.JsonException je) {
226 msoLogger.debug(" Request is not in JSON format.")
227 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, "Invalid request format")
231 String restFaultMessage = e.getMessage()
232 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, " Exception Encountered - " + "\n" + restFaultMessage, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
233 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, restFaultMessage)
238 * Prepare and send the sychronous response for this flow.
240 * @param execution The flow's execution instance.
242 public void sendSynchResponse(DelegateExecution execution) {
243 def method = getClass().getSimpleName() + '.sendSynchResponse(' +
244 'execution=' + execution.getId() +
247 msoLogger.trace('Entered ' + method)
251 def requestInfo = execution.getVariable('requestInfo')
252 def requestId = execution.getVariable('requestId')
253 def source = execution.getVariable('source')
254 def progress = getNodeTextForce(requestInfo, 'progress')
255 if (progress.isEmpty()) {
258 def startTime = getNodeTextForce(requestInfo, 'start-time')
259 if (startTime.isEmpty()) {
260 startTime = System.currentTimeMillis()
263 // RESTResponse (for API Handler (APIH) Reply Task)
264 def vnfId = execution.getVariable("vnfId")
265 String synchResponse = """{"requestReferences":{"instanceId":"${vnfId}","requestId":"${requestId}"}}""".trim()
267 sendWorkflowResponse(execution, 200, synchResponse)
269 msoLogger.trace('Exited ' + method)
270 } catch (BpmnError e) {
272 } catch (Exception e) {
273 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
274 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in sendResponse(): ' + e.getMessage())
281 * Get VnfResource decomposition object for this VNF.
284 * @param execution The flow's execution instance.
286 public void getVnfResourceDecomposition(DelegateExecution execution) {
287 def method = getClass().getSimpleName() + '.getVnfResourceDecomposition(' +
288 'execution=' + execution.getId() +
291 msoLogger.trace('Entered ' + method)
294 ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
295 String vnfModelInvariantUuid = execution.getVariable('vnfModelInvariantUuid')
296 msoLogger.debug("vnfModelInvariantUuid: " + vnfModelInvariantUuid)
297 List<VnfResource> vnfResources = serviceDecomposition.getVnfResources()
299 for (i in 0..vnfResources.size()-1) {
300 ModelInfo modelInfo = vnfResources[i].getModelInfo()
301 String modelInvariantUuidFromDecomposition = modelInfo.getModelInvariantUuid()
302 msoLogger.debug("modelInvariantUuidFromDecomposition: " + modelInvariantUuidFromDecomposition)
304 if (vnfModelInvariantUuid.equals(modelInvariantUuidFromDecomposition)) {
305 VnfResource vnfResourceDecomposition = vnfResources[i]
306 execution.setVariable('vnfResourceDecomposition', vnfResourceDecomposition)
307 def nfRole = vnfResourceDecomposition.getNfRole()
308 execution.setVariable('nfRole', nfRole)
309 msoLogger.debug("vnfResourceDecomposition: " + vnfResourceDecomposition.toJsonString())
318 msoLogger.trace('Exited ' + method)
319 } catch (BpmnError e) {
321 } catch (Exception e) {
322 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
323 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in getVnfResourceDecomposition(): ' + e.getMessage())
328 * Check if this VNF is already in maintenance in A&AI.
331 * @param execution The flow's execution instance.
333 public void checkIfVnfInMaintInAAI(DelegateExecution execution) {
334 def method = getClass().getSimpleName() + '.checkIfVnfInMaintInAAI(' +
335 'execution=' + execution.getId() +
338 execution.setVariable('errorCode', "0")
339 execution.setVariable("workStep", "checkIfVnfInMaintInAAI")
340 execution.setVariable("failedActivity", "AAI")
341 msoLogger.trace('Entered ' + method)
344 AAIRestClientImpl client = new AAIRestClientImpl()
345 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
346 aaiValidator.setClient(client)
347 def vnfId = execution.getVariable("vnfId")
348 boolean isInMaint = aaiValidator.isVNFLocked(vnfId)
349 msoLogger.debug("isInMaint result: " + isInMaint)
350 execution.setVariable('isVnfInMaintenance', isInMaint)
353 execution.setVariable("errorCode", "1003")
354 execution.setVariable("errorText", "VNF is in maintenance in A&AI")
358 msoLogger.trace('Exited ' + method)
359 } catch (BpmnError e) {
361 } catch (Exception e) {
362 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
363 execution.setVariable("errorCode", "1002")
364 execution.setVariable("errorText", e.getMessage())
365 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfVnfInMaintInAAI(): ' + e.getMessage())
371 * Check if this VNF's pservers are locked in A&AI.
374 * @param execution The flow's execution instance.
376 public void checkIfPserversInMaintInAAI(DelegateExecution execution) {
377 def method = getClass().getSimpleName() + '.checkIfPserversInMaintInAAI(' +
378 'execution=' + execution.getId() +
381 execution.setVariable('errorCode', "0")
382 msoLogger.trace('Entered ' + method)
383 execution.setVariable("workStep", "checkIfPserversInMaintInAAI")
384 execution.setVariable("failedActivity", "AAI")
387 AAIRestClientImpl client = new AAIRestClientImpl()
388 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
389 aaiValidator.setClient(client)
390 def vnfId = execution.getVariable("vnfId")
391 boolean areLocked = aaiValidator.isPhysicalServerLocked(vnfId)
392 msoLogger.debug("areLocked result: " + areLocked)
393 execution.setVariable('arePserversLocked', areLocked)
396 execution.setVariable("errorCode", "1003")
397 execution.setVariable("errorText", "pServers are locked in A&AI")
400 msoLogger.trace('Exited ' + method)
401 } catch (BpmnError e) {
403 } catch (Exception e) {
404 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
405 execution.setVariable("errorCode", "1002")
406 execution.setVariable("errorText", e.getMessage())
407 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfPserversInMaintInAAI(): ' + e.getMessage())
412 * Set inMaint flag for this VNF to the specified value in A&AI.
415 * @param execution The flow's execution instance.
416 * @param inMaint The boolean value of the flag to set
418 public void setVnfInMaintFlagInAAI(DelegateExecution execution, boolean inMaint) {
419 def method = getClass().getSimpleName() + '.setVnfInMaintFlagInAAI(' +
420 'execution=' + execution.getId() +
423 execution.setVariable('errorCode', "0")
424 msoLogger.trace('Entered ' + method)
426 execution.setVariable("workStep", "setVnfInMaintFlagInAAI")
429 execution.setVariable("workStep", "unsetVnfInMaintFlagInAAI")
431 execution.setVariable("failedActivity", "AAI")
434 AAIRestClientImpl client = new AAIRestClientImpl()
435 AAIUpdatorImpl aaiUpdator = new AAIUpdatorImpl()
436 aaiUpdator.setClient(client)
437 def vnfId = execution.getVariable("vnfId")
439 aaiUpdator.updateVnfToLocked(vnfId)
440 execution.setVariable("rollbackSetVnfInMaintenanceFlag", true)
443 aaiUpdator.updateVnfToUnLocked(vnfId)
446 msoLogger.trace('Exited ' + method)
447 } catch (BpmnError e) {
449 } catch (Exception e) {
450 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
451 execution.setVariable("errorCode", "1002")
452 execution.setVariable("errorText", e.getMessage())
457 * Call APP-C client to execute specified APP-C command for this VNF.
460 * @param execution The flow's execution instance.
461 * @param action The action to take in APP-C.
463 public void runAppcCommand(DelegateExecution execution, Action action) {
464 def method = getClass().getSimpleName() + '.runAppcCommand(' +
465 'execution=' + execution.getId() +
468 execution.setVariable('errorCode', "0")
469 msoLogger.trace('Entered ' + method)
472 msoLogger.debug("Running APP-C action: " + action.toString())
473 String vnfId = execution.getVariable('vnfId')
474 String msoRequestId = execution.getVariable('requestId')
475 execution.setVariable('msoRequestId', msoRequestId)
476 execution.setVariable("failedActivity", "APP-C")
477 execution.setVariable("workStep", action.toString() + "VNF")
479 ApplicationControllerOrchestrator appcClient = new ApplicationControllerOrchestrator()
480 Status appcStatus = null
483 execution.setVariable('workStep', "LockVNF")
484 appcStatus = appcClient.runCommand(Action.Lock,msoRequestId,vnfId,null)
487 execution.setVariable('workStep', "UnlockVNF")
488 appcStatus = appcClient.runCommand(Action.Unlock,msoRequestId,vnfId,null)
490 case Action.HealthCheck:
491 def healthCheckIndex = execution.getVariable('healthCheckIndex')
492 execution.setVariable('workStep', "HealthCheckVNF" + healthCheckIndex)
493 execution.setVariable('healthCheckIndex', healthCheckIndex + 1)
494 appcStatus = appcClient.runCommand(Action.HealthCheck,msoRequestId,vnfId,null)
497 execution.setVariable('workStep', "StartVNF")
498 appcStatus = appcClient.runCommand(Action.Start,msoRequestId,vnfId,null)
501 execution.setVariable('workStep', "StopVNF")
502 appcStatus = appcClient.runCommand(Action.Stop,msoRequestId,vnfId,null)
507 msoLogger.debug("Completed AppC request")
508 int appcCode = appcStatus.getCode()
509 msoLogger.debug("AppC status code is: " + appcCode)
510 msoLogger.debug("AppC status message is: " + appcStatus.getMessage())
511 if (support.getCategoryOf(appcStatus) == ApplicationControllerSupport.StatusCategory.ERROR) {
512 execution.setVariable("errorCode", Integer.toString(appcCode))
513 execution.setVariable("errorText", appcStatus.getMessage())
516 msoLogger.trace('Exited ' + method)
517 } catch (BpmnError e) {
518 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
519 execution.setVariable("errorCode", "1002")
520 execution.setVariable("errorText", e.getMessage())
521 } catch (java.lang.NoSuchMethodError e) {
522 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
523 execution.setVariable("errorCode", "1002")
524 execution.setVariable("errorText", e.getMessage())
525 } catch (Exception e) {
526 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, 'Caught exception in ' + method, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception is:\n" + e);
527 execution.setVariable("errorCode", "1002")
528 execution.setVariable("errorText", e.getMessage())
535 * Prepare DoDeleteVnfAndModules call.
538 * @param execution The flow's execution instance.
540 public void prepDoDeleteVnfAndModules(DelegateExecution execution) {
541 def method = getClass().getSimpleName() + '.prepDoDeleteVnfAndModules(' +
542 'execution=' + execution.getId() +
545 execution.setVariable('errorCode', "0")
546 msoLogger.trace('Entered ' + method)
547 execution.setVariable("workStep", "doDeleteVnfAndModules")
548 execution.setVariable("failedActivity", "MSO Delete VNF")
549 msoLogger.trace('Exited ' + method)
554 * Prepare DoCreateVnfAndModules call.
557 * @param execution The flow's execution instance.
559 public void prepDoCreateVnfAndModules(DelegateExecution execution) {
560 def method = getClass().getSimpleName() + '.prepDoReplaceVnfAndModules(' +
561 'execution=' + execution.getId() +
564 execution.setVariable('errorCode', "0")
565 msoLogger.trace('Entered ' + method)
566 execution.setVariable("workStep", "doCreateVnfAndModules")
567 execution.setVariable("failedActivity", "MSO Create VNF")
568 msoLogger.trace('Exited ' + method)
574 * Handle Abort disposition from RainyDayHandler
576 * @param execution The flow's execution instance.
578 public void abortProcessing(DelegateExecution execution) {
579 def method = getClass().getSimpleName() + '.abortProcessing(' +
580 'execution=' + execution.getId() +
583 msoLogger.trace('Entered ' + method)
585 def errorText = execution.getVariable("errorText")
586 def errorCode = execution.getVariable("errorCode")
588 exceptionUtil.buildAndThrowWorkflowException(execution, errorCode as Integer, errorText)
592 * Handle Manual disposition from RainyDayHandler
594 * @param execution The flow's execution instance.
596 public void manualProcessing(DelegateExecution execution) {
597 def method = getClass().getSimpleName() + '.manualProcessing(' +
598 'execution=' + execution.getId() +
601 msoLogger.trace('Entered ' + method)
603 def taskId = execution.getVariable("taskId")
605 exceptionUtil.buildAndThrowWorkflowException(execution, 2000, "Processing halted - manual task created: " + taskId)