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.openecomp.mso.bpmn.infrastructure.scripts
22 import groovy.json.JsonOutput
23 import groovy.json.JsonSlurper
24 import groovy.util.Node
25 import groovy.util.XmlParser;
26 import groovy.xml.QName
28 import java.beans.MetaData.java_lang_Class_PersistenceDelegate
29 import java.io.Serializable;
30 import java.util.UUID;
31 import org.openecomp.mso.bpmn.common.scripts.ExceptionUtil
32 import org.camunda.bpm.engine.delegate.BpmnError
33 import org.camunda.bpm.engine.impl.cmd.AbstractSetVariableCmd
34 import org.camunda.bpm.engine.delegate.DelegateExecution
35 import org.openecomp.mso.rest.APIResponse
36 import org.openecomp.mso.rest.RESTClient
37 import org.openecomp.mso.rest.RESTConfig
38 import org.openecomp.mso.bpmn.common.scripts.AbstractServiceTaskProcessor;
39 import org.openecomp.mso.bpmn.common.scripts.VidUtils;
40 import org.openecomp.mso.bpmn.core.RollbackData
41 import org.openecomp.mso.bpmn.core.WorkflowException
42 import org.openecomp.mso.bpmn.common.scripts.ExceptionUtil
43 import org.openecomp.mso.bpmn.core.json.JsonUtils
44 import org.openecomp.mso.bpmn.core.domain.ModelInfo
45 import org.openecomp.mso.bpmn.core.domain.ServiceDecomposition
46 import org.openecomp.mso.bpmn.core.domain.VnfResource
47 import org.openecomp.mso.client.aai.*
49 import org.openecomp.mso.client.appc.ApplicationControllerClient;
50 import org.openecomp.mso.client.appc.ApplicationControllerSupport;
51 import org.openecomp.mso.client.aai.AAIResourcesClient
52 import org.openecomp.mso.client.aai.entities.AAIResultWrapper
53 import org.openecomp.mso.client.aai.entities.uri.AAIUri
54 import org.openecomp.mso.client.aai.entities.uri.AAIUriFactory
55 import org.onap.appc.client.lcm.model.Action;
56 import org.onap.appc.client.lcm.model.ActionIdentifiers;
57 import org.onap.appc.client.lcm.model.LockInput
58 import org.onap.appc.client.lcm.model.UnlockInput
59 import org.onap.appc.client.lcm.model.HealthCheckInput
60 import org.onap.appc.client.lcm.model.StartInput
61 import org.onap.appc.client.lcm.model.StopInput
62 import org.onap.appc.client.lcm.model.Flags
63 import org.onap.appc.client.lcm.model.Status
66 public class VnfConfigUpdate extends VnfCmBase {
68 ExceptionUtil exceptionUtil = new ExceptionUtil()
69 JsonUtils jsonUtils = new JsonUtils()
70 def prefix = "VnfIPU_"
73 * Initialize the flow's variables.
75 * @param execution The flow's execution instance.
77 public void initProcessVariables(DelegateExecution execution) {
78 execution.setVariable('prefix', 'VnfCU_')
79 execution.setVariable('Request', null)
80 execution.setVariable('source', null)
81 execution.setVariable('UpdateVnfSuccessIndicator', false)
82 execution.setVariable('serviceType', null)
83 execution.setVariable('nfRole', null)
84 execution.setVariable('currentActivity', 'VnfCU')
85 execution.setVariable('workStep', null)
86 execution.setVariable('failedActivity', null)
87 execution.setVariable('errorCode', "0")
88 execution.setVariable('errorText', null)
89 execution.setVariable('healthCheckIndex0', 0)
90 execution.setVariable('healthCheckIndex1', 1)
91 execution.setVariable('maxRetryCount', 3)
92 execution.setVariable('retryCount', 0)
93 execution.setVariable("lcpCloudRegionId", null)
94 execution.setVariable("rollbackSetClosedLoopDisabledFlag", false)
95 execution.setVariable("rollbackVnfStop", false)
96 execution.setVariable("rollbackVnfLock", false)
97 execution.setVariable("rollbackQuiesceTraffic", false)
98 execution.setVariable("rollbackSetVnfInMaintenanceFlag", false)
102 * Check for missing elements in the received request.
104 * @param execution The flow's execution instance.
106 public void preProcessRequest(DelegateExecution execution) {
107 def method = getClass().getSimpleName() + '.preProcessRequest(' +
108 'execution=' + execution.getId() +
110 initProcessVariables(execution)
111 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
112 logDebug('Entered ' + method, isDebugLogEnabled)
114 initProcessVariables(execution)
116 def incomingRequest = execution.getVariable('bpmnRequest')
118 utils.log("DEBUG", "Incoming Infra Request: " + incomingRequest, isDebugLogEnabled)
120 def jsonSlurper = new JsonSlurper()
121 def jsonOutput = new JsonOutput()
122 Map reqMap = jsonSlurper.parseText(incomingRequest)
123 utils.log("DEBUG", " Request is in JSON format.", isDebugLogEnabled)
125 def serviceInstanceId = execution.getVariable('serviceInstanceId')
126 def vnfId = execution.getVariable('vnfId')
128 execution.setVariable('serviceInstanceId', serviceInstanceId)
129 execution.setVariable('vnfId', vnfId)
130 execution.setVariable('serviceType', 'Mobility')
131 execution.setVariable('payload', "")
132 execution.setVariable('actionHealthCheck', Action.HealthCheck)
133 execution.setVariable('actionConfigModify', Action.ConfigModify)
135 def payload = reqMap.requestDetails?.requestParameters?.payload
136 execution.setVariable('payload', payload)
138 utils.log("DEBUG", 'Processed payload: ' + payload, isDebugLogEnabled)
140 def requestId = execution.getVariable("mso-request-id")
141 execution.setVariable('requestId', requestId)
142 execution.setVariable('msoRequestId', requestId)
144 def requestorId = reqMap.requestDetails?.requestInfo?.requestorId ?: null
145 execution.setVariable('requestorId', requestorId)
147 execution.setVariable('sdncVersion', '1702')
149 execution.setVariable("UpdateVnfInfraSuccessIndicator", false)
151 execution.setVariable("isDebugLogEnabled", isDebugLogEnabled)
153 def source = reqMap.requestDetails?.requestInfo?.source
154 execution.setVariable("source", source)
156 //For Completion Handler & Fallout Handler
158 """<request-info xmlns="http://org.openecomp/mso/infra/vnf-request/v1">
159 <request-id>${requestId}</request-id>
160 <action>UPDATE</action>
161 <source>${source}</source>
164 execution.setVariable("requestInfo", requestInfo)
166 logDebug('RequestInfo: ' + execution.getVariable("requestInfo"), isDebugLogEnabled)
168 logDebug('Exited ' + method, isDebugLogEnabled)
171 catch(groovy.json.JsonException je) {
172 utils.log("DEBUG", " Request is not in JSON format.", isDebugLogEnabled)
173 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, "Invalid request format")
177 String restFaultMessage = e.getMessage()
178 utils.log("ERROR", " Exception Encountered - " + "\n" + restFaultMessage, isDebugLogEnabled)
179 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, restFaultMessage)
184 * Prepare and send the sychronous response for this flow.
186 * @param execution The flow's execution instance.
188 public void sendSynchResponse(DelegateExecution execution) {
189 def method = getClass().getSimpleName() + '.sendSynchResponse(' +
190 'execution=' + execution.getId() +
192 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
193 logDebug('Entered ' + method, isDebugLogEnabled)
197 def requestInfo = execution.getVariable('requestInfo')
198 def requestId = execution.getVariable('requestId')
199 def source = execution.getVariable('source')
200 def progress = getNodeTextForce(requestInfo, 'progress')
201 if (progress.isEmpty()) {
204 def startTime = getNodeTextForce(requestInfo, 'start-time')
205 if (startTime.isEmpty()) {
206 startTime = System.currentTimeMillis()
209 // RESTResponse (for API Handler (APIH) Reply Task)
210 def vnfId = execution.getVariable("vnfId")
211 String synchResponse = """{"requestReferences":{"instanceId":"${vnfId}","requestId":"${requestId}"}}""".trim()
213 sendWorkflowResponse(execution, 200, synchResponse)
215 logDebug('Exited ' + method, isDebugLogEnabled)
216 } catch (BpmnError e) {
218 } catch (Exception e) {
219 logError('Caught exception in ' + method, e)
220 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in sendResponse(): ' + e.getMessage())
226 * Check if this VNF is already in maintenance in A&AI.
229 * @param execution The flow's execution instance.
231 public void checkIfVnfInMaintInAAI(DelegateExecution execution) {
232 def method = getClass().getSimpleName() + '.checkIfVnfInMaintInAAI(' +
233 'execution=' + execution.getId() +
235 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
236 execution.setVariable('errorCode', "0")
237 execution.setVariable("workStep", "checkIfVnfInMaintInAAI")
238 execution.setVariable("failedActivity", "AAI")
239 logDebug('Entered ' + method, isDebugLogEnabled)
242 def transactionLoggingUuid = UUID.randomUUID().toString()
243 AAIRestClientImpl client = new AAIRestClientImpl()
244 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
245 aaiValidator.setClient(client)
246 def vnfId = execution.getVariable("vnfId")
247 boolean isInMaint = aaiValidator.isVNFLocked(vnfId, transactionLoggingUuid)
248 logDebug("isInMaint result: " + isInMaint, isDebugLogEnabled)
249 execution.setVariable('isVnfInMaintenance', isInMaint)
252 execution.setVariable("errorCode", "1003")
253 execution.setVariable("errorText", "VNF is in maintenance in A&AI")
256 logDebug('Exited ' + method, isDebugLogEnabled)
257 } catch (BpmnError e) {
259 } catch (Exception e) {
260 logError('Caught exception in ' + method, e)
261 execution.setVariable("errorCode", "1002")
262 execution.setVariable("errorText", e.getMessage())
263 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfVnfInMaintInAAI(): ' + e.getMessage())
269 * Check if this VNF's pservers are locked in A&AI.
272 * @param execution The flow's execution instance.
274 public void checkIfPserversInMaintInAAI(DelegateExecution execution) {
275 def method = getClass().getSimpleName() + '.checkIfPserversInMaintInAAI(' +
276 'execution=' + execution.getId() +
278 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
279 execution.setVariable('errorCode', "0")
280 logDebug('Entered ' + method, isDebugLogEnabled)
281 execution.setVariable("workStep", "checkIfPserversInMaintInAAI")
282 execution.setVariable("failedActivity", "AAI")
285 def transactionLoggingUuid = UUID.randomUUID().toString()
286 AAIRestClientImpl client = new AAIRestClientImpl()
287 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
288 aaiValidator.setClient(client)
289 def vnfId = execution.getVariable("vnfId")
290 boolean areLocked = aaiValidator.isPhysicalServerLocked(vnfId, transactionLoggingUuid)
291 logDebug("areLocked result: " + areLocked, isDebugLogEnabled)
292 execution.setVariable('arePserversLocked', areLocked)
295 execution.setVariable("errorCode", "1003")
296 execution.setVariable("errorText", "pServers are locked in A&AI")
300 logDebug('Exited ' + method, isDebugLogEnabled)
301 } catch (BpmnError e) {
303 } catch (Exception e) {
304 logError('Caught exception in ' + method, e)
305 execution.setVariable("errorCode", "1002")
306 execution.setVariable("errorText", e.getMessage())
307 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfPserversInMaintInAAI(): ' + e.getMessage())
312 * Set inMaint flag for this VNF to the specified value in A&AI.
315 * @param execution The flow's execution instance.
316 * @param inMaint The boolean value of the flag to set
318 public void setVnfInMaintFlagInAAI(DelegateExecution execution, boolean inMaint) {
319 def method = getClass().getSimpleName() + '.setVnfInMaintFlagInAAI(' +
320 'execution=' + execution.getId() +
322 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
323 execution.setVariable('errorCode', "0")
324 logDebug('Entered ' + method, isDebugLogEnabled)
326 execution.setVariable("workStep", "setVnfInMaintFlagInAAI")
327 execution.setVariable("rollbackSetVnfInMaintenanceFlag", true)
330 execution.setVariable("workStep", "unsetVnfInMaintFlagInAAI")
332 execution.setVariable("failedActivity", "AAI")
335 def transactionLoggingUuid = UUID.randomUUID().toString()
336 AAIRestClientImpl client = new AAIRestClientImpl()
337 AAIUpdatorImpl aaiUpdator = new AAIUpdatorImpl()
338 aaiUpdator.setClient(client)
339 def vnfId = execution.getVariable("vnfId")
341 aaiUpdator.updateVnfToLocked(vnfId, transactionLoggingUuid)
342 execution.setVariable("rollbackSetVnfInMaintenanceFlag", true)
345 aaiUpdator.updateVnfToUnLocked(vnfId, transactionLoggingUuid)
348 logDebug('Exited ' + method, isDebugLogEnabled)
349 } catch (BpmnError e) {
351 } catch (Exception e) {
352 logError('Caught exception in ' + method, e)
353 execution.setVariable("errorCode", "1002")
354 execution.setVariable("errorText", e.getMessage())
355 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in setVnfInMaintFlagInAAI(): ' + e.getMessage())
360 * Check if VF Closed Loop Disabled in A&AI.
363 * @param execution The flow's execution instance.
365 public void checkIfClosedLoopDisabledInAAI(DelegateExecution execution) {
366 def method = getClass().getSimpleName() + '.checkIfClosedLoopDisabledInAAI(' +
367 'execution=' + execution.getId() +
369 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
370 execution.setVariable('errorCode', "0")
371 execution.setVariable("workStep", "checkClosedLoopDisabledFlagInAAI")
372 execution.setVariable("failedActivity", "AAI")
373 logDebug('Entered ' + method, isDebugLogEnabled)
376 def transactionLoggingUuid = UUID.randomUUID().toString()
377 def vnfId = execution.getVariable("vnfId")
378 logDebug("vnfId is: " + vnfId, isDebugLogEnabled)
379 AAIResourcesClient client = new AAIResourcesClient()
380 AAIUri genericVnfUri = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId)
381 AAIResultWrapper aaiRW = client.get(genericVnfUri)
382 Map<String, Object> result = aaiRW.asMap()
383 boolean isClosedLoopDisabled = result.getOrDefault("is-closed-loop-disabled", false)
385 logDebug("isClosedLoopDisabled result: " + isClosedLoopDisabled, isDebugLogEnabled)
386 execution.setVariable('isClosedLoopDisabled', isClosedLoopDisabled)
388 if (isClosedLoopDisabled) {
389 execution.setVariable("errorCode", "1004")
390 execution.setVariable("errorText", "closedLoop is disabled in A&AI")
393 logDebug('Exited ' + method, isDebugLogEnabled)
394 } catch (BpmnError e) {
396 } catch (Exception e) {
397 logError('Caught exception in ' + method, e)
398 execution.setVariable("errorCode", "1002")
399 execution.setVariable("errorText", e.getMessage())
400 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfVnfInMaintInAAI(): ' + e.getMessage())
405 * Set VF Closed Loop Disabled Flag in A&AI.
408 * @param execution The flow's execution instance.
410 public void setClosedLoopDisabledInAAI(DelegateExecution execution, boolean setDisabled) {
411 def method = getClass().getSimpleName() + '.setClosedLoopDisabledInAAI(' +
412 'execution=' + execution.getId() +
414 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
415 execution.setVariable('errorCode', "0")
417 execution.setVariable("workStep", "setClosedLoopDisabledFlagInAAI")
418 execution.setVariable("rollbackSetClosedLoopDisabledFlag", true)
421 execution.setVariable("workStep", "unsetClosedLoopDisabledFlagInAAI")
424 execution.setVariable("failedActivity", "AAI")
425 logDebug('Entered ' + method, isDebugLogEnabled)
428 def transactionLoggingUuid = UUID.randomUUID().toString()
429 def vnfId = execution.getVariable("vnfId")
430 AAIResourcesClient client = new AAIResourcesClient()
431 AAIUri genericVnfUri = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId)
433 Map<String, Boolean> request = new HashMap<>()
434 request.put("is-closed-loop-disabled", setDisabled)
435 client.update(genericVnfUri, request)
436 logDebug("set isClosedLoop to: " + setDisabled, isDebugLogEnabled)
439 logDebug('Exited ' + method, isDebugLogEnabled)
440 } catch (BpmnError e) {
442 } catch (Exception e) {
443 logError('Caught exception in ' + method, e)
444 execution.setVariable("errorCode", "1002")
445 execution.setVariable("errorText", e.getMessage())
446 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfVnfInMaintInAAI(): ' + e.getMessage())
452 * Handle Abort disposition from RainyDayHandler
454 * @param execution The flow's execution instance.
456 public void abortProcessing(DelegateExecution execution) {
457 def method = getClass().getSimpleName() + '.abortProcessing(' +
458 'execution=' + execution.getId() +
460 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
461 logDebug('Entered ' + method, isDebugLogEnabled)
463 def errorText = execution.getVariable("errorText")
464 def errorCode = execution.getVariable("errorCode")
466 exceptionUtil.buildAndThrowWorkflowException(execution, errorCode as Integer, errorText)
470 * Increment Retry Count for Current Work Step
472 * @param execution The flow's execution instance.
474 public void incrementRetryCount(DelegateExecution execution) {
475 def method = getClass().getSimpleName() + '.incrementRetryCount(' +
476 'execution=' + execution.getId() +
478 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
479 logDebug('Entered ' + method, isDebugLogEnabled)
481 String retryCountVariableName = execution.getVariable("workStep") + "RetryCount"
482 execution.setVariable("retryCountVariableName", retryCountVariableName)
484 def retryCountVariable = execution.getVariable(retryCountVariableName)
487 if (retryCountVariable != null) {
488 retryCount = (int) retryCountVariable
493 execution.setVariable(retryCountVariableName, retryCount)
495 logDebug("value of " + retryCountVariableName + " is " + retryCount, isDebugLogEnabled)
496 logDebug('Exited ' + method, isDebugLogEnabled)