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.beans.MetaData.java_lang_Class_PersistenceDelegate
\r
29 import java.io.Serializable;
\r
30 import java.util.UUID;
\r
31 import org.openecomp.mso.bpmn.common.scripts.ExceptionUtil
\r
32 import org.camunda.bpm.engine.delegate.BpmnError
\r
33 import org.camunda.bpm.engine.impl.cmd.AbstractSetVariableCmd
\r
34 import org.camunda.bpm.engine.delegate.DelegateExecution
\r
35 import org.openecomp.mso.rest.APIResponse
\r
36 import org.openecomp.mso.rest.RESTClient
\r
37 import org.openecomp.mso.rest.RESTConfig
\r
38 import org.openecomp.mso.bpmn.common.scripts.AbstractServiceTaskProcessor;
\r
39 import org.openecomp.mso.bpmn.common.scripts.VidUtils;
\r
40 import org.openecomp.mso.bpmn.core.RollbackData
\r
41 import org.openecomp.mso.bpmn.core.WorkflowException
\r
42 import org.openecomp.mso.bpmn.common.scripts.ExceptionUtil
\r
43 import org.openecomp.mso.bpmn.core.json.JsonUtils
\r
44 import org.openecomp.mso.bpmn.core.domain.ModelInfo
\r
45 import org.openecomp.mso.bpmn.core.domain.ServiceDecomposition
\r
46 import org.openecomp.mso.bpmn.core.domain.VnfResource
\r
47 import org.openecomp.mso.client.aai.*
\r
49 import org.openecomp.mso.client.appc.ApplicationControllerOrchestrator
\r
50 import org.onap.appc.client.lcm.model.Action;
\r
51 import org.onap.appc.client.lcm.model.ActionIdentifiers;
\r
52 import org.onap.appc.client.lcm.model.LockInput
\r
53 import org.onap.appc.client.lcm.model.UnlockInput
\r
54 import org.onap.appc.client.lcm.model.HealthCheckInput
\r
55 import org.onap.appc.client.lcm.model.StartInput
\r
56 import org.onap.appc.client.lcm.model.StopInput
\r
57 import org.onap.appc.client.lcm.model.Flags
\r
58 import org.onap.appc.client.lcm.model.Status
\r
62 public class UpdateVnfInfra extends VnfCmBase {
\r
64 ExceptionUtil exceptionUtil = new ExceptionUtil()
\r
65 JsonUtils jsonUtils = new JsonUtils()
\r
66 def prefix = "UPDVnfI_"
\r
69 * Initialize the flow's variables.
\r
71 * @param execution The flow's execution instance.
\r
73 public void initProcessVariables(DelegateExecution execution) {
\r
74 execution.setVariable('prefix', 'UPDVnfI_')
\r
75 execution.setVariable('Request', null)
\r
76 execution.setVariable('source', null)
\r
77 execution.setVariable('vnfInputs', null)
\r
78 execution.setVariable('tenantId', null)
\r
79 execution.setVariable('vnfParams', null)
\r
80 execution.setVariable('UpdateVnfSuccessIndicator', false)
\r
81 execution.setVariable('serviceType', null)
\r
82 execution.setVariable('nfRole', null)
\r
83 execution.setVariable('currentActivity', 'UPDVnfI')
\r
84 execution.setVariable('workStep', null)
\r
85 execution.setVariable('failedActivity', null)
\r
86 execution.setVariable('errorCode', "0")
\r
87 execution.setVariable('errorText', null)
\r
88 execution.setVariable('healthCheckIndex0', 0)
\r
89 execution.setVariable('healthCheckIndex1', 1)
\r
90 execution.setVariable("rollbackSetClosedLoopDisabledFlag", false)
\r
91 execution.setVariable("rollbackVnfStop", false)
\r
92 execution.setVariable("rollbackVnfLock", false)
\r
93 execution.setVariable("rollbackQuiesceTraffic", false)
\r
94 execution.setVariable("rollbackSetVnfInMaintenanceFlag", false)
\r
98 * Check for missing elements in the received request.
\r
100 * @param execution The flow's execution instance.
\r
102 public void preProcessRequest(DelegateExecution execution) {
\r
103 def method = getClass().getSimpleName() + '.preProcessRequest(' +
\r
104 'execution=' + execution.getId() +
\r
106 initProcessVariables(execution)
\r
107 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
108 logDebug('Entered ' + method, isDebugLogEnabled)
\r
110 initProcessVariables(execution)
\r
112 def incomingRequest = execution.getVariable('bpmnRequest')
\r
114 utils.log("DEBUG", "Incoming Infra Request: " + incomingRequest, isDebugLogEnabled)
\r
116 def jsonSlurper = new JsonSlurper()
\r
117 def jsonOutput = new JsonOutput()
\r
118 Map reqMap = jsonSlurper.parseText(incomingRequest)
\r
119 utils.log("DEBUG", " Request is in JSON format.", isDebugLogEnabled)
\r
121 execution.setVariable("isVidRequest", "true")
\r
122 execution.setVariable('serviceType', 'Mobility')
\r
123 execution.setVariable('actionLock', Action.Lock)
\r
124 execution.setVariable('actionUnlock', Action.Unlock)
\r
125 execution.setVariable('actionHealthCheck', Action.HealthCheck)
\r
126 execution.setVariable('actionStart', Action.Start)
\r
127 execution.setVariable('actionStop', Action.Stop)
\r
129 def asdcServiceModelVersion = ''
\r
130 def serviceModelInfo = null
\r
132 def relatedInstanceList = reqMap.requestDetails?.relatedInstanceList
\r
134 if (relatedInstanceList != null) {
\r
135 relatedInstanceList.each {
\r
136 if (it.relatedInstance.modelInfo?.modelType == 'service') {
\r
137 utils.log("DEBUG", "PROCESSING SERVICE INFO", isDebugLogEnabled)
\r
138 asdcServiceModelVersion = it.relatedInstance.modelInfo?.modelVersion
\r
139 serviceModelInfo = jsonOutput.toJson(it.relatedInstance.modelInfo)
\r
140 utils.log("DEBUG", "ServiceModelInfo: " + serviceModelInfo, isDebugLogEnabled)
\r
141 def modelInvariant = jsonUtils.getJsonValue(serviceModelInfo, "modelInvariantUuid")
\r
142 utils.log("DEBUG", "modelInvariant: " + modelInvariant, isDebugLogEnabled)
\r
148 execution.setVariable('asdcServiceModelVersion', asdcServiceModelVersion)
\r
149 execution.setVariable('serviceModelInfo', serviceModelInfo)
\r
150 def vnfModelInfo = jsonOutput.toJson(reqMap.requestDetails?.modelInfo)
\r
151 execution.setVariable('vnfModelInfo', vnfModelInfo)
\r
152 def vnfModelInvariantUuid = jsonUtils.getJsonValue(vnfModelInfo, "modelInvariantUuid")
\r
153 execution.setVariable('vnfModelInvariantUuid', vnfModelInvariantUuid)
\r
154 logDebug("vnfModelInvariantUuid: " + vnfModelInvariantUuid, isDebugLogEnabled)
\r
156 def vnfType = execution.getVariable('vnfType')
\r
157 execution.setVariable('vnfType', vnfType)
\r
159 def userParams = reqMap.requestDetails?.requestParameters?.userParams
\r
161 Map<String, String> userParamsMap = [:]
\r
162 if (userParams != null) {
\r
163 userParams.each { userParam ->
\r
164 userParamsMap.put(userParam.name, userParam.value.toString())
\r
168 utils.log("DEBUG", 'Processed user params: ' + userParamsMap, isDebugLogEnabled)
\r
170 execution.setVariable('vfModuleInputParams', userParamsMap)
\r
172 def requestId = execution.getVariable("mso-request-id")
\r
173 execution.setVariable('requestId', requestId)
\r
174 execution.setVariable('msoRequestId', requestId)
\r
177 def vnfName = reqMap.requestDetails?.requestInfo?.instanceName ?: null
\r
178 execution.setVariable('vnfName', vnfName)
\r
180 def requestorId = reqMap.requestDetails?.requestInfo?.requestorId ?: null
\r
181 execution.setVariable('requestorId', requestorId)
\r
183 def usePreload = reqMap.requestDetails?.requestParameters?.usePreload
\r
184 execution.setVariable('usePreload', usePreload)
\r
186 def cloudConfiguration = reqMap.requestDetails?.cloudConfiguration
\r
187 def lcpCloudRegionId = cloudConfiguration.lcpCloudRegionId
\r
188 execution.setVariable('lcpCloudRegionId', lcpCloudRegionId)
\r
189 def tenantId = cloudConfiguration.tenantId
\r
190 execution.setVariable('tenantId', tenantId)
\r
192 def globalSubscriberId = reqMap.requestDetails?.subscriberInfo?.globalSubscriberId ?: ''
\r
193 execution.setVariable('globalSubscriberId', globalSubscriberId)
\r
195 execution.setVariable('sdncVersion', '1702')
\r
197 execution.setVariable("UpdateVnfInfraSuccessIndicator", false)
\r
199 execution.setVariable("isDebugLogEnabled", isDebugLogEnabled)
\r
201 def source = reqMap.requestDetails?.requestInfo?.source
\r
202 execution.setVariable("source", source)
\r
204 //For Completion Handler & Fallout Handler
\r
205 String requestInfo =
\r
206 """<request-info xmlns="http://org.openecomp/mso/infra/vnf-request/v1">
\r
207 <request-id>${requestId}</request-id>
\r
208 <action>UPDATE</action>
\r
209 <source>${source}</source>
\r
212 execution.setVariable("requestInfo", requestInfo)
\r
214 logDebug('RequestInfo: ' + execution.getVariable("requestInfo"), isDebugLogEnabled)
\r
216 logDebug('Exited ' + method, isDebugLogEnabled)
\r
219 catch(groovy.json.JsonException je) {
\r
220 utils.log("DEBUG", " Request is not in JSON format.", isDebugLogEnabled)
\r
221 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, "Invalid request format")
\r
224 catch(Exception e) {
\r
225 String restFaultMessage = e.getMessage()
\r
226 utils.log("ERROR", " Exception Encountered - " + "\n" + restFaultMessage, isDebugLogEnabled)
\r
227 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, restFaultMessage)
\r
232 * Prepare and send the sychronous response for this flow.
\r
234 * @param execution The flow's execution instance.
\r
236 public void sendSynchResponse(DelegateExecution execution) {
\r
237 def method = getClass().getSimpleName() + '.sendSynchResponse(' +
\r
238 'execution=' + execution.getId() +
\r
240 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
241 logDebug('Entered ' + method, isDebugLogEnabled)
\r
245 def requestInfo = execution.getVariable('requestInfo')
\r
246 def requestId = execution.getVariable('requestId')
\r
247 def source = execution.getVariable('source')
\r
248 def progress = getNodeTextForce(requestInfo, 'progress')
\r
249 if (progress.isEmpty()) {
\r
252 def startTime = getNodeTextForce(requestInfo, 'start-time')
\r
253 if (startTime.isEmpty()) {
\r
254 startTime = System.currentTimeMillis()
\r
257 // RESTResponse (for API Handler (APIH) Reply Task)
\r
258 def vnfId = execution.getVariable("vnfId")
\r
259 String synchResponse = """{"requestReferences":{"instanceId":"${vnfId}","requestId":"${requestId}"}}""".trim()
\r
261 sendWorkflowResponse(execution, 200, synchResponse)
\r
263 logDebug('Exited ' + method, isDebugLogEnabled)
\r
264 } catch (BpmnError e) {
\r
266 } catch (Exception e) {
\r
267 logError('Caught exception in ' + method, e)
\r
268 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in sendResponse(): ' + e.getMessage())
\r
275 * Get VnfResource decomposition object for this VNF.
\r
278 * @param execution The flow's execution instance.
\r
280 public void getVnfResourceDecomposition(DelegateExecution execution) {
\r
281 def method = getClass().getSimpleName() + '.getVnfResourceDecomposition(' +
\r
282 'execution=' + execution.getId() +
\r
284 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
285 logDebug('Entered ' + method, isDebugLogEnabled)
\r
288 ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
\r
289 String vnfModelInvariantUuid = execution.getVariable('vnfModelInvariantUuid')
\r
290 logDebug("vnfModelInvariantUuid: " + vnfModelInvariantUuid, isDebugLogEnabled)
\r
291 List<VnfResource> vnfResources = serviceDecomposition.getServiceVnfs()
\r
293 for (i in 0..vnfResources.size()-1) {
\r
294 ModelInfo modelInfo = vnfResources[i].getModelInfo()
\r
295 String modelInvariantUuidFromDecomposition = modelInfo.getModelInvariantUuid()
\r
296 logDebug("modelInvariantUuidFromDecomposition: " + modelInvariantUuidFromDecomposition, isDebugLogEnabled)
\r
298 if (vnfModelInvariantUuid.equals(modelInvariantUuidFromDecomposition)) {
\r
299 VnfResource vnfResourceDecomposition = vnfResources[i]
\r
300 execution.setVariable('vnfResourceDecomposition', vnfResourceDecomposition)
\r
301 def nfRole = vnfResourceDecomposition.getNfRole()
\r
302 execution.setVariable('nfRole', nfRole)
\r
303 logDebug("vnfResourceDecomposition: " + vnfResourceDecomposition.toJsonString(), isDebugLogEnabled)
\r
312 logDebug('Exited ' + method, isDebugLogEnabled)
\r
313 } catch (BpmnError e) {
\r
315 } catch (Exception e) {
\r
316 logError('Caught exception in ' + method, e)
\r
317 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in getVnfResourceDecomposition(): ' + e.getMessage())
\r
322 * Check if this VNF is already in maintenance in A&AI.
\r
325 * @param execution The flow's execution instance.
\r
327 public void checkIfVnfInMaintInAAI(DelegateExecution execution) {
\r
328 def method = getClass().getSimpleName() + '.checkIfVnfInMaintInAAI(' +
\r
329 'execution=' + execution.getId() +
\r
331 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
332 execution.setVariable('errorCode', "0")
\r
333 execution.setVariable("workStep", "checkIfVnfInMaintInAAI")
\r
334 execution.setVariable("failedActivity", "AAI")
\r
335 logDebug('Entered ' + method, isDebugLogEnabled)
\r
338 def transactionLoggingUuid = UUID.randomUUID().toString()
\r
339 AAIRestClientImpl client = new AAIRestClientImpl()
\r
340 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
\r
341 aaiValidator.setClient(client)
\r
342 def vnfId = execution.getVariable("vnfId")
\r
343 boolean isInMaint = aaiValidator.isVNFLocked(vnfId, transactionLoggingUuid)
\r
344 logDebug("isInMaint result: " + isInMaint, isDebugLogEnabled)
\r
345 execution.setVariable('isVnfInMaintenance', isInMaint)
\r
348 execution.setVariable("errorCode", "1003")
\r
349 execution.setVariable("errorText", "VNF is in maintenance in A&AI")
\r
353 logDebug('Exited ' + method, isDebugLogEnabled)
\r
354 } catch (BpmnError e) {
\r
356 } catch (Exception e) {
\r
357 logError('Caught exception in ' + method, e)
\r
358 execution.setVariable("errorCode", "1002")
\r
359 execution.setVariable("errorText", e.getMessage())
\r
360 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfVnfInMaintInAAI(): ' + e.getMessage())
\r
366 * Check if this VNF's pservers are locked in A&AI.
\r
369 * @param execution The flow's execution instance.
\r
371 public void checkIfPserversInMaintInAAI(DelegateExecution execution) {
\r
372 def method = getClass().getSimpleName() + '.checkIfPserversInMaintInAAI(' +
\r
373 'execution=' + execution.getId() +
\r
375 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
376 execution.setVariable('errorCode', "0")
\r
377 logDebug('Entered ' + method, isDebugLogEnabled)
\r
378 execution.setVariable("workStep", "checkIfPserversInMaintInAAI")
\r
379 execution.setVariable("failedActivity", "AAI")
\r
382 def transactionLoggingUuid = UUID.randomUUID().toString()
\r
383 AAIRestClientImpl client = new AAIRestClientImpl()
\r
384 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
\r
385 aaiValidator.setClient(client)
\r
386 def vnfId = execution.getVariable("vnfId")
\r
387 boolean areLocked = aaiValidator.isPhysicalServerLocked(vnfId, transactionLoggingUuid)
\r
388 logDebug("areLocked result: " + areLocked, isDebugLogEnabled)
\r
389 execution.setVariable('arePserversLocked', areLocked)
\r
392 execution.setVariable("errorCode", "1003")
\r
393 execution.setVariable("errorText", "pServers are locked in A&AI")
\r
396 logDebug('Exited ' + method, isDebugLogEnabled)
\r
397 } catch (BpmnError e) {
\r
399 } catch (Exception e) {
\r
400 logError('Caught exception in ' + method, e)
\r
401 execution.setVariable("errorCode", "1002")
\r
402 execution.setVariable("errorText", e.getMessage())
\r
403 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfPserversInMaintInAAI(): ' + e.getMessage())
\r
408 * Set inMaint flag for this VNF to the specified value in A&AI.
\r
411 * @param execution The flow's execution instance.
\r
412 * @param inMaint The boolean value of the flag to set
\r
414 public void setVnfInMaintFlagInAAI(DelegateExecution execution, boolean inMaint) {
\r
415 def method = getClass().getSimpleName() + '.setVnfInMaintFlagInAAI(' +
\r
416 'execution=' + execution.getId() +
\r
418 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
419 execution.setVariable('errorCode', "0")
\r
420 logDebug('Entered ' + method, isDebugLogEnabled)
\r
422 execution.setVariable("workStep", "setVnfInMaintFlagInAAI")
\r
425 execution.setVariable("workStep", "unsetVnfInMaintFlagInAAI")
\r
427 execution.setVariable("failedActivity", "AAI")
\r
430 def transactionLoggingUuid = UUID.randomUUID().toString()
\r
431 AAIRestClientImpl client = new AAIRestClientImpl()
\r
432 AAIUpdatorImpl aaiUpdator = new AAIUpdatorImpl()
\r
433 aaiUpdator.setClient(client)
\r
434 def vnfId = execution.getVariable("vnfId")
\r
436 aaiUpdator.updateVnfToLocked(vnfId, transactionLoggingUuid)
\r
437 execution.setVariable("rollbackSetVnfInMaintenanceFlag", true)
\r
440 aaiUpdator.updateVnfToUnLocked(vnfId, transactionLoggingUuid)
\r
443 logDebug('Exited ' + method, isDebugLogEnabled)
\r
444 } catch (BpmnError e) {
\r
446 } catch (Exception e) {
\r
447 logError('Caught exception in ' + method, e)
\r
448 execution.setVariable("errorCode", "1002")
\r
449 execution.setVariable("errorText", e.getMessage())
\r
450 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in setVnfInMaintFlagInAAI(): ' + e.getMessage())
\r
457 * Prepare DoUpdateVnfAndModules call.
\r
460 * @param execution The flow's execution instance.
\r
462 public void prepDoUpdateVnfAndModules(DelegateExecution execution) {
\r
463 def method = getClass().getSimpleName() + '.prepDoUpdateVnfAndModules(' +
\r
464 'execution=' + execution.getId() +
\r
466 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
467 execution.setVariable('errorCode', "0")
\r
468 logDebug('Entered ' + method, isDebugLogEnabled)
\r
469 execution.setVariable("workStep", "doUpdateVnfAndModules")
\r
470 execution.setVariable("failedActivity", "MSO Update VNF")
\r
471 logDebug('Exited ' + method, isDebugLogEnabled)
\r
477 * Handle Abort disposition from RainyDayHandler
\r
479 * @param execution The flow's execution instance.
\r
481 public void abortProcessing(DelegateExecution execution) {
\r
482 def method = getClass().getSimpleName() + '.abortProcessing(' +
\r
483 'execution=' + execution.getId() +
\r
485 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
486 logDebug('Entered ' + method, isDebugLogEnabled)
\r
488 def errorText = execution.getVariable("errorText")
\r
489 def errorCode = execution.getVariable("errorCode")
\r
491 exceptionUtil.buildAndThrowWorkflowException(execution, errorCode as Integer, errorText)
\r