Merge "Reorder modifiers"
[so.git] / bpmn / MSOInfrastructureBPMN / src / main / groovy / org / openecomp / mso / bpmn / infrastructure / scripts / VnfConfigUpdate.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
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
11  * 
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=========================================================
18  */
19
20 package org.openecomp.mso.bpmn.infrastructure.scripts
21
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
27
28 import java.io.Serializable;
29 import java.util.UUID;
30 import org.openecomp.mso.bpmn.common.scripts.ExceptionUtil
31 import org.camunda.bpm.engine.delegate.BpmnError
32 import org.camunda.bpm.engine.impl.cmd.AbstractSetVariableCmd
33 import org.camunda.bpm.engine.delegate.DelegateExecution
34 import org.openecomp.mso.rest.APIResponse
35 import org.openecomp.mso.rest.RESTClient
36 import org.openecomp.mso.rest.RESTConfig
37 import org.openecomp.mso.bpmn.common.scripts.AbstractServiceTaskProcessor;
38 import org.openecomp.mso.bpmn.common.scripts.VidUtils;
39 import org.openecomp.mso.bpmn.core.RollbackData
40 import org.openecomp.mso.bpmn.core.WorkflowException
41 import org.openecomp.mso.bpmn.core.json.JsonUtils
42 import org.openecomp.mso.bpmn.core.domain.ModelInfo
43 import org.openecomp.mso.bpmn.core.domain.ServiceDecomposition
44 import org.openecomp.mso.bpmn.core.domain.VnfResource
45 import org.openecomp.mso.client.aai.*
46
47 import org.openecomp.mso.client.appc.ApplicationControllerClient;
48 import org.openecomp.mso.client.appc.ApplicationControllerSupport;
49 import org.openecomp.mso.client.aai.AAIResourcesClient
50 import org.openecomp.mso.client.aai.entities.AAIResultWrapper
51 import org.openecomp.mso.client.aai.entities.uri.AAIUri
52 import org.openecomp.mso.client.aai.entities.uri.AAIUriFactory
53 import org.onap.appc.client.lcm.model.Action;
54 import org.onap.appc.client.lcm.model.ActionIdentifiers;
55 import org.onap.appc.client.lcm.model.LockInput
56 import org.onap.appc.client.lcm.model.UnlockInput
57 import org.onap.appc.client.lcm.model.HealthCheckInput
58 import org.onap.appc.client.lcm.model.StartInput
59 import org.onap.appc.client.lcm.model.StopInput
60 import org.onap.appc.client.lcm.model.Flags
61 import org.onap.appc.client.lcm.model.Status
62
63
64 public class VnfConfigUpdate extends VnfCmBase {
65
66         ExceptionUtil exceptionUtil = new ExceptionUtil()
67         JsonUtils jsonUtils = new JsonUtils()   
68         def prefix = "VnfIPU_"
69
70         /**
71          * Initialize the flow's variables.
72          *
73          * @param execution The flow's execution instance.
74          */
75         public void initProcessVariables(DelegateExecution execution) {
76                 execution.setVariable('prefix', 'VnfCU_')
77                 execution.setVariable('Request', null)                  
78                 execution.setVariable('source', null)
79                 execution.setVariable('controllerType', null)                   
80                 execution.setVariable('UpdateVnfSuccessIndicator', false)
81                 execution.setVariable('serviceType', null)
82                 execution.setVariable('nfRole', null)
83                 execution.setVariable('currentActivity', 'VnfCU')
84                 execution.setVariable('workStep', null)
85                 execution.setVariable('failedActivity', null)
86                 execution.setVariable('errorCode', "0")
87                 execution.setVariable('errorText', null)
88                 execution.setVariable('healthCheckIndex0', 0)
89                 execution.setVariable('healthCheckIndex1', 1)
90                 execution.setVariable('maxRetryCount', 3)
91                 execution.setVariable('retryCount', 0)
92                 execution.setVariable("lcpCloudRegionId", null)
93                 execution.setVariable("rollbackSetClosedLoopDisabledFlag", false)
94                 execution.setVariable("rollbackVnfStop", false)
95                 execution.setVariable("rollbackVnfLock", false)
96                 execution.setVariable("rollbackQuiesceTraffic", false)
97                 execution.setVariable("rollbackSetVnfInMaintenanceFlag", false)
98         }
99
100         /**
101          * Check for missing elements in the received request.
102          *
103          * @param execution The flow's execution instance.
104          */
105         public void preProcessRequest(DelegateExecution execution) {
106                 def method = getClass().getSimpleName() + '.preProcessRequest(' +
107                 'execution=' + execution.getId() +
108                 ')'
109                 initProcessVariables(execution)
110                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
111                 logDebug('Entered ' + method, isDebugLogEnabled)
112
113                 initProcessVariables(execution)         
114
115                 def incomingRequest = execution.getVariable('bpmnRequest')
116
117                 utils.log("DEBUG", "Incoming Infra Request: " + incomingRequest, isDebugLogEnabled)
118                 try {
119                         def jsonSlurper = new JsonSlurper()
120                         def jsonOutput = new JsonOutput()
121                         Map reqMap = jsonSlurper.parseText(incomingRequest)
122                         utils.log("DEBUG", " Request is in JSON format.", isDebugLogEnabled)
123
124                         def serviceInstanceId = execution.getVariable('serviceInstanceId')
125                         def vnfId = execution.getVariable('vnfId')
126                         
127                         execution.setVariable('serviceInstanceId', serviceInstanceId)
128                         execution.setVariable('vnfId', vnfId)                   
129                         execution.setVariable('serviceType', 'Mobility')
130                         execution.setVariable('payload', "")
131                         execution.setVariable('actionHealthCheck', Action.HealthCheck)
132                         execution.setVariable('actionConfigModify', Action.ConfigModify)
133                         
134                         def controllerType = reqMap.requestDetails?.requestParameters?.controllerType
135                         execution.setVariable('controllerType', controllerType)
136                         
137                         utils.log("DEBUG", 'Controller Type: ' + controllerType, isDebugLogEnabled)                     
138                         
139                         def payload = reqMap.requestDetails?.requestParameters?.payload
140                         execution.setVariable('payload', payload)
141                         
142                         utils.log("DEBUG", 'Processed payload: ' + payload, isDebugLogEnabled)
143                         
144                         def requestId = execution.getVariable("mso-request-id")
145                         execution.setVariable('requestId', requestId)
146                         execution.setVariable('msoRequestId', requestId)                        
147                         
148                         def requestorId = reqMap.requestDetails?.requestInfo?.requestorId ?: null
149                         execution.setVariable('requestorId', requestorId)
150                         
151                         execution.setVariable('sdncVersion', '1702')
152
153                         execution.setVariable("UpdateVnfInfraSuccessIndicator", false)
154                                                 
155                         execution.setVariable("isDebugLogEnabled", isDebugLogEnabled)                   
156                         
157                         def source = reqMap.requestDetails?.requestInfo?.source
158                         execution.setVariable("source", source)
159                         
160                         //For Completion Handler & Fallout Handler
161                         String requestInfo =
162                         """<request-info xmlns="http://org.openecomp/mso/infra/vnf-request/v1">
163                                         <request-id>${requestId}</request-id>
164                                         <action>UPDATE</action>
165                                         <source>${source}</source>
166                                    </request-info>"""
167                         
168                         execution.setVariable("requestInfo", requestInfo)                       
169                         
170                         logDebug('RequestInfo: ' + execution.getVariable("requestInfo"), isDebugLogEnabled)             
171                         
172                         logDebug('Exited ' + method, isDebugLogEnabled)
173
174                 }
175                 catch(groovy.json.JsonException je) {
176                         utils.log("DEBUG", " Request is not in JSON format.", isDebugLogEnabled)
177                         exceptionUtil.buildAndThrowWorkflowException(execution, 5000, "Invalid request format")
178
179                 }
180                 catch(Exception e) {
181                         String restFaultMessage = e.getMessage()
182                         utils.log("ERROR", " Exception Encountered - " + "\n" + restFaultMessage, isDebugLogEnabled)
183                         exceptionUtil.buildAndThrowWorkflowException(execution, 5000, restFaultMessage)
184                 }       
185         }
186
187         /**
188          * Prepare and send the sychronous response for this flow.
189          *
190          * @param execution The flow's execution instance.
191          */
192         public void sendSynchResponse(DelegateExecution execution) {
193                 def method = getClass().getSimpleName() + '.sendSynchResponse(' +
194                         'execution=' + execution.getId() +
195                         ')'
196                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
197                 logDebug('Entered ' + method, isDebugLogEnabled)
198
199
200                 try {
201                         def requestInfo = execution.getVariable('requestInfo')
202                         def requestId = execution.getVariable('requestId')
203                         def source = execution.getVariable('source')
204                         def progress = getNodeTextForce(requestInfo, 'progress')
205                         if (progress.isEmpty()) {
206                                 progress = '0'
207                         }
208                         def startTime = getNodeTextForce(requestInfo, 'start-time')
209                         if (startTime.isEmpty()) {
210                                 startTime = System.currentTimeMillis()
211                         }
212
213                         // RESTResponse (for API Handler (APIH) Reply Task)
214                         def vnfId = execution.getVariable("vnfId")
215                         String synchResponse = """{"requestReferences":{"instanceId":"${vnfId}","requestId":"${requestId}"}}""".trim()
216
217                         sendWorkflowResponse(execution, 200, synchResponse)
218
219                         logDebug('Exited ' + method, isDebugLogEnabled)
220                 } catch (BpmnError e) {
221                         throw e;
222                 } catch (Exception e) {
223                         logError('Caught exception in ' + method, e)
224                         exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in sendResponse(): ' + e.getMessage())
225                 }
226         }       
227         
228         
229         /**
230          * Check if this VNF is already in maintenance in A&AI.
231          *
232          *
233          * @param execution The flow's execution instance.
234          */
235         public void checkIfVnfInMaintInAAI(DelegateExecution execution) {
236                 def method = getClass().getSimpleName() + '.checkIfVnfInMaintInAAI(' +
237                         'execution=' + execution.getId() +
238                         ')'
239                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
240                 execution.setVariable('errorCode', "0")
241                 execution.setVariable("workStep", "checkIfVnfInMaintInAAI")
242                 execution.setVariable("failedActivity", "AAI")
243                 logDebug('Entered ' + method, isDebugLogEnabled)
244
245                 try {
246                         def transactionLoggingUuid = UUID.randomUUID().toString()
247                         AAIRestClientImpl client = new AAIRestClientImpl()
248                         AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
249                         aaiValidator.setClient(client)
250                         def vnfId = execution.getVariable("vnfId")
251                         boolean isInMaint = aaiValidator.isVNFLocked(vnfId, transactionLoggingUuid)
252                         logDebug("isInMaint result: " + isInMaint, isDebugLogEnabled)
253                         execution.setVariable('isVnfInMaintenance', isInMaint)
254                         
255                         if (isInMaint) {
256                                 execution.setVariable("errorCode", "1003")
257                                 execution.setVariable("errorText", "VNF is in maintenance in A&AI")
258                         }
259
260                         logDebug('Exited ' + method, isDebugLogEnabled)
261                 } catch (BpmnError e) {
262                         throw e;
263                 } catch (Exception e) {
264                         logError('Caught exception in ' + method, e)                    
265                         execution.setVariable("errorCode", "1002")
266                         execution.setVariable("errorText", e.getMessage())
267                         //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfVnfInMaintInAAI(): ' + e.getMessage())
268                 }
269         }
270         
271         
272         /**
273          * Check if this VNF's pservers are locked in A&AI.
274          *
275          *
276          * @param execution The flow's execution instance.
277          */
278         public void checkIfPserversInMaintInAAI(DelegateExecution execution) {
279                 def method = getClass().getSimpleName() + '.checkIfPserversInMaintInAAI(' +
280                         'execution=' + execution.getId() +
281                         ')'
282                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
283                 execution.setVariable('errorCode', "0")
284                 logDebug('Entered ' + method, isDebugLogEnabled)
285                 execution.setVariable("workStep", "checkIfPserversInMaintInAAI")
286                 execution.setVariable("failedActivity", "AAI")
287
288                 try {
289                         def transactionLoggingUuid = UUID.randomUUID().toString()
290                         AAIRestClientImpl client = new AAIRestClientImpl()
291                         AAIValidatorImpl aaiValidator = new AAIValidatorImpl()
292                         aaiValidator.setClient(client)
293                         def vnfId = execution.getVariable("vnfId")                      
294                         boolean areLocked = aaiValidator.isPhysicalServerLocked(vnfId, transactionLoggingUuid)
295                         logDebug("areLocked result: " + areLocked, isDebugLogEnabled)
296                         execution.setVariable('arePserversLocked', areLocked)
297                         
298                         if (areLocked) {
299                                 execution.setVariable("errorCode", "1003")
300                                 execution.setVariable("errorText", "pServers are locked in A&AI")
301                         }
302
303
304                         logDebug('Exited ' + method, isDebugLogEnabled)
305                 } catch (BpmnError e) {
306                         throw e;
307                 } catch (Exception e) {
308                         logError('Caught exception in ' + method, e)
309                         execution.setVariable("errorCode", "1002")
310                         execution.setVariable("errorText", e.getMessage())
311                         //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfPserversInMaintInAAI(): ' + e.getMessage())
312                 }
313         }
314         
315         /**
316          * Set inMaint flag for this VNF to the specified value in A&AI.
317          *
318          *
319          * @param execution The flow's execution instance.
320          * @param inMaint The boolean value of the flag to set
321          */
322         public void setVnfInMaintFlagInAAI(DelegateExecution execution, boolean inMaint) {
323                 def method = getClass().getSimpleName() + '.setVnfInMaintFlagInAAI(' +
324                         'execution=' + execution.getId() +
325                         ')'
326                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
327                 execution.setVariable('errorCode', "0")
328                 logDebug('Entered ' + method, isDebugLogEnabled)
329                 if (inMaint) {
330                         execution.setVariable("workStep", "setVnfInMaintFlagInAAI")
331                         execution.setVariable("rollbackSetVnfInMaintenanceFlag", true)
332                 }
333                 else {
334                         execution.setVariable("workStep", "unsetVnfInMaintFlagInAAI")
335                 }
336                 execution.setVariable("failedActivity", "AAI")
337
338                 try {
339                         def transactionLoggingUuid = UUID.randomUUID().toString()
340                         AAIRestClientImpl client = new AAIRestClientImpl()
341                         AAIUpdatorImpl aaiUpdator = new AAIUpdatorImpl()
342                         aaiUpdator.setClient(client)
343                         def vnfId = execution.getVariable("vnfId")
344                         if (inMaint) {
345                                 aaiUpdator.updateVnfToLocked(vnfId, transactionLoggingUuid)
346                                 execution.setVariable("rollbackSetVnfInMaintenanceFlag", true)
347                         }
348                         else {
349                                 aaiUpdator.updateVnfToUnLocked(vnfId, transactionLoggingUuid)
350                         }
351                                                         
352                         logDebug('Exited ' + method, isDebugLogEnabled)
353                 } catch (BpmnError e) {
354                         throw e;
355                 } catch (Exception e) {
356                         logError('Caught exception in ' + method, e)
357                         execution.setVariable("errorCode", "1002")
358                         execution.setVariable("errorText", e.getMessage())
359                         //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in setVnfInMaintFlagInAAI(): ' + e.getMessage())
360                 }
361         }
362         
363         /**
364          * Check if VF Closed Loop Disabled in A&AI.
365          *
366          *
367          * @param execution The flow's execution instance.
368          */
369         public void checkIfClosedLoopDisabledInAAI(DelegateExecution execution) {
370                 def method = getClass().getSimpleName() + '.checkIfClosedLoopDisabledInAAI(' +
371                         'execution=' + execution.getId() +
372                         ')'
373                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
374                 execution.setVariable('errorCode', "0")
375                 execution.setVariable("workStep", "checkClosedLoopDisabledFlagInAAI")
376                 execution.setVariable("failedActivity", "AAI")
377                 logDebug('Entered ' + method, isDebugLogEnabled)
378
379                 try {
380                         def transactionLoggingUuid = UUID.randomUUID().toString()
381                         def vnfId = execution.getVariable("vnfId")
382                         logDebug("vnfId is: " + vnfId, isDebugLogEnabled)
383                         AAIResourcesClient client = new AAIResourcesClient()                    
384                         AAIUri genericVnfUri = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId)
385                         AAIResultWrapper aaiRW = client.get(genericVnfUri)
386                         Map<String, Object> result = aaiRW.asMap()
387                         boolean isClosedLoopDisabled = result.getOrDefault("is-closed-loop-disabled", false)
388                 
389                         logDebug("isClosedLoopDisabled result: " + isClosedLoopDisabled, isDebugLogEnabled)
390                         execution.setVariable('isClosedLoopDisabled', isClosedLoopDisabled)
391                         
392                         if (isClosedLoopDisabled) {
393                                 execution.setVariable("errorCode", "1004")
394                                 execution.setVariable("errorText", "closedLoop is disabled in A&AI")
395                         }
396
397                         logDebug('Exited ' + method, isDebugLogEnabled)
398                 } catch (BpmnError e) {
399                         throw e;
400                 } catch (Exception e) {
401                         logError('Caught exception in ' + method, e)
402                         execution.setVariable("errorCode", "1002")
403                         execution.setVariable("errorText", e.getMessage())
404                         //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfVnfInMaintInAAI(): ' + e.getMessage())
405                 }
406         }
407         
408         /**
409          * Set VF Closed Loop Disabled Flag in A&AI.
410          *
411          *
412          * @param execution The flow's execution instance.
413          */
414         public void setClosedLoopDisabledInAAI(DelegateExecution execution, boolean setDisabled) {
415                 def method = getClass().getSimpleName() + '.setClosedLoopDisabledInAAI(' +
416                         'execution=' + execution.getId() +
417                         ')'
418                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
419                 execution.setVariable('errorCode', "0")
420                 if (setDisabled) {
421                         execution.setVariable("workStep", "setClosedLoopDisabledFlagInAAI")
422                         execution.setVariable("rollbackSetClosedLoopDisabledFlag", true)
423                 }
424                 else {
425                         execution.setVariable("workStep", "unsetClosedLoopDisabledFlagInAAI")
426                 }
427                 
428                 execution.setVariable("failedActivity", "AAI")
429                 logDebug('Entered ' + method, isDebugLogEnabled)
430
431                 try {
432                         def transactionLoggingUuid = UUID.randomUUID().toString()
433                         def vnfId = execution.getVariable("vnfId")
434                         AAIResourcesClient client = new AAIResourcesClient()                    
435                         AAIUri genericVnfUri = AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId)
436                         
437                         Map<String, Boolean> request = new HashMap<>()
438                         request.put("is-closed-loop-disabled", setDisabled)
439                         client.update(genericVnfUri, request)
440                         logDebug("set isClosedLoop to: " + setDisabled, isDebugLogEnabled)              
441
442
443                         logDebug('Exited ' + method, isDebugLogEnabled)
444                 } catch (BpmnError e) {
445                         throw e;
446                 } catch (Exception e) {
447                         logError('Caught exception in ' + method, e)
448                         execution.setVariable("errorCode", "1002")
449                         execution.setVariable("errorText", e.getMessage())
450                         //exceptionUtil.buildAndThrowWorkflowException(execution, 1002, 'Error in checkIfVnfInMaintInAAI(): ' + e.getMessage())
451                 }
452         }       
453
454         
455         /**
456          * Handle Abort disposition from RainyDayHandler
457          *
458          * @param execution The flow's execution instance.       
459          */
460         public void abortProcessing(DelegateExecution execution) {
461                 def method = getClass().getSimpleName() + '.abortProcessing(' +
462                         'execution=' + execution.getId() +
463                         ')'
464                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
465                 logDebug('Entered ' + method, isDebugLogEnabled)
466                 
467                 def errorText = execution.getVariable("errorText")
468                 def errorCode = execution.getVariable("errorCode")
469                 
470                 exceptionUtil.buildAndThrowWorkflowException(execution, errorCode as Integer, errorText)
471         }
472         
473         /**
474          * Increment Retry Count for Current Work Step
475          *
476          * @param execution The flow's execution instance.
477          */
478         public void incrementRetryCount(DelegateExecution execution) {
479                 def method = getClass().getSimpleName() + '.incrementRetryCount(' +
480                         'execution=' + execution.getId() +
481                         ')'
482                 def isDebugLogEnabled = execution.getVariable('isDebugLogEnabled')
483                 logDebug('Entered ' + method, isDebugLogEnabled)
484                 
485                 String retryCountVariableName = execution.getVariable("workStep") + "RetryCount"
486                 execution.setVariable("retryCountVariableName", retryCountVariableName)
487                 
488                 def retryCountVariable = execution.getVariable(retryCountVariableName)
489                 int retryCount = 0
490                 
491                 if (retryCountVariable != null) {
492                         retryCount = (int) retryCountVariable
493                 }               
494                 
495                 retryCount += 1
496                 
497                 execution.setVariable(retryCountVariableName, retryCount)
498                 
499                 logDebug("value of " + retryCountVariableName + " is " + retryCount, isDebugLogEnabled)
500                 logDebug('Exited ' + method, isDebugLogEnabled)
501                         
502                 
503         }
504         
505         
506         
507 }