1a62ad60f9831db3a2112251432ad4a4d5339ec0
[so.git] / bpmn / so-bpmn-infrastructure-common / src / main / groovy / org / onap / so / bpmn / infrastructure / scripts / UpdateVnfInfra.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
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
13  * 
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=========================================================
20  */
21
22 package org.onap.so.bpmn.infrastructure.scripts
23
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
42
43 public class UpdateVnfInfra extends VnfCmBase {
44     private static final Logger logger = LoggerFactory.getLogger(UpdateVnfInfra.class)
45
46         ExceptionUtil exceptionUtil = new ExceptionUtil()
47         JsonUtils jsonUtils = new JsonUtils()   
48         def prefix = "UPDVnfI_"
49
50         /**
51          * Initialize the flow's variables.
52          *
53          * @param execution The flow's execution instance.
54          */
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)
78         }
79
80         /**
81          * Check for missing elements in the received request.
82          *
83          * @param execution The flow's execution instance.
84          */
85         public void preProcessRequest(DelegateExecution execution) {
86                 def method = getClass().getSimpleName() + '.preProcessRequest(' +
87                 'execution=' + execution.getId() +
88                 ')'
89                 initProcessVariables(execution)
90
91         logger.trace('Entered {}', method)
92
93                 initProcessVariables(execution)         
94
95                 def incomingRequest = execution.getVariable('bpmnRequest')
96
97         logger.debug("Incoming Infra Request: {}", incomingRequest)
98                 try {
99                         def jsonSlurper = new JsonSlurper()
100                         def jsonOutput = new JsonOutput()
101                         Map reqMap = jsonSlurper.parseText(incomingRequest)
102             logger.debug(" Request is in JSON format.")
103                         
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)
111                         
112                         def asdcServiceModelVersion = ''
113                         def serviceModelInfo = null
114                         
115                         def relatedInstanceList = reqMap.requestDetails?.relatedInstanceList
116                                                 
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)
126                                         }
127                                         
128                                 }
129                         }               
130                         
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)
138                         
139                         def vnfType = execution.getVariable('vnfType')
140                         execution.setVariable('vnfType', vnfType)
141                         
142
143                         def controllerType = reqMap.requestDetails?.requestParameters?.controllerType
144                         execution.setVariable('controllerType', controllerType)
145
146             logger.debug('Controller Type: {}', controllerType)
147                         
148                         def userParams = reqMap.requestDetails?.requestParameters?.userParams                                   
149                         
150                         Map<String, String> userParamsMap = [:]
151                         if (userParams != null) {
152                                 userParams.each { userParam ->
153                                         userParamsMap.put(userParam.name, userParam.value.toString())
154                                 }                                                       
155                         }
156
157             logger.debug('Processed user params: {}', userParamsMap)
158                         
159                         execution.setVariable('vfModuleInputParams', userParamsMap)                     
160                                                 
161                         def requestId = execution.getVariable("mso-request-id")
162                         execution.setVariable('requestId', requestId)
163                         execution.setVariable('msoRequestId', requestId)
164                         
165                         
166                         def vnfName = reqMap.requestDetails?.requestInfo?.instanceName ?: null
167                         execution.setVariable('vnfName', vnfName)
168                         
169                         def requestorId = reqMap.requestDetails?.requestInfo?.requestorId ?: null
170                         execution.setVariable('requestorId', requestorId)
171                         
172                         def usePreload = reqMap.requestDetails?.requestParameters?.usePreload
173                         execution.setVariable('usePreload', usePreload)
174                         
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)
182                         
183                         def globalSubscriberId = reqMap.requestDetails?.subscriberInfo?.globalSubscriberId ?: ''
184                         execution.setVariable('globalSubscriberId', globalSubscriberId)
185                         
186                         execution.setVariable('sdncVersion', '1702')
187
188                         execution.setVariable("UpdateVnfInfraSuccessIndicator", false)
189                                                 
190
191                         
192                         def source = reqMap.requestDetails?.requestInfo?.source
193                         execution.setVariable("source", source)
194                         
195                         //For Completion Handler & Fallout Handler
196                         String requestInfo =
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>
201                                    </request-info>"""
202                         
203                         execution.setVariable("requestInfo", requestInfo)
204
205             logger.debug('RequestInfo: {}', execution.getVariable("requestInfo"))
206             logger.trace('Exited {}', method)
207
208                 }
209                 catch(groovy.json.JsonException je) {
210             logger.debug(" Request is not in JSON format.")
211                         exceptionUtil.buildAndThrowWorkflowException(execution, 5000, "Invalid request format")
212
213                 }
214                 catch(Exception e) {
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)
219                 }       
220         }
221
222         /**
223          * Prepare and send the sychronous response for this flow.
224          *
225          * @param execution The flow's execution instance.
226          */
227         public void sendSynchResponse(DelegateExecution execution) {
228                 def method = getClass().getSimpleName() + '.sendSynchResponse(' +
229                         'execution=' + execution.getId() +
230                         ')'
231
232         logger.trace('Entered {}', method)
233
234                 try {
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()) {
240                                 progress = '0'
241                         }
242                         def startTime = getNodeTextForce(requestInfo, 'start-time')
243                         if (startTime.isEmpty()) {
244                                 startTime = System.currentTimeMillis()
245                         }
246
247                         // RESTResponse (for API Handler (APIH) Reply Task)
248                         def vnfId = execution.getVariable("vnfId")
249                         String synchResponse = """{"requestReferences":{"instanceId":"${vnfId}","requestId":"${requestId}"}}""".trim()
250
251                         sendWorkflowResponse(execution, 200, synchResponse)
252
253             logger.trace('Exited {}', method)
254                 } catch (BpmnError e) {
255                         throw 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())
260                 }
261         }
262         
263         
264
265         /**
266          * Get VnfResource decomposition object for this VNF.
267          *      
268          *
269          * @param execution The flow's execution instance.
270          */
271         public void getVnfResourceDecomposition(DelegateExecution execution) {
272                 def method = getClass().getSimpleName() + '.getVnfResourceDecomposition(' +
273                         'execution=' + execution.getId() +
274                         ')'
275
276         logger.trace('Entered {}', method)
277
278                 try {
279                         ServiceDecomposition serviceDecomposition = execution.getVariable("serviceDecomposition")
280                         String vnfModelInvariantUuid = execution.getVariable('vnfModelInvariantUuid')
281             logger.debug("vnfModelInvariantUuid: {}", vnfModelInvariantUuid)
282                         List<VnfResource> vnfResources = serviceDecomposition.getVnfResources()
283                         
284                         for (i in 0..vnfResources.size()-1) {
285                                 ModelInfo modelInfo = vnfResources[i].getModelInfo()
286                                 String modelInvariantUuidFromDecomposition = modelInfo.getModelInvariantUuid()
287                 logger.debug("modelInvariantUuidFromDecomposition: {}", modelInvariantUuidFromDecomposition)
288
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())
295                                         break
296                                 }
297                                 else {
298                                         //exception!
299                                 }
300                                 
301                         }
302
303             logger.trace('Exited {}', method)
304                 } catch (BpmnError e) {
305                         throw 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())
310                 }
311         }
312         
313         /**
314          * Check if this VNF is already in maintenance in A&AI.
315          *
316          *
317          * @param execution The flow's execution instance.
318          */
319         public void checkIfVnfInMaintInAAI(DelegateExecution execution) {
320                 def method = getClass().getSimpleName() + '.checkIfVnfInMaintInAAI(' +
321                         'execution=' + execution.getId() +
322                         ')'
323
324                 execution.setVariable('errorCode', "0")
325                 execution.setVariable("workStep", "checkIfVnfInMaintInAAI")
326                 execution.setVariable("failedActivity", "AAI")
327         logger.trace('Entered {}', method)
328
329                 try {
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)
337                         
338                         if (isInMaint) {
339                                 execution.setVariable("errorCode", "1003")
340                                 execution.setVariable("errorText", "VNF is in maintenance in A&AI")
341                         }
342
343
344             logger.trace('Exited {}', method)
345                 } catch (BpmnError e) {
346                         throw 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())
353                 }
354         }
355         
356         
357         /**
358          * Check if this VNF's pservers are locked in A&AI.
359          *
360          *
361          * @param execution The flow's execution instance.
362          */
363         public void checkIfPserversInMaintInAAI(DelegateExecution execution) {
364                 def method = getClass().getSimpleName() + '.checkIfPserversInMaintInAAI(' +
365                         'execution=' + execution.getId() +
366                         ')'
367
368                 execution.setVariable('errorCode', "0")
369         logger.trace('Entered {}', method)
370                 execution.setVariable("workStep", "checkIfPserversInMaintInAAI")
371                 execution.setVariable("failedActivity", "AAI")
372
373                 try {
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)
381                         
382                         if (areLocked) {
383                                 execution.setVariable("errorCode", "1003")
384                                 execution.setVariable("errorText", "pServers are locked in A&AI")
385                         }
386
387             logger.trace('Exited {}', method)
388                 } catch (BpmnError e) {
389                         throw 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())
396                 }
397         }
398         
399         /**
400          * Set inMaint flag for this VNF to the specified value in A&AI.
401          *
402          *
403          * @param execution The flow's execution instance.
404          * @param inMaint The boolean value of the flag to set
405          */
406         public void setVnfInMaintFlagInAAI(DelegateExecution execution, boolean inMaint) {
407                 def method = getClass().getSimpleName() + '.setVnfInMaintFlagInAAI(' +
408                         'execution=' + execution.getId() +
409                         ')'
410
411                 execution.setVariable('errorCode', "0")
412         logger.trace('Entered {}', method)
413                 if (inMaint) {
414                         execution.setVariable("workStep", "setVnfInMaintFlagInAAI")
415                 }
416                 else {
417                         execution.setVariable("workStep", "unsetVnfInMaintFlagInAAI")
418                 }
419                 execution.setVariable("failedActivity", "AAI")
420
421                 try {
422                         AAIRestClientImpl client = new AAIRestClientImpl()
423                         AAIUpdatorImpl aaiUpdator = new AAIUpdatorImpl()
424                         aaiUpdator.setClient(client)
425                         def vnfId = execution.getVariable("vnfId")
426                         if (inMaint) {
427                                 aaiUpdator.updateVnfToLocked(vnfId)
428                                 execution.setVariable("rollbackSetVnfInMaintenanceFlag", true)
429                         }
430                         else {
431                                 aaiUpdator.updateVnfToUnLocked(vnfId)
432                         }
433
434             logger.trace('Exited {}', method)
435                 } catch (BpmnError e) {
436                         throw 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())
442                 }
443         }
444         
445         
446
447         /**
448         * Prepare DoUpdateVnfAndModules call.
449         *
450         *
451         * @param execution The flow's execution instance.
452         */
453    public void prepDoUpdateVnfAndModules(DelegateExecution execution) {
454            def method = getClass().getSimpleName() + '.prepDoUpdateVnfAndModules(' +
455                    'execution=' + execution.getId() +
456                    ')'
457
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)
463    }
464         
465         
466         /**
467          * Handle Abort disposition from RainyDayHandler
468          *
469          * @param execution The flow's execution instance.       
470          */
471         public void abortProcessing(DelegateExecution execution) {
472                 def method = getClass().getSimpleName() + '.abortProcessing(' +
473                         'execution=' + execution.getId() +
474                         ')'
475
476                 logger.trace('Entered ' + method)
477                 
478                 def errorText = execution.getVariable("errorText")
479                 def errorCode = execution.getVariable("errorCode")
480                 
481                 exceptionUtil.buildAndThrowWorkflowException(execution, errorCode as Integer, errorText)
482         }
483         
484         
485
486         
487 }