2 * ============LICENSE_START=======================================================
\r
4 * ================================================================================
\r
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
\r
6 * ================================================================================
\r
7 * Licensed under the Apache License, Version 2.0 (the "License");
\r
8 * you may not use this file except in compliance with the License.
\r
9 * You may obtain a copy of the License at
\r
10 * http://www.apache.org/licenses/LICENSE-2.0
\r
12 * Unless required by applicable law or agreed to in writing, software
\r
13 * distributed under the License is distributed on an "AS IS" BASIS,
\r
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
15 * See the License for the specific language governing permissions and
\r
16 * limitations under the License.
\r
17 * ============LICENSE_END=========================================================
\r
20 package org.openecomp.mso.bpmn.infrastructure.scripts
\r
22 import groovy.json.JsonOutput
\r
23 import groovy.json.JsonSlurper
\r
24 import groovy.util.Node
\r
25 import groovy.util.XmlParser;
\r
26 import groovy.xml.QName
\r
28 import java.io.Serializable;
\r
29 import java.util.UUID;
\r
30 import org.openecomp.mso.bpmn.common.scripts.ExceptionUtil
\r
31 import org.camunda.bpm.engine.delegate.BpmnError
\r
32 import org.camunda.bpm.engine.impl.cmd.AbstractSetVariableCmd
\r
33 import org.camunda.bpm.engine.delegate.DelegateExecution
\r
34 import org.openecomp.mso.rest.APIResponse
\r
35 import org.openecomp.mso.rest.RESTClient
\r
36 import org.openecomp.mso.rest.RESTConfig
\r
37 import org.openecomp.mso.bpmn.common.scripts.AbstractServiceTaskProcessor;
\r
38 import org.openecomp.mso.bpmn.common.scripts.VidUtils;
\r
39 import org.openecomp.mso.bpmn.core.RollbackData
\r
40 import org.openecomp.mso.bpmn.core.WorkflowException
\r
41 import org.openecomp.mso.bpmn.core.json.JsonUtils
\r
42 import org.openecomp.mso.bpmn.core.domain.ModelInfo
\r
43 import org.openecomp.mso.bpmn.core.domain.ServiceDecomposition
\r
44 import org.openecomp.mso.bpmn.core.domain.VnfResource
\r
45 import org.openecomp.mso.client.aai.*
\r
47 import org.openecomp.mso.client.appc.ApplicationControllerOrchestrator
\r
48 import org.onap.appc.client.lcm.model.Action;
\r
49 import org.onap.appc.client.lcm.model.ActionIdentifiers;
\r
50 import org.onap.appc.client.lcm.model.LockInput
\r
51 import org.onap.appc.client.lcm.model.UnlockInput
\r
52 import org.onap.appc.client.lcm.model.HealthCheckInput
\r
53 import org.onap.appc.client.lcm.model.StartInput
\r
54 import org.onap.appc.client.lcm.model.StopInput
\r
55 import org.onap.appc.client.lcm.model.Flags
\r
56 import org.onap.appc.client.lcm.model.Status
\r
60 public class UpdateVnfInfra extends VnfCmBase {
\r
62 ExceptionUtil exceptionUtil = new ExceptionUtil()
\r
63 JsonUtils jsonUtils = new JsonUtils()
\r
64 def prefix = "UPDVnfI_"
\r
67 * Initialize the flow's variables.
\r
69 * @param execution The flow's execution instance.
\r
71 public void initProcessVariables(DelegateExecution execution) {
\r
72 execution.setVariable('prefix', 'UPDVnfI_')
\r
73 execution.setVariable('Request', null)
\r
74 execution.setVariable('source', null)
\r
75 execution.setVariable('vnfInputs', null)
\r
76 execution.setVariable('tenantId', null)
\r
77 execution.setVariable('vnfParams', null)
\r
78 execution.setVariable('controllerType', null)
\r
79 execution.setVariable('UpdateVnfSuccessIndicator', false)
\r
80 execution.setVariable('serviceType', null)
\r
81 execution.setVariable('nfRole', null)
\r
82 execution.setVariable('currentActivity', 'UPDVnfI')
\r
83 execution.setVariable('workStep', null)
\r
84 execution.setVariable('failedActivity', null)
\r
85 execution.setVariable('errorCode', "0")
\r
86 execution.setVariable('errorText', null)
\r
87 execution.setVariable('healthCheckIndex0', 0)
\r
88 execution.setVariable('healthCheckIndex1', 1)
\r
89 execution.setVariable("rollbackSetClosedLoopDisabledFlag", false)
\r
90 execution.setVariable("rollbackVnfStop", false)
\r
91 execution.setVariable("rollbackVnfLock", false)
\r
92 execution.setVariable("rollbackQuiesceTraffic", false)
\r
93 execution.setVariable("rollbackSetVnfInMaintenanceFlag", false)
\r
97 * Check for missing elements in the received request.
\r
99 * @param execution The flow's execution instance.
\r
101 public void preProcessRequest(DelegateExecution execution) {
\r
102 def method = getClass().getSimpleName() + '.preProcessRequest(' +
\r
103 'execution=' + execution.getId() +
\r
105 initProcessVariables(execution)
\r
106 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
107 logDebug('Entered ' + method, isDebugLogEnabled)
\r
109 initProcessVariables(execution)
\r
111 def incomingRequest = execution.getVariable('bpmnRequest')
\r
113 utils.log("DEBUG", "Incoming Infra Request: " + incomingRequest, isDebugLogEnabled)
\r
115 def jsonSlurper = new JsonSlurper()
\r
116 def jsonOutput = new JsonOutput()
\r
117 Map reqMap = jsonSlurper.parseText(incomingRequest)
\r
118 utils.log("DEBUG", " Request is in JSON format.", isDebugLogEnabled)
\r
120 execution.setVariable("isVidRequest", "true")
\r
121 execution.setVariable('serviceType', 'Mobility')
\r
122 execution.setVariable('actionLock', Action.Lock)
\r
123 execution.setVariable('actionUnlock', Action.Unlock)
\r
124 execution.setVariable('actionHealthCheck', Action.HealthCheck)
\r
125 execution.setVariable('actionStart', Action.Start)
\r
126 execution.setVariable('actionStop', Action.Stop)
\r
128 def asdcServiceModelVersion = ''
\r
129 def serviceModelInfo = null
\r
131 def relatedInstanceList = reqMap.requestDetails?.relatedInstanceList
\r
133 if (relatedInstanceList != null) {
\r
134 relatedInstanceList.each {
\r
135 if (it.relatedInstance.modelInfo?.modelType == 'service') {
\r
136 utils.log("DEBUG", "PROCESSING SERVICE INFO", isDebugLogEnabled)
\r
137 asdcServiceModelVersion = it.relatedInstance.modelInfo?.modelVersion
\r
138 serviceModelInfo = jsonOutput.toJson(it.relatedInstance.modelInfo)
\r
139 utils.log("DEBUG", "ServiceModelInfo: " + serviceModelInfo, isDebugLogEnabled)
\r
140 def modelInvariant = jsonUtils.getJsonValue(serviceModelInfo, "modelInvariantUuid")
\r
141 utils.log("DEBUG", "modelInvariant: " + modelInvariant, isDebugLogEnabled)
\r
147 execution.setVariable('asdcServiceModelVersion', asdcServiceModelVersion)
\r
148 execution.setVariable('serviceModelInfo', serviceModelInfo)
\r
149 def vnfModelInfo = jsonOutput.toJson(reqMap.requestDetails?.modelInfo)
\r
150 execution.setVariable('vnfModelInfo', vnfModelInfo)
\r
151 def vnfModelInvariantUuid = jsonUtils.getJsonValue(vnfModelInfo, "modelInvariantUuid")
\r
152 execution.setVariable('vnfModelInvariantUuid', vnfModelInvariantUuid)
\r
153 logDebug("vnfModelInvariantUuid: " + vnfModelInvariantUuid, isDebugLogEnabled)
\r
155 def vnfType = execution.getVariable('vnfType')
\r
156 execution.setVariable('vnfType', vnfType)
\r
158 def controllerType = reqMap.requestDetails?.requestParameters?.controllerType
\r
159 execution.setVariable('controllerType', controllerType)
\r
161 utils.log("DEBUG", 'Controller Type: ' + controllerType, isDebugLogEnabled)
\r
163 def userParams = reqMap.requestDetails?.requestParameters?.userParams
\r
165 Map<String, String> userParamsMap = [:]
\r
166 if (userParams != null) {
\r
167 userParams.each { userParam ->
\r
168 userParamsMap.put(userParam.name, userParam.value.toString())
\r
172 utils.log("DEBUG", 'Processed user params: ' + userParamsMap, isDebugLogEnabled)
\r
174 execution.setVariable('vfModuleInputParams', userParamsMap)
\r
176 def requestId = execution.getVariable("mso-request-id")
\r
177 execution.setVariable('requestId', requestId)
\r
178 execution.setVariable('msoRequestId', requestId)
\r
181 def vnfName = reqMap.requestDetails?.requestInfo?.instanceName ?: null
\r
182 execution.setVariable('vnfName', vnfName)
\r
184 def requestorId = reqMap.requestDetails?.requestInfo?.requestorId ?: null
\r
185 execution.setVariable('requestorId', requestorId)
\r
187 def usePreload = reqMap.requestDetails?.requestParameters?.usePreload
\r
188 execution.setVariable('usePreload', usePreload)
\r
190 def cloudConfiguration = reqMap.requestDetails?.cloudConfiguration
\r
191 def lcpCloudRegionId = cloudConfiguration.lcpCloudRegionId
\r
192 execution.setVariable('lcpCloudRegionId', lcpCloudRegionId)
\r
193 def tenantId = cloudConfiguration.tenantId
\r
194 execution.setVariable('tenantId', tenantId)
\r
196 def globalSubscriberId = reqMap.requestDetails?.subscriberInfo?.globalSubscriberId ?: ''
\r
197 execution.setVariable('globalSubscriberId', globalSubscriberId)
\r
199 execution.setVariable('sdncVersion', '1702')
\r
201 execution.setVariable("UpdateVnfInfraSuccessIndicator", false)
\r
203 execution.setVariable("isDebugLogEnabled", isDebugLogEnabled)
\r
205 def source = reqMap.requestDetails?.requestInfo?.source
\r
206 execution.setVariable("source", source)
\r
208 //For Completion Handler & Fallout Handler
\r
209 String requestInfo =
\r
210 """<request-info xmlns="http://org.openecomp/mso/infra/vnf-request/v1">
\r
211 <request-id>${requestId}</request-id>
\r
212 <action>UPDATE</action>
\r
213 <source>${source}</source>
\r
216 execution.setVariable("requestInfo", requestInfo)
\r
218 logDebug('RequestInfo: ' + execution.getVariable("requestInfo"), isDebugLogEnabled)
\r
220 logDebug('Exited ' + method, isDebugLogEnabled)
\r
223 catch(groovy.json.JsonException je) {
\r
224 utils.log("DEBUG", " Request is not in JSON format.", isDebugLogEnabled)
\r
225 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, "Invalid request format")
\r
228 catch(Exception e) {
\r
229 String restFaultMessage = e.getMessage()
\r
230 utils.log("ERROR", " Exception Encountered - " + "\n" + restFaultMessage, isDebugLogEnabled)
\r
231 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, restFaultMessage)
\r
236 * Prepare and send the sychronous response for this flow.
\r
238 * @param execution The flow's execution instance.
\r
240 public void sendSynchResponse(DelegateExecution execution) {
\r
241 def method = getClass().getSimpleName() + '.sendSynchResponse(' +
\r
242 'execution=' + execution.getId() +
\r
244 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
245 logDebug('Entered ' + method, isDebugLogEnabled)
\r
249 def requestInfo = execution.getVariable('requestInfo')
\r
250 def requestId = execution.getVariable('requestId')
\r
251 def source = execution.getVariable('source')
\r
252 def progress = getNodeTextForce(requestInfo, 'progress')
\r
253 if (progress.isEmpty()) {
\r
256 def startTime = getNodeTextForce(requestInfo, 'start-time')
\r
257 if (startTime.isEmpty()) {
\r
258 startTime = System.currentTimeMillis()
\r
261 // RESTResponse (for API Handler (APIH) Reply Task)
\r
262 def vnfId = execution.getVariable("vnfId")
\r
263 String synchResponse = """{"requestReferences":{"instanceId":"${vnfId}","requestId":"${requestId}"}}""".trim()
\r
265 sendWorkflowResponse(execution, 200, synchResponse)
\r
267 logDebug('Exited ' + method, isDebugLogEnabled)
\r
268 } catch (BpmnError e) {
\r
270 } catch (Exception e) {
\r
271 logError('Caught exception in ' + method, e)
\r
272 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in sendResponse(): ' + e.getMessage())
\r
279 * Get VnfResource decomposition object for this VNF.
\r
282 * @param execution The flow's execution instance.
\r
284 public void getVnfResourceDecomposition(DelegateExecution execution) {
\r
285 def method = getClass().getSimpleName() + '.getVnfResourceDecomposition(' +
\r
286 'execution=' + execution.getId() +
\r
288 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
289 logDebug('Entered ' + method, isDebugLogEnabled)
\r
292 ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
\r
293 String vnfModelInvariantUuid = execution.getVariable('vnfModelInvariantUuid')
\r
294 logDebug("vnfModelInvariantUuid: " + vnfModelInvariantUuid, isDebugLogEnabled)
\r
295 List<VnfResource> vnfResources = serviceDecomposition.getServiceVnfs()
\r
297 for (i in 0..vnfResources.size()-1) {
\r
298 ModelInfo modelInfo = vnfResources[i].getModelInfo()
\r
299 String modelInvariantUuidFromDecomposition = modelInfo.getModelInvariantUuid()
\r
300 logDebug("modelInvariantUuidFromDecomposition: " + modelInvariantUuidFromDecomposition, isDebugLogEnabled)
\r
302 if (vnfModelInvariantUuid.equals(modelInvariantUuidFromDecomposition)) {
\r
303 VnfResource vnfResourceDecomposition = vnfResources[i]
\r
304 execution.setVariable('vnfResourceDecomposition', vnfResourceDecomposition)
\r
305 def nfRole = vnfResourceDecomposition.getNfRole()
\r
306 execution.setVariable('nfRole', nfRole)
\r
307 logDebug("vnfResourceDecomposition: " + vnfResourceDecomposition.toJsonString(), isDebugLogEnabled)
\r
316 logDebug('Exited ' + method, isDebugLogEnabled)
\r
317 } catch (BpmnError e) {
\r
319 } catch (Exception e) {
\r
320 logError('Caught exception in ' + method, e)
\r
321 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in getVnfResourceDecomposition(): ' + e.getMessage())
\r
326 * Check if this VNF is already in maintenance in A&AI.
\r
329 * @param execution The flow's execution instance.
\r
331 public void checkIfVnfInMaintInAAI(DelegateExecution execution) {
\r
332 def method = getClass().getSimpleName() + '.checkIfVnfInMaintInAAI(' +
\r
333 'execution=' + execution.getId() +
\r
335 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
336 execution.setVariable('errorCode', "0")
\r
337 execution.setVariable("workStep", "checkIfVnfInMaintInAAI")
\r
338 execution.setVariable("failedActivity", "AAI")
\r
339 logDebug('Entered ' + method, isDebugLogEnabled)
\r
342 def transactionLoggingUuid = UUID.randomUUID().toString()
\r
343 AAIRestClientImpl client = new AAIRestClientImpl()
\r
344 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
\r
345 aaiValidator.setClient(client)
\r
346 def vnfId = execution.getVariable("vnfId")
\r
347 boolean isInMaint = aaiValidator.isVNFLocked(vnfId, transactionLoggingUuid)
\r
348 logDebug("isInMaint result: " + isInMaint, isDebugLogEnabled)
\r
349 execution.setVariable('isVnfInMaintenance', isInMaint)
\r
352 execution.setVariable("errorCode", "1003")
\r
353 execution.setVariable("errorText", "VNF is in maintenance in A&AI")
\r
357 logDebug('Exited ' + method, isDebugLogEnabled)
\r
358 } catch (BpmnError e) {
\r
360 } catch (Exception e) {
\r
361 logError('Caught exception in ' + method, e)
\r
362 execution.setVariable("errorCode", "1002")
\r
363 execution.setVariable("errorText", e.getMessage())
\r
364 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfVnfInMaintInAAI(): ' + e.getMessage())
\r
370 * Check if this VNF's pservers are locked in A&AI.
\r
373 * @param execution The flow's execution instance.
\r
375 public void checkIfPserversInMaintInAAI(DelegateExecution execution) {
\r
376 def method = getClass().getSimpleName() + '.checkIfPserversInMaintInAAI(' +
\r
377 'execution=' + execution.getId() +
\r
379 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
380 execution.setVariable('errorCode', "0")
\r
381 logDebug('Entered ' + method, isDebugLogEnabled)
\r
382 execution.setVariable("workStep", "checkIfPserversInMaintInAAI")
\r
383 execution.setVariable("failedActivity", "AAI")
\r
386 def transactionLoggingUuid = UUID.randomUUID().toString()
\r
387 AAIRestClientImpl client = new AAIRestClientImpl()
\r
388 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
\r
389 aaiValidator.setClient(client)
\r
390 def vnfId = execution.getVariable("vnfId")
\r
391 boolean areLocked = aaiValidator.isPhysicalServerLocked(vnfId, transactionLoggingUuid)
\r
392 logDebug("areLocked result: " + areLocked, isDebugLogEnabled)
\r
393 execution.setVariable('arePserversLocked', areLocked)
\r
396 execution.setVariable("errorCode", "1003")
\r
397 execution.setVariable("errorText", "pServers are locked in A&AI")
\r
400 logDebug('Exited ' + method, isDebugLogEnabled)
\r
401 } catch (BpmnError e) {
\r
403 } catch (Exception e) {
\r
404 logError('Caught exception in ' + method, e)
\r
405 execution.setVariable("errorCode", "1002")
\r
406 execution.setVariable("errorText", e.getMessage())
\r
407 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfPserversInMaintInAAI(): ' + e.getMessage())
\r
412 * Set inMaint flag for this VNF to the specified value in A&AI.
\r
415 * @param execution The flow's execution instance.
\r
416 * @param inMaint The boolean value of the flag to set
\r
418 public void setVnfInMaintFlagInAAI(DelegateExecution execution, boolean inMaint) {
\r
419 def method = getClass().getSimpleName() + '.setVnfInMaintFlagInAAI(' +
\r
420 'execution=' + execution.getId() +
\r
422 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
423 execution.setVariable('errorCode', "0")
\r
424 logDebug('Entered ' + method, isDebugLogEnabled)
\r
426 execution.setVariable("workStep", "setVnfInMaintFlagInAAI")
\r
429 execution.setVariable("workStep", "unsetVnfInMaintFlagInAAI")
\r
431 execution.setVariable("failedActivity", "AAI")
\r
434 def transactionLoggingUuid = UUID.randomUUID().toString()
\r
435 AAIRestClientImpl client = new AAIRestClientImpl()
\r
436 AAIUpdatorImpl aaiUpdator = new AAIUpdatorImpl()
\r
437 aaiUpdator.setClient(client)
\r
438 def vnfId = execution.getVariable("vnfId")
\r
440 aaiUpdator.updateVnfToLocked(vnfId, transactionLoggingUuid)
\r
441 execution.setVariable("rollbackSetVnfInMaintenanceFlag", true)
\r
444 aaiUpdator.updateVnfToUnLocked(vnfId, transactionLoggingUuid)
\r
447 logDebug('Exited ' + method, isDebugLogEnabled)
\r
448 } catch (BpmnError e) {
\r
450 } catch (Exception e) {
\r
451 logError('Caught exception in ' + method, e)
\r
452 execution.setVariable("errorCode", "1002")
\r
453 execution.setVariable("errorText", e.getMessage())
\r
454 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in setVnfInMaintFlagInAAI(): ' + e.getMessage())
\r
461 * Prepare DoUpdateVnfAndModules call.
\r
464 * @param execution The flow's execution instance.
\r
466 public void prepDoUpdateVnfAndModules(DelegateExecution execution) {
\r
467 def method = getClass().getSimpleName() + '.prepDoUpdateVnfAndModules(' +
\r
468 'execution=' + execution.getId() +
\r
470 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
471 execution.setVariable('errorCode', "0")
\r
472 logDebug('Entered ' + method, isDebugLogEnabled)
\r
473 execution.setVariable("workStep", "doUpdateVnfAndModules")
\r
474 execution.setVariable("failedActivity", "MSO Update VNF")
\r
475 logDebug('Exited ' + method, isDebugLogEnabled)
\r
481 * Handle Abort disposition from RainyDayHandler
\r
483 * @param execution The flow's execution instance.
\r
485 public void abortProcessing(DelegateExecution execution) {
\r
486 def method = getClass().getSimpleName() + '.abortProcessing(' +
\r
487 'execution=' + execution.getId() +
\r
489 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
490 logDebug('Entered ' + method, isDebugLogEnabled)
\r
492 def errorText = execution.getVariable("errorText")
\r
493 def errorCode = execution.getVariable("errorCode")
\r
495 exceptionUtil.buildAndThrowWorkflowException(execution, errorCode as Integer, errorText)
\r