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