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 groovy.json.JsonOutput
 
  25 import groovy.json.JsonSlurper
 
  26 import org.camunda.bpm.engine.delegate.BpmnError
 
  27 import org.camunda.bpm.engine.delegate.DelegateExecution
 
  28 import org.onap.appc.client.lcm.model.Action
 
  29 import org.onap.so.bpmn.common.scripts.ExceptionUtil
 
  30 import org.onap.so.bpmn.common.scripts.MsoUtils
 
  31 import org.onap.so.bpmn.core.domain.ModelInfo
 
  32 import org.onap.so.bpmn.core.domain.ServiceDecomposition
 
  33 import org.onap.so.bpmn.core.domain.VnfResource
 
  34 import org.onap.so.bpmn.core.json.JsonUtils
 
  35 import org.onap.so.client.aai.AAIRestClientImpl
 
  36 import org.onap.so.client.aai.AAIUpdatorImpl
 
  37 import org.onap.so.client.aai.AAIValidatorImpl
 
  38 import org.onap.so.logger.MessageEnum
 
  39 import org.onap.so.logger.MsoLogger
 
  40 import org.slf4j.Logger
 
  41 import org.slf4j.LoggerFactory
 
  43 public class UpdateVnfInfra extends VnfCmBase {
 
  44     private static final Logger logger = LoggerFactory.getLogger(UpdateVnfInfra.class)
 
  46         ExceptionUtil exceptionUtil = new ExceptionUtil()
 
  47         JsonUtils jsonUtils = new JsonUtils()   
 
  48         def prefix = "UPDVnfI_"
 
  51          * Initialize the flow's variables.
 
  53          * @param execution The flow's execution instance.
 
  55         public void initProcessVariables(DelegateExecution execution) {
 
  56                 execution.setVariable('prefix', 'UPDVnfI_')
 
  57                 execution.setVariable('Request', null)          
 
  58                 execution.setVariable('source', null)
 
  59                 execution.setVariable('vnfInputs', null)                        
 
  60                 execution.setVariable('tenantId', null)         
 
  61                 execution.setVariable('vnfParams', null)                
 
  62                 execution.setVariable('controllerType', null)           
 
  63                 execution.setVariable('UpdateVnfSuccessIndicator', false)
 
  64                 execution.setVariable('serviceType', null)
 
  65                 execution.setVariable('nfRole', null)
 
  66                 execution.setVariable('currentActivity', 'UPDVnfI')
 
  67                 execution.setVariable('workStep', null)
 
  68                 execution.setVariable('failedActivity', null)
 
  69                 execution.setVariable('errorCode', "0")
 
  70                 execution.setVariable('errorText', null)
 
  71                 execution.setVariable('healthCheckIndex0', 0)
 
  72                 execution.setVariable('healthCheckIndex1', 1)
 
  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                         execution.setVariable("isVidRequest", "true")
 
 105                         execution.setVariable('serviceType', 'Mobility')
 
 106                         execution.setVariable('actionLock', Action.Lock)
 
 107                         execution.setVariable('actionUnlock', Action.Unlock)
 
 108                         execution.setVariable('actionHealthCheck', Action.HealthCheck)
 
 109                         execution.setVariable('actionStart', Action.Start)
 
 110                         execution.setVariable('actionStop', Action.Stop)
 
 112                         def asdcServiceModelVersion = ''
 
 113                         def serviceModelInfo = null
 
 115                         def relatedInstanceList = reqMap.requestDetails?.relatedInstanceList
 
 117                         if (relatedInstanceList != null) {
 
 118                                 relatedInstanceList.each {
 
 119                                         if (it.relatedInstance.modelInfo?.modelType == 'service') {
 
 120                         logger.debug("PROCESSING SERVICE INFO")
 
 121                                                 asdcServiceModelVersion = it.relatedInstance.modelInfo?.modelVersion
 
 122                                                 serviceModelInfo = jsonOutput.toJson(it.relatedInstance.modelInfo)
 
 123                         logger.debug("ServiceModelInfo: {}", serviceModelInfo)
 
 124                                                 def modelInvariant = jsonUtils.getJsonValue(serviceModelInfo, "modelInvariantUuid")
 
 125                         logger.debug("modelInvariant: {}", modelInvariant)
 
 131                         execution.setVariable('asdcServiceModelVersion', asdcServiceModelVersion)
 
 132                         execution.setVariable('serviceModelInfo', serviceModelInfo)
 
 133                         def vnfModelInfo = jsonOutput.toJson(reqMap.requestDetails?.modelInfo)
 
 134                         execution.setVariable('vnfModelInfo', vnfModelInfo)
 
 135                         def vnfModelInvariantUuid = jsonUtils.getJsonValue(vnfModelInfo, "modelInvariantUuid")
 
 136                         execution.setVariable('vnfModelInvariantUuid', vnfModelInvariantUuid)
 
 137             logger.debug("vnfModelInvariantUuid: {}", vnfModelInvariantUuid)
 
 139                         def vnfType = execution.getVariable('vnfType')
 
 140                         execution.setVariable('vnfType', vnfType)
 
 143                         def controllerType = reqMap.requestDetails?.requestParameters?.controllerType
 
 144                         execution.setVariable('controllerType', controllerType)
 
 146             logger.debug('Controller Type: {}', controllerType)
 
 148                         def userParams = reqMap.requestDetails?.requestParameters?.userParams                                   
 
 150                         Map<String, String> userParamsMap = [:]
 
 151                         if (userParams != null) {
 
 152                                 userParams.each { userParam ->
 
 153                                         userParamsMap.put(userParam.name, userParam.value.toString())
 
 157             logger.debug('Processed user params: {}', userParamsMap)
 
 159                         execution.setVariable('vfModuleInputParams', userParamsMap)                     
 
 161                         def requestId = execution.getVariable("mso-request-id")
 
 162                         execution.setVariable('requestId', requestId)
 
 163                         execution.setVariable('msoRequestId', requestId)
 
 166                         def vnfName = reqMap.requestDetails?.requestInfo?.instanceName ?: null
 
 167                         execution.setVariable('vnfName', vnfName)
 
 169                         def requestorId = reqMap.requestDetails?.requestInfo?.requestorId ?: null
 
 170                         execution.setVariable('requestorId', requestorId)
 
 172                         def usePreload = reqMap.requestDetails?.requestParameters?.usePreload
 
 173                         execution.setVariable('usePreload', usePreload)
 
 175                         def cloudConfiguration = jsonOutput.toJson(reqMap.requestDetails?.cloudConfiguration)                   
 
 176                         def lcpCloudRegionId    = jsonUtils.getJsonValue(cloudConfiguration, "lcpCloudRegionId")
 
 177                         execution.setVariable('lcpCloudRegionId', lcpCloudRegionId)
 
 178                         def cloudOwner  = jsonUtils.getJsonValue(cloudConfiguration, "cloudOwner")
 
 179                         execution.setVariable('cloudOwner', cloudOwner)
 
 180                         def tenantId = jsonUtils.getJsonValue(cloudConfiguration, "tenantId")
 
 181                         execution.setVariable('tenantId', tenantId)
 
 183                         def globalSubscriberId = reqMap.requestDetails?.subscriberInfo?.globalSubscriberId ?: ''
 
 184                         execution.setVariable('globalSubscriberId', globalSubscriberId)
 
 186                         execution.setVariable('sdncVersion', '1702')
 
 188                         execution.setVariable("UpdateVnfInfraSuccessIndicator", false)
 
 192                         def source = reqMap.requestDetails?.requestInfo?.source
 
 193                         execution.setVariable("source", source)
 
 195                         //For Completion Handler & Fallout Handler
 
 197                         """<request-info xmlns="http://org.onap/so/infra/vnf-request/v1">
 
 198                                         <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
 
 199                                         <action>UPDATE</action>
 
 200                                         <source>${MsoUtils.xmlEscape(source)}</source>
 
 203                         execution.setVariable("requestInfo", requestInfo)
 
 205             logger.debug('RequestInfo: {}', execution.getVariable("requestInfo"))
 
 206             logger.trace('Exited {}', method)
 
 209                 catch(groovy.json.JsonException je) {
 
 210             logger.debug(" Request is not in JSON format.")
 
 211                         exceptionUtil.buildAndThrowWorkflowException(execution, 5000, "Invalid request format")
 
 215                         String restFaultMessage = e.getMessage()
 
 216             logger.error("{} {} {} Exception Encountered - \n{}\n ", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
 
 217                     MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError.getValue(), restFaultMessage, e)
 
 218                         exceptionUtil.buildAndThrowWorkflowException(execution, 5000, restFaultMessage)
 
 223          * Prepare and send the sychronous response for this flow.
 
 225          * @param execution The flow's execution instance.
 
 227         public void sendSynchResponse(DelegateExecution execution) {
 
 228                 def method = getClass().getSimpleName() + '.sendSynchResponse(' +
 
 229                         'execution=' + execution.getId() +
 
 232         logger.trace('Entered {}', method)
 
 235                         def requestInfo = execution.getVariable('requestInfo')
 
 236                         def requestId = execution.getVariable('requestId')
 
 237                         def source = execution.getVariable('source')
 
 238                         def progress = getNodeTextForce(requestInfo, 'progress')
 
 239                         if (progress.isEmpty()) {
 
 242                         def startTime = getNodeTextForce(requestInfo, 'start-time')
 
 243                         if (startTime.isEmpty()) {
 
 244                                 startTime = System.currentTimeMillis()
 
 247                         // RESTResponse (for API Handler (APIH) Reply Task)
 
 248                         def vnfId = execution.getVariable("vnfId")
 
 249                         String synchResponse = """{"requestReferences":{"instanceId":"${vnfId}","requestId":"${requestId}"}}""".trim()
 
 251                         sendWorkflowResponse(execution, 200, synchResponse)
 
 253             logger.trace('Exited {}', method)
 
 254                 } catch (BpmnError e) {
 
 256                 } catch (Exception e) {
 
 257             logger.error("{} {} {} Caught exception in {}\n ", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
 
 258                     MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError.getValue(), method, e)
 
 259                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in sendResponse(): ' + e.getMessage())
 
 266          * Get VnfResource decomposition object for this VNF.
 
 269          * @param execution The flow's execution instance.
 
 271         public void getVnfResourceDecomposition(DelegateExecution execution) {
 
 272                 def method = getClass().getSimpleName() + '.getVnfResourceDecomposition(' +
 
 273                         'execution=' + execution.getId() +
 
 276         logger.trace('Entered {}', method)
 
 279                         ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
 
 280                         String vnfModelInvariantUuid = execution.getVariable('vnfModelInvariantUuid')
 
 281             logger.debug("vnfModelInvariantUuid: {}", vnfModelInvariantUuid)
 
 282                         List<VnfResource> vnfResources = serviceDecomposition.getVnfResources()
 
 284                         for (i in 0..vnfResources.size()-1) {
 
 285                                 ModelInfo modelInfo = vnfResources[i].getModelInfo()
 
 286                                 String modelInvariantUuidFromDecomposition = modelInfo.getModelInvariantUuid()
 
 287                 logger.debug("modelInvariantUuidFromDecomposition: {}", modelInvariantUuidFromDecomposition)
 
 289                                 if (vnfModelInvariantUuid.equals(modelInvariantUuidFromDecomposition)) {
 
 290                                         VnfResource vnfResourceDecomposition = vnfResources[i]
 
 291                                         execution.setVariable('vnfResourceDecomposition', vnfResourceDecomposition)
 
 292                                         def nfRole = vnfResourceDecomposition.getNfRole()                                       
 
 293                                         execution.setVariable('nfRole', nfRole)
 
 294                     logger.debug("vnfResourceDecomposition: {}", vnfResourceDecomposition.toJsonString())
 
 303             logger.trace('Exited {}', method)
 
 304                 } catch (BpmnError e) {
 
 306                 } catch (Exception e) {
 
 307             logger.error("{} {} {} Caught exception in {}\n ", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
 
 308                     MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError.getValue(), method, e)
 
 309                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in getVnfResourceDecomposition(): ' + e.getMessage())
 
 314          * Check if this VNF is already in maintenance in A&AI.
 
 317          * @param execution The flow's execution instance.
 
 319         public void checkIfVnfInMaintInAAI(DelegateExecution execution) {
 
 320                 def method = getClass().getSimpleName() + '.checkIfVnfInMaintInAAI(' +
 
 321                         'execution=' + execution.getId() +
 
 324                 execution.setVariable('errorCode', "0")
 
 325                 execution.setVariable("workStep", "checkIfVnfInMaintInAAI")
 
 326                 execution.setVariable("failedActivity", "AAI")
 
 327         logger.trace('Entered {}', method)
 
 330                         AAIRestClientImpl client = new AAIRestClientImpl()
 
 331                         AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
 
 332                         aaiValidator.setClient(client)
 
 333                         def vnfId = execution.getVariable("vnfId")
 
 334                         boolean isInMaint = aaiValidator.isVNFLocked(vnfId)
 
 335             logger.debug("isInMaint result: {}", isInMaint)
 
 336                         execution.setVariable('isVnfInMaintenance', isInMaint)
 
 339                                 execution.setVariable("errorCode", "1003")
 
 340                                 execution.setVariable("errorText", "VNF is in maintenance in A&AI")
 
 344             logger.trace('Exited {}', method)
 
 345                 } catch (BpmnError e) {
 
 347                 } catch (Exception e) {
 
 348             logger.error("{} {} {} Caught exception in {}\n ", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
 
 349                     MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError.getValue(), method, e)
 
 350                         execution.setVariable("errorCode", "1002")
 
 351                         execution.setVariable("errorText", e.getMessage())
 
 352                         //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfVnfInMaintInAAI(): ' + e.getMessage())
 
 358          * Check if this VNF's pservers are locked in A&AI.
 
 361          * @param execution The flow's execution instance.
 
 363         public void checkIfPserversInMaintInAAI(DelegateExecution execution) {
 
 364                 def method = getClass().getSimpleName() + '.checkIfPserversInMaintInAAI(' +
 
 365                         'execution=' + execution.getId() +
 
 368                 execution.setVariable('errorCode', "0")
 
 369         logger.trace('Entered {}', method)
 
 370                 execution.setVariable("workStep", "checkIfPserversInMaintInAAI")
 
 371                 execution.setVariable("failedActivity", "AAI")
 
 374                         AAIRestClientImpl client = new AAIRestClientImpl()
 
 375                         AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
 
 376                         aaiValidator.setClient(client)
 
 377                         def vnfId = execution.getVariable("vnfId")                      
 
 378                         boolean areLocked = aaiValidator.isPhysicalServerLocked(vnfId)
 
 379             logger.debug("areLocked result: {}", areLocked)
 
 380                         execution.setVariable('arePserversLocked', areLocked)
 
 383                                 execution.setVariable("errorCode", "1003")
 
 384                                 execution.setVariable("errorText", "pServers are locked in A&AI")
 
 387             logger.trace('Exited {}', method)
 
 388                 } catch (BpmnError e) {
 
 390                 } catch (Exception e) {
 
 391             logger.error("{} {} {} Caught exception in {}\n ", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
 
 392                     MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError.getValue(), method, e)
 
 393                         execution.setVariable("errorCode", "1002")
 
 394                         execution.setVariable("errorText", e.getMessage())
 
 395                         //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfPserversInMaintInAAI(): ' + e.getMessage())
 
 400          * Set inMaint flag for this VNF to the specified value in A&AI.
 
 403          * @param execution The flow's execution instance.
 
 404          * @param inMaint The boolean value of the flag to set
 
 406         public void setVnfInMaintFlagInAAI(DelegateExecution execution, boolean inMaint) {
 
 407                 def method = getClass().getSimpleName() + '.setVnfInMaintFlagInAAI(' +
 
 408                         'execution=' + execution.getId() +
 
 411                 execution.setVariable('errorCode', "0")
 
 412         logger.trace('Entered {}', method)
 
 414                         execution.setVariable("workStep", "setVnfInMaintFlagInAAI")
 
 417                         execution.setVariable("workStep", "unsetVnfInMaintFlagInAAI")
 
 419                 execution.setVariable("failedActivity", "AAI")
 
 422                         AAIRestClientImpl client = new AAIRestClientImpl()
 
 423                         AAIUpdatorImpl aaiUpdator = new AAIUpdatorImpl()
 
 424                         aaiUpdator.setClient(client)
 
 425                         def vnfId = execution.getVariable("vnfId")
 
 427                                 aaiUpdator.updateVnfToLocked(vnfId)
 
 428                                 execution.setVariable("rollbackSetVnfInMaintenanceFlag", true)
 
 431                                 aaiUpdator.updateVnfToUnLocked(vnfId)
 
 434             logger.trace('Exited {}', method)
 
 435                 } catch (BpmnError e) {
 
 437                 } catch (Exception e) {
 
 438             logger.error("{} {} {} Caught exception in {}\n ", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
 
 439                     MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError.getValue(), method, e)
 
 440                         execution.setVariable("errorCode", "1002")
 
 441                         execution.setVariable("errorText", e.getMessage())
 
 448         * Prepare DoUpdateVnfAndModules call.
 
 451         * @param execution The flow's execution instance.
 
 453    public void prepDoUpdateVnfAndModules(DelegateExecution execution) {
 
 454            def method = getClass().getSimpleName() + '.prepDoUpdateVnfAndModules(' +
 
 455                    'execution=' + execution.getId() +
 
 458            execution.setVariable('errorCode', "0")
 
 459        logger.trace('Entered {}', method)
 
 460            execution.setVariable("workStep", "doUpdateVnfAndModules")
 
 461            execution.setVariable("failedActivity", "MSO Update VNF")
 
 462        logger.trace('Exited {}', method)
 
 467          * Handle Abort disposition from RainyDayHandler
 
 469          * @param execution The flow's execution instance.       
 
 471         public void abortProcessing(DelegateExecution execution) {
 
 472                 def method = getClass().getSimpleName() + '.abortProcessing(' +
 
 473                         'execution=' + execution.getId() +
 
 476                 logger.trace('Entered ' + method)
 
 478                 def errorText = execution.getVariable("errorText")
 
 479                 def errorCode = execution.getVariable("errorCode")
 
 481                 exceptionUtil.buildAndThrowWorkflowException(execution, errorCode as Integer, errorText)