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('UpdateVnfSuccessIndicator', false)
\r
79 execution.setVariable('serviceType', null)
\r
80 execution.setVariable('nfRole', null)
\r
81 execution.setVariable('currentActivity', 'UPDVnfI')
\r
82 execution.setVariable('workStep', null)
\r
83 execution.setVariable('failedActivity', null)
\r
84 execution.setVariable('errorCode', "0")
\r
85 execution.setVariable('errorText', null)
\r
86 execution.setVariable('healthCheckIndex0', 0)
\r
87 execution.setVariable('healthCheckIndex1', 1)
\r
88 execution.setVariable("rollbackSetClosedLoopDisabledFlag", false)
\r
89 execution.setVariable("rollbackVnfStop", false)
\r
90 execution.setVariable("rollbackVnfLock", false)
\r
91 execution.setVariable("rollbackQuiesceTraffic", false)
\r
92 execution.setVariable("rollbackSetVnfInMaintenanceFlag", false)
\r
96 * Check for missing elements in the received request.
\r
98 * @param execution The flow's execution instance.
\r
100 public void preProcessRequest(DelegateExecution execution) {
\r
101 def method = getClass().getSimpleName() + '.preProcessRequest(' +
\r
102 'execution=' + execution.getId() +
\r
104 initProcessVariables(execution)
\r
105 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
106 logDebug('Entered ' + method, isDebugLogEnabled)
\r
108 initProcessVariables(execution)
\r
110 def incomingRequest = execution.getVariable('bpmnRequest')
\r
112 utils.log("DEBUG", "Incoming Infra Request: " + incomingRequest, isDebugLogEnabled)
\r
114 def jsonSlurper = new JsonSlurper()
\r
115 def jsonOutput = new JsonOutput()
\r
116 Map reqMap = jsonSlurper.parseText(incomingRequest)
\r
117 utils.log("DEBUG", " Request is in JSON format.", isDebugLogEnabled)
\r
119 execution.setVariable("isVidRequest", "true")
\r
120 execution.setVariable('serviceType', 'Mobility')
\r
121 execution.setVariable('actionLock', Action.Lock)
\r
122 execution.setVariable('actionUnlock', Action.Unlock)
\r
123 execution.setVariable('actionHealthCheck', Action.HealthCheck)
\r
124 execution.setVariable('actionStart', Action.Start)
\r
125 execution.setVariable('actionStop', Action.Stop)
\r
127 def asdcServiceModelVersion = ''
\r
128 def serviceModelInfo = null
\r
130 def relatedInstanceList = reqMap.requestDetails?.relatedInstanceList
\r
132 if (relatedInstanceList != null) {
\r
133 relatedInstanceList.each {
\r
134 if (it.relatedInstance.modelInfo?.modelType == 'service') {
\r
135 utils.log("DEBUG", "PROCESSING SERVICE INFO", isDebugLogEnabled)
\r
136 asdcServiceModelVersion = it.relatedInstance.modelInfo?.modelVersion
\r
137 serviceModelInfo = jsonOutput.toJson(it.relatedInstance.modelInfo)
\r
138 utils.log("DEBUG", "ServiceModelInfo: " + serviceModelInfo, isDebugLogEnabled)
\r
139 def modelInvariant = jsonUtils.getJsonValue(serviceModelInfo, "modelInvariantUuid")
\r
140 utils.log("DEBUG", "modelInvariant: " + modelInvariant, isDebugLogEnabled)
\r
146 execution.setVariable('asdcServiceModelVersion', asdcServiceModelVersion)
\r
147 execution.setVariable('serviceModelInfo', serviceModelInfo)
\r
148 def vnfModelInfo = jsonOutput.toJson(reqMap.requestDetails?.modelInfo)
\r
149 execution.setVariable('vnfModelInfo', vnfModelInfo)
\r
150 def vnfModelInvariantUuid = jsonUtils.getJsonValue(vnfModelInfo, "modelInvariantUuid")
\r
151 execution.setVariable('vnfModelInvariantUuid', vnfModelInvariantUuid)
\r
152 logDebug("vnfModelInvariantUuid: " + vnfModelInvariantUuid, isDebugLogEnabled)
\r
154 def vnfType = execution.getVariable('vnfType')
\r
155 execution.setVariable('vnfType', vnfType)
\r
157 def userParams = reqMap.requestDetails?.requestParameters?.userParams
\r
159 Map<String, String> userParamsMap = [:]
\r
160 if (userParams != null) {
\r
161 userParams.each { userParam ->
\r
162 userParamsMap.put(userParam.name, userParam.value.toString())
\r
166 utils.log("DEBUG", 'Processed user params: ' + userParamsMap, isDebugLogEnabled)
\r
168 execution.setVariable('vfModuleInputParams', userParamsMap)
\r
170 def requestId = execution.getVariable("mso-request-id")
\r
171 execution.setVariable('requestId', requestId)
\r
172 execution.setVariable('msoRequestId', requestId)
\r
175 def vnfName = reqMap.requestDetails?.requestInfo?.instanceName ?: null
\r
176 execution.setVariable('vnfName', vnfName)
\r
178 def requestorId = reqMap.requestDetails?.requestInfo?.requestorId ?: null
\r
179 execution.setVariable('requestorId', requestorId)
\r
181 def usePreload = reqMap.requestDetails?.requestParameters?.usePreload
\r
182 execution.setVariable('usePreload', usePreload)
\r
184 def cloudConfiguration = reqMap.requestDetails?.cloudConfiguration
\r
185 def lcpCloudRegionId = cloudConfiguration.lcpCloudRegionId
\r
186 execution.setVariable('lcpCloudRegionId', lcpCloudRegionId)
\r
187 def tenantId = cloudConfiguration.tenantId
\r
188 execution.setVariable('tenantId', tenantId)
\r
190 def globalSubscriberId = reqMap.requestDetails?.subscriberInfo?.globalSubscriberId ?: ''
\r
191 execution.setVariable('globalSubscriberId', globalSubscriberId)
\r
193 execution.setVariable('sdncVersion', '1702')
\r
195 execution.setVariable("UpdateVnfInfraSuccessIndicator", false)
\r
197 execution.setVariable("isDebugLogEnabled", isDebugLogEnabled)
\r
199 def source = reqMap.requestDetails?.requestInfo?.source
\r
200 execution.setVariable("source", source)
\r
202 //For Completion Handler & Fallout Handler
\r
203 String requestInfo =
\r
204 """<request-info xmlns="http://org.openecomp/mso/infra/vnf-request/v1">
\r
205 <request-id>${requestId}</request-id>
\r
206 <action>UPDATE</action>
\r
207 <source>${source}</source>
\r
210 execution.setVariable("requestInfo", requestInfo)
\r
212 logDebug('RequestInfo: ' + execution.getVariable("requestInfo"), isDebugLogEnabled)
\r
214 logDebug('Exited ' + method, isDebugLogEnabled)
\r
217 catch(groovy.json.JsonException je) {
\r
218 utils.log("DEBUG", " Request is not in JSON format.", isDebugLogEnabled)
\r
219 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, "Invalid request format")
\r
222 catch(Exception e) {
\r
223 String restFaultMessage = e.getMessage()
\r
224 utils.log("ERROR", " Exception Encountered - " + "\n" + restFaultMessage, isDebugLogEnabled)
\r
225 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, restFaultMessage)
\r
230 * Prepare and send the sychronous response for this flow.
\r
232 * @param execution The flow's execution instance.
\r
234 public void sendSynchResponse(DelegateExecution execution) {
\r
235 def method = getClass().getSimpleName() + '.sendSynchResponse(' +
\r
236 'execution=' + execution.getId() +
\r
238 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
239 logDebug('Entered ' + method, isDebugLogEnabled)
\r
243 def requestInfo = execution.getVariable('requestInfo')
\r
244 def requestId = execution.getVariable('requestId')
\r
245 def source = execution.getVariable('source')
\r
246 def progress = getNodeTextForce(requestInfo, 'progress')
\r
247 if (progress.isEmpty()) {
\r
250 def startTime = getNodeTextForce(requestInfo, 'start-time')
\r
251 if (startTime.isEmpty()) {
\r
252 startTime = System.currentTimeMillis()
\r
255 // RESTResponse (for API Handler (APIH) Reply Task)
\r
256 def vnfId = execution.getVariable("vnfId")
\r
257 String synchResponse = """{"requestReferences":{"instanceId":"${vnfId}","requestId":"${requestId}"}}""".trim()
\r
259 sendWorkflowResponse(execution, 200, synchResponse)
\r
261 logDebug('Exited ' + method, isDebugLogEnabled)
\r
262 } catch (BpmnError e) {
\r
264 } catch (Exception e) {
\r
265 logError('Caught exception in ' + method, e)
\r
266 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in sendResponse(): ' + e.getMessage())
\r
273 * Get VnfResource decomposition object for this VNF.
\r
276 * @param execution The flow's execution instance.
\r
278 public void getVnfResourceDecomposition(DelegateExecution execution) {
\r
279 def method = getClass().getSimpleName() + '.getVnfResourceDecomposition(' +
\r
280 'execution=' + execution.getId() +
\r
282 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
283 logDebug('Entered ' + method, isDebugLogEnabled)
\r
286 ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
\r
287 String vnfModelInvariantUuid = execution.getVariable('vnfModelInvariantUuid')
\r
288 logDebug("vnfModelInvariantUuid: " + vnfModelInvariantUuid, isDebugLogEnabled)
\r
289 List<VnfResource> vnfResources = serviceDecomposition.getServiceVnfs()
\r
291 for (i in 0..vnfResources.size()-1) {
\r
292 ModelInfo modelInfo = vnfResources[i].getModelInfo()
\r
293 String modelInvariantUuidFromDecomposition = modelInfo.getModelInvariantUuid()
\r
294 logDebug("modelInvariantUuidFromDecomposition: " + modelInvariantUuidFromDecomposition, isDebugLogEnabled)
\r
296 if (vnfModelInvariantUuid.equals(modelInvariantUuidFromDecomposition)) {
\r
297 VnfResource vnfResourceDecomposition = vnfResources[i]
\r
298 execution.setVariable('vnfResourceDecomposition', vnfResourceDecomposition)
\r
299 def nfRole = vnfResourceDecomposition.getNfRole()
\r
300 execution.setVariable('nfRole', nfRole)
\r
301 logDebug("vnfResourceDecomposition: " + vnfResourceDecomposition.toJsonString(), isDebugLogEnabled)
\r
310 logDebug('Exited ' + method, isDebugLogEnabled)
\r
311 } catch (BpmnError e) {
\r
313 } catch (Exception e) {
\r
314 logError('Caught exception in ' + method, e)
\r
315 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in getVnfResourceDecomposition(): ' + e.getMessage())
\r
320 * Check if this VNF is already in maintenance in A&AI.
\r
323 * @param execution The flow's execution instance.
\r
325 public void checkIfVnfInMaintInAAI(DelegateExecution execution) {
\r
326 def method = getClass().getSimpleName() + '.checkIfVnfInMaintInAAI(' +
\r
327 'execution=' + execution.getId() +
\r
329 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
330 execution.setVariable('errorCode', "0")
\r
331 execution.setVariable("workStep", "checkIfVnfInMaintInAAI")
\r
332 execution.setVariable("failedActivity", "AAI")
\r
333 logDebug('Entered ' + method, isDebugLogEnabled)
\r
336 def transactionLoggingUuid = UUID.randomUUID().toString()
\r
337 AAIRestClientImpl client = new AAIRestClientImpl()
\r
338 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
\r
339 aaiValidator.setClient(client)
\r
340 def vnfId = execution.getVariable("vnfId")
\r
341 boolean isInMaint = aaiValidator.isVNFLocked(vnfId, transactionLoggingUuid)
\r
342 logDebug("isInMaint result: " + isInMaint, isDebugLogEnabled)
\r
343 execution.setVariable('isVnfInMaintenance', isInMaint)
\r
346 execution.setVariable("errorCode", "1003")
\r
347 execution.setVariable("errorText", "VNF is in maintenance in A&AI")
\r
351 logDebug('Exited ' + method, isDebugLogEnabled)
\r
352 } catch (BpmnError e) {
\r
354 } catch (Exception e) {
\r
355 logError('Caught exception in ' + method, e)
\r
356 execution.setVariable("errorCode", "1002")
\r
357 execution.setVariable("errorText", e.getMessage())
\r
358 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfVnfInMaintInAAI(): ' + e.getMessage())
\r
364 * Check if this VNF's pservers are locked in A&AI.
\r
367 * @param execution The flow's execution instance.
\r
369 public void checkIfPserversInMaintInAAI(DelegateExecution execution) {
\r
370 def method = getClass().getSimpleName() + '.checkIfPserversInMaintInAAI(' +
\r
371 'execution=' + execution.getId() +
\r
373 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
374 execution.setVariable('errorCode', "0")
\r
375 logDebug('Entered ' + method, isDebugLogEnabled)
\r
376 execution.setVariable("workStep", "checkIfPserversInMaintInAAI")
\r
377 execution.setVariable("failedActivity", "AAI")
\r
380 def transactionLoggingUuid = UUID.randomUUID().toString()
\r
381 AAIRestClientImpl client = new AAIRestClientImpl()
\r
382 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
\r
383 aaiValidator.setClient(client)
\r
384 def vnfId = execution.getVariable("vnfId")
\r
385 boolean areLocked = aaiValidator.isPhysicalServerLocked(vnfId, transactionLoggingUuid)
\r
386 logDebug("areLocked result: " + areLocked, isDebugLogEnabled)
\r
387 execution.setVariable('arePserversLocked', areLocked)
\r
390 execution.setVariable("errorCode", "1003")
\r
391 execution.setVariable("errorText", "pServers are locked in A&AI")
\r
394 logDebug('Exited ' + method, isDebugLogEnabled)
\r
395 } catch (BpmnError e) {
\r
397 } catch (Exception e) {
\r
398 logError('Caught exception in ' + method, e)
\r
399 execution.setVariable("errorCode", "1002")
\r
400 execution.setVariable("errorText", e.getMessage())
\r
401 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfPserversInMaintInAAI(): ' + e.getMessage())
\r
406 * Set inMaint flag for this VNF to the specified value in A&AI.
\r
409 * @param execution The flow's execution instance.
\r
410 * @param inMaint The boolean value of the flag to set
\r
412 public void setVnfInMaintFlagInAAI(DelegateExecution execution, boolean inMaint) {
\r
413 def method = getClass().getSimpleName() + '.setVnfInMaintFlagInAAI(' +
\r
414 'execution=' + execution.getId() +
\r
416 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
417 execution.setVariable('errorCode', "0")
\r
418 logDebug('Entered ' + method, isDebugLogEnabled)
\r
420 execution.setVariable("workStep", "setVnfInMaintFlagInAAI")
\r
423 execution.setVariable("workStep", "unsetVnfInMaintFlagInAAI")
\r
425 execution.setVariable("failedActivity", "AAI")
\r
428 def transactionLoggingUuid = UUID.randomUUID().toString()
\r
429 AAIRestClientImpl client = new AAIRestClientImpl()
\r
430 AAIUpdatorImpl aaiUpdator = new AAIUpdatorImpl()
\r
431 aaiUpdator.setClient(client)
\r
432 def vnfId = execution.getVariable("vnfId")
\r
434 aaiUpdator.updateVnfToLocked(vnfId, transactionLoggingUuid)
\r
435 execution.setVariable("rollbackSetVnfInMaintenanceFlag", true)
\r
438 aaiUpdator.updateVnfToUnLocked(vnfId, transactionLoggingUuid)
\r
441 logDebug('Exited ' + method, isDebugLogEnabled)
\r
442 } catch (BpmnError e) {
\r
444 } catch (Exception e) {
\r
445 logError('Caught exception in ' + method, e)
\r
446 execution.setVariable("errorCode", "1002")
\r
447 execution.setVariable("errorText", e.getMessage())
\r
448 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in setVnfInMaintFlagInAAI(): ' + e.getMessage())
\r
455 * Prepare DoUpdateVnfAndModules call.
\r
458 * @param execution The flow's execution instance.
\r
460 public void prepDoUpdateVnfAndModules(DelegateExecution execution) {
\r
461 def method = getClass().getSimpleName() + '.prepDoUpdateVnfAndModules(' +
\r
462 'execution=' + execution.getId() +
\r
464 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
465 execution.setVariable('errorCode', "0")
\r
466 logDebug('Entered ' + method, isDebugLogEnabled)
\r
467 execution.setVariable("workStep", "doUpdateVnfAndModules")
\r
468 execution.setVariable("failedActivity", "MSO Update VNF")
\r
469 logDebug('Exited ' + method, isDebugLogEnabled)
\r
475 * Handle Abort disposition from RainyDayHandler
\r
477 * @param execution The flow's execution instance.
\r
479 public void abortProcessing(DelegateExecution execution) {
\r
480 def method = getClass().getSimpleName() + '.abortProcessing(' +
\r
481 'execution=' + execution.getId() +
\r
483 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
\r
484 logDebug('Entered ' + method, isDebugLogEnabled)
\r
486 def errorText = execution.getVariable("errorText")
\r
487 def errorCode = execution.getVariable("errorCode")
\r
489 exceptionUtil.buildAndThrowWorkflowException(execution, errorCode as Integer, errorText)
\r