2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Modifications Copyright (c) 2019 Samsung
8 * ================================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.so.bpmn.infrastructure.scripts
24 import org.camunda.bpm.engine.delegate.BpmnError
25 import org.camunda.bpm.engine.delegate.DelegateExecution
26 import org.onap.appc.client.lcm.model.Action
27 import org.onap.logging.filter.base.ErrorCode
28 import org.onap.so.bpmn.common.scripts.ExceptionUtil
29 import org.onap.so.bpmn.common.scripts.MsoUtils
30 import org.onap.so.bpmn.core.json.JsonUtils
31 import org.onap.aaiclient.client.aai.*
32 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
33 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
34 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
35 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder
36 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types
37 import org.onap.so.logger.MessageEnum
38 import org.slf4j.Logger
39 import org.slf4j.LoggerFactory
40 import groovy.json.JsonOutput
41 import groovy.json.JsonSlurper
43 public class VnfConfigUpdate extends VnfCmBase {
44 private static final Logger logger = LoggerFactory.getLogger( VnfConfigUpdate.class)
46 ExceptionUtil exceptionUtil = new ExceptionUtil()
47 JsonUtils jsonUtils = new JsonUtils()
48 def prefix = "VnfIPU_"
51 * Initialize the flow's variables.
53 * @param execution The flow's execution instance.
55 public void initProcessVariables(DelegateExecution execution) {
56 execution.setVariable('prefix', 'VnfCU_')
57 execution.setVariable('Request', null)
58 execution.setVariable('source', null)
59 execution.setVariable('controllerType', null)
60 execution.setVariable('UpdateVnfSuccessIndicator', false)
61 execution.setVariable('serviceType', null)
62 execution.setVariable('nfRole', null)
63 execution.setVariable('currentActivity', 'VnfCU')
64 execution.setVariable('workStep', null)
65 execution.setVariable('failedActivity', null)
66 execution.setVariable('errorCode', "0")
67 execution.setVariable('errorText', null)
68 execution.setVariable('healthCheckIndex0', 0)
69 execution.setVariable('healthCheckIndex1', 1)
70 execution.setVariable('maxRetryCount', 3)
71 execution.setVariable('retryCount', 0)
72 execution.setVariable("lcpCloudRegionId", null)
73 execution.setVariable("rollbackSetClosedLoopDisabledFlag", false)
74 execution.setVariable("rollbackVnfStop", false)
75 execution.setVariable("rollbackVnfLock", false)
76 execution.setVariable("rollbackQuiesceTraffic", false)
77 execution.setVariable("rollbackSetVnfInMaintenanceFlag", false)
81 * Check for missing elements in the received request.
83 * @param execution The flow's execution instance.
85 public void preProcessRequest(DelegateExecution execution) {
86 def method = getClass().getSimpleName() + '.preProcessRequest(' +
87 'execution=' + execution.getId() +
89 initProcessVariables(execution)
91 logger.trace('Entered {}', method)
93 initProcessVariables(execution)
95 def incomingRequest = execution.getVariable('bpmnRequest')
97 logger.debug("Incoming Infra Request: {}", incomingRequest)
99 def jsonSlurper = new JsonSlurper()
100 def jsonOutput = new JsonOutput()
101 Map reqMap = jsonSlurper.parseText(incomingRequest)
102 logger.debug(" Request is in JSON format.")
104 def serviceInstanceId = execution.getVariable('serviceInstanceId')
105 def vnfId = execution.getVariable('vnfId')
107 execution.setVariable('serviceInstanceId', serviceInstanceId)
108 execution.setVariable('vnfId', vnfId)
109 execution.setVariable('serviceType', 'Mobility')
110 execution.setVariable('payload', "")
111 execution.setVariable('actionHealthCheck', Action.HealthCheck)
112 execution.setVariable('actionConfigModify', Action.ConfigModify)
115 def controllerType = reqMap.requestDetails?.requestParameters?.controllerType
116 execution.setVariable('controllerType', controllerType)
118 logger.debug('Controller Type: {}', controllerType)
120 def payload = reqMap.requestDetails?.requestParameters?.payload
121 execution.setVariable('payload', payload)
123 logger.debug('Processed payload: {}', payload)
125 def requestId = execution.getVariable("mso-request-id")
126 execution.setVariable('requestId', requestId)
127 execution.setVariable('msoRequestId', requestId)
129 def requestorId = reqMap.requestDetails?.requestInfo?.requestorId ?: null
130 execution.setVariable('requestorId', requestorId)
132 execution.setVariable('sdncVersion', '1702')
134 execution.setVariable("UpdateVnfInfraSuccessIndicator", false)
138 def source = reqMap.requestDetails?.requestInfo?.source
139 execution.setVariable("source", source)
141 //For Completion Handler & Fallout Handler
143 """<request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
144 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
145 <action>UPDATE</action>
146 <source>${MsoUtils.xmlEscape(source)}</source>
149 execution.setVariable("requestInfo", requestInfo)
151 logger.debug('RequestInfo: {}', execution.getVariable("requestInfo"))
153 logger.trace('Exited {}', method)
156 catch(groovy.json.JsonException je) {
157 logger.debug(" Request is not in JSON format.")
158 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, "Invalid request format")
162 String restFaultMessage = e.getMessage()
163 logger.error("{} {} Exception Encountered - \n {} \n ", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
164 ErrorCode.UnknownError.getValue(), restFaultMessage, e)
165 exceptionUtil.buildAndThrowWorkflowException(execution, 5000, restFaultMessage)
170 * Prepare and send the sychronous response for this flow.
172 * @param execution The flow's execution instance.
174 public void sendSynchResponse(DelegateExecution execution) {
175 def method = getClass().getSimpleName() + '.sendSynchResponse(' +
176 'execution=' + execution.getId() +
179 logger.trace('Entered {}', method)
183 def requestInfo = execution.getVariable('requestInfo')
184 def requestId = execution.getVariable('requestId')
185 def source = execution.getVariable('source')
186 def progress = getNodeTextForce(requestInfo, 'progress')
187 if (progress.isEmpty()) {
190 def startTime = getNodeTextForce(requestInfo, 'start-time')
191 if (startTime.isEmpty()) {
192 startTime = System.currentTimeMillis()
195 // RESTResponse (for API Handler (APIH) Reply Task)
196 def vnfId = execution.getVariable("vnfId")
197 String synchResponse = """{"requestReferences":{"instanceId":"${vnfId}","requestId":"${requestId}"}}""".trim()
199 sendWorkflowResponse(execution, 200, synchResponse)
201 logger.trace('Exited {}', method)
202 } catch (BpmnError e) {
204 } catch (Exception e) {
205 logger.error("{} {} Caught exception in {}\n ", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
206 ErrorCode.UnknownError.getValue(), method, e)
207 exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in sendResponse(): ' + e.getMessage())
213 * Check if this VNF is already in maintenance in A&AI.
216 * @param execution The flow's execution instance.
218 public void checkIfVnfInMaintInAAI(DelegateExecution execution) {
219 def method = getClass().getSimpleName() + '.checkIfVnfInMaintInAAI(' +
220 'execution=' + execution.getId() +
223 execution.setVariable('errorCode', "0")
224 execution.setVariable("workStep", "checkIfVnfInMaintInAAI")
225 execution.setVariable("failedActivity", "AAI")
226 logger.trace('Entered {}', method)
229 AAIRestClientImpl client = new AAIRestClientImpl()
230 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
231 aaiValidator.setClient(client)
232 def vnfId = execution.getVariable("vnfId")
233 boolean isInMaint = aaiValidator.isVNFLocked(vnfId)
234 logger.debug("isInMaint result: {}", isInMaint)
235 execution.setVariable('isVnfInMaintenance', isInMaint)
238 execution.setVariable("errorCode", "1003")
239 execution.setVariable("errorText", "VNF is in maintenance in A&AI")
242 logger.trace('Exited {}', method)
243 } catch (BpmnError e) {
245 } catch (Exception e) {
246 logger.error("{} {} Caught exception in {}\n ", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
247 ErrorCode.UnknownError.getValue(), method, e)
248 execution.setVariable("errorCode", "1002")
249 execution.setVariable("errorText", e.getMessage())
250 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfVnfInMaintInAAI(): ' + e.getMessage())
256 * Check if this VNF's pservers are locked in A&AI.
259 * @param execution The flow's execution instance.
261 public void checkIfPserversInMaintInAAI(DelegateExecution execution) {
262 def method = getClass().getSimpleName() + '.checkIfPserversInMaintInAAI(' +
263 'execution=' + execution.getId() +
266 execution.setVariable('errorCode', "0")
267 logger.trace('Entered {}', method)
268 execution.setVariable("workStep", "checkIfPserversInMaintInAAI")
269 execution.setVariable("failedActivity", "AAI")
272 AAIRestClientImpl client = new AAIRestClientImpl()
273 AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
274 aaiValidator.setClient(client)
275 def vnfId = execution.getVariable("vnfId")
276 boolean areLocked = aaiValidator.isPhysicalServerLocked(vnfId)
277 logger.debug("areLocked result: {}", areLocked)
278 execution.setVariable('arePserversLocked', areLocked)
281 execution.setVariable("errorCode", "1003")
282 execution.setVariable("errorText", "pServers are locked in A&AI")
285 logger.trace('Exited {}', method)
286 } catch (BpmnError e) {
288 } catch (Exception e) {
289 logger.error("{} {} Caught exception in {}\n ", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
290 ErrorCode.UnknownError.getValue(), method, e)
291 execution.setVariable("errorCode", "1002")
292 execution.setVariable("errorText", e.getMessage())
293 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfPserversInMaintInAAI(): ' + e.getMessage())
298 * Set inMaint flag for this VNF to the specified value in A&AI.
301 * @param execution The flow's execution instance.
302 * @param inMaint The boolean value of the flag to set
304 public void setVnfInMaintFlagInAAI(DelegateExecution execution, boolean inMaint) {
305 def method = getClass().getSimpleName() + '.setVnfInMaintFlagInAAI(' +
306 'execution=' + execution.getId() +
309 execution.setVariable('errorCode', "0")
310 logger.trace('Entered {}', method)
312 execution.setVariable("workStep", "setVnfInMaintFlagInAAI")
313 execution.setVariable("rollbackSetVnfInMaintenanceFlag", true)
316 execution.setVariable("workStep", "unsetVnfInMaintFlagInAAI")
318 execution.setVariable("failedActivity", "AAI")
321 AAIRestClientImpl client = new AAIRestClientImpl()
322 AAIUpdatorImpl aaiUpdator = new AAIUpdatorImpl()
323 aaiUpdator.setClient(client)
324 def vnfId = execution.getVariable("vnfId")
326 aaiUpdator.updateVnfToLocked(vnfId)
327 execution.setVariable("rollbackSetVnfInMaintenanceFlag", true)
330 aaiUpdator.updateVnfToUnLocked(vnfId)
333 logger.trace('Exited {}', method)
334 } catch (BpmnError e) {
336 } catch (Exception e) {
337 logger.error("{} {} Caught exception in {}\n ", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
338 ErrorCode.UnknownError.getValue(), method, e)
339 execution.setVariable("errorCode", "1002")
340 execution.setVariable("errorText", e.getMessage())
345 * Check if VF Closed Loop Disabled in A&AI.
348 * @param execution The flow's execution instance.
350 public void checkIfClosedLoopDisabledInAAI(DelegateExecution execution) {
351 def method = getClass().getSimpleName() + '.checkIfClosedLoopDisabledInAAI(' +
352 'execution=' + execution.getId() +
355 execution.setVariable('errorCode', "0")
356 execution.setVariable("workStep", "checkClosedLoopDisabledFlagInAAI")
357 execution.setVariable("failedActivity", "AAI")
358 logger.trace('Entered {}', method)
361 def transactionLoggingUuid = UUID.randomUUID().toString()
362 def vnfId = execution.getVariable("vnfId")
363 logger.debug("vnfId is: {}", vnfId)
364 AAIResourcesClient client = new AAIResourcesClient()
365 AAIResourceUri genericVnfUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId))
366 AAIResultWrapper aaiRW = client.get(genericVnfUri)
367 Map<String, Object> result = aaiRW.asMap()
368 boolean isClosedLoopDisabled = result.getOrDefault("is-closed-loop-disabled", false)
370 logger.debug("isClosedLoopDisabled result: {}", isClosedLoopDisabled)
371 execution.setVariable('isClosedLoopDisabled', isClosedLoopDisabled)
373 if (isClosedLoopDisabled) {
374 execution.setVariable("errorCode", "1004")
375 execution.setVariable("errorText", "closedLoop is disabled in A&AI")
378 logger.trace('Exited {}', method)
379 } catch (BpmnError e) {
381 } catch (Exception e) {
382 logger.error("{} {} Caught exception in {}\n ", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
383 ErrorCode.UnknownError.getValue(), method, e)
384 execution.setVariable("errorCode", "1002")
385 execution.setVariable("errorText", e.getMessage())
386 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfVnfInMaintInAAI(): ' + e.getMessage())
391 * Set VF Closed Loop Disabled Flag in A&AI.
394 * @param execution The flow's execution instance.
396 public void setClosedLoopDisabledInAAI(DelegateExecution execution, boolean setDisabled) {
397 def method = getClass().getSimpleName() + '.setClosedLoopDisabledInAAI(' +
398 'execution=' + execution.getId() +
401 execution.setVariable('errorCode', "0")
403 execution.setVariable("workStep", "setClosedLoopDisabledFlagInAAI")
404 execution.setVariable("rollbackSetClosedLoopDisabledFlag", true)
407 execution.setVariable("workStep", "unsetClosedLoopDisabledFlagInAAI")
410 execution.setVariable("failedActivity", "AAI")
411 logger.trace('Entered {}', method)
414 def transactionLoggingUuid = UUID.randomUUID().toString()
415 def vnfId = execution.getVariable("vnfId")
416 AAIResourcesClient client = new AAIResourcesClient()
417 AAIResourceUri genericVnfUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.network().genericVnf(vnfId))
419 Map<String, Boolean> request = new HashMap<>()
420 request.put("is-closed-loop-disabled", setDisabled)
421 client.update(genericVnfUri, request)
422 logger.debug("set isClosedLoop to: {}", setDisabled)
424 logger.trace('Exited {}', method)
425 } catch (BpmnError e) {
427 } catch (Exception e) {
428 logger.error("{} {} Caught exception in {}\n ", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
429 ErrorCode.UnknownError.getValue(), method, e)
430 execution.setVariable("errorCode", "1002")
431 execution.setVariable("errorText", e.getMessage())
432 //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfVnfInMaintInAAI(): ' + e.getMessage())
438 * Handle Abort disposition from RainyDayHandler
440 * @param execution The flow's execution instance.
442 public void abortProcessing(DelegateExecution execution) {
443 def method = getClass().getSimpleName() + '.abortProcessing(' +
444 'execution=' + execution.getId() +
447 logger.trace('Entered {}', method)
449 def errorText = execution.getVariable("errorText")
450 def errorCode = execution.getVariable("errorCode")
452 exceptionUtil.buildAndThrowWorkflowException(execution, errorCode as Integer, errorText)
456 * Increment Retry Count for Current Work Step
458 * @param execution The flow's execution instance.
460 public void incrementRetryCount(DelegateExecution execution) {
461 def method = getClass().getSimpleName() + '.incrementRetryCount(' +
462 'execution=' + execution.getId() +
465 logger.trace('Entered {}', method)
467 String retryCountVariableName = execution.getVariable("workStep") + "RetryCount"
468 execution.setVariable("retryCountVariableName", retryCountVariableName)
470 def retryCountVariable = execution.getVariable(retryCountVariableName)
473 if (retryCountVariable != null) {
474 retryCount = (int) retryCountVariable
479 execution.setVariable(retryCountVariableName, retryCount)
481 logger.debug("value of {} is {}", retryCountVariableName, retryCount)
482 logger.trace('Exited {}', method)