Merge "Fix Neutron Network"
[so.git] / bpmn / MSOCommonBPMN / src / main / groovy / org / onap / so / bpmn / common / scripts / VidUtils.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  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.bpmn.common.scripts
24
25 import groovy.json.JsonBuilder
26 import groovy.json.JsonSlurper
27
28 import org.json.JSONObject
29 import org.json.XML
30 import org.onap.so.bpmn.core.xml.XmlTool
31 import org.slf4j.Logger
32 import org.slf4j.LoggerFactory
33
34
35 class VidUtils {
36     private static final Logger logger = LoggerFactory.getLogger( VidUtils.class);
37
38         public MsoUtils utils = new MsoUtils()
39         private AbstractServiceTaskProcessor taskProcessor
40
41         public VidUtils(AbstractServiceTaskProcessor taskProcessor) {
42                 this.taskProcessor = taskProcessor
43         }
44
45         /**
46          * Create a volume-request XML using a JSON string
47          * @param jsonReq - JSON request from VID
48          * @param action
49          * @return
50          */
51         public String createXmlVolumeRequest(String jsonReq, String action, String serviceInstanceId) {
52                 def jsonSlurper = new JsonSlurper()
53                 try{
54                         Map reqMap = jsonSlurper.parseText(jsonReq)
55                         return createXmlVolumeRequest(reqMap, action, serviceInstanceId)
56                 }
57                 catch(Exception e) {
58                         throw e
59                 }
60         }
61
62         /**
63          * Create a volume-request XML using a map
64          * @param requestMap - map created from VID JSON
65          * @param action
66          * @param serviceInstanceId
67          * @return
68          */
69         public String createXmlVolumeRequest(Map requestMap, String action, String serviceInstanceId) {
70                 createXmlVolumeRequest(requestMap, action, serviceInstanceId, '')
71         }
72         
73
74         /**
75          * Create a volume-request XML using a map
76          * @param requestMap
77          * @param action
78          * @param serviceInstanceId
79          * @param volumeGroupId
80          * @return
81          */
82         public String createXmlVolumeRequest(Map requestMap, String action, String serviceInstanceId, String volumeGroupId) {
83                 def vnfType = ''
84                 def serviceName = ''
85                 def modelCustomizationName = ''
86                 def asdcServiceModelVersion = ''
87                 
88                 def suppressRollback = requestMap.requestDetails.requestInfo.suppressRollback
89                 
90                 def backoutOnFailure = ""
91                 if(suppressRollback != null){
92                         if ( suppressRollback == true) {
93                                 backoutOnFailure = "false"
94                         } else if ( suppressRollback == false) {
95                                 backoutOnFailure = "true"
96                         }
97                 }
98                 
99                 def volGrpName = requestMap.requestDetails.requestInfo?.instanceName ?: ''
100                 def serviceId = requestMap.requestDetails.requestParameters?.serviceId ?: ''
101                 def relatedInstanceList = requestMap.requestDetails.relatedInstanceList
102                 relatedInstanceList.each {
103                         if (it.relatedInstance.modelInfo?.modelType == 'service') {
104                                 serviceName = it.relatedInstance.modelInfo?.modelName
105                                 asdcServiceModelVersion = it.relatedInstance.modelInfo?.modelVersion
106                         }
107                         if (it.relatedInstance.modelInfo?.modelType == 'vnf') {
108                                 modelCustomizationName = it.relatedInstance.modelInfo?.modelInstanceName
109                         }
110                 }
111                 
112                 vnfType = serviceName + '/' + modelCustomizationName
113                 
114                 def userParams = requestMap.requestDetails?.requestParameters?.userParams
115                 def userParamsNode = ''
116                 if(userParams != null) {
117                         userParamsNode = buildUserParams(userParams)
118                 }
119                 def modelCustomizationId = requestMap.requestDetails?.modelInfo?.modelCustomizationUuid ?: ''
120                 
121                 String xmlReq = """
122                 <volume-request xmlns="http://www.w3.org/2001/XMLSchema">
123                         <request-info>
124                                 <action>${MsoUtils.xmlEscape(action)}</action>
125                                 <source>${MsoUtils.xmlEscape(requestMap.requestDetails.requestInfo.source)}</source>
126                                 <service-instance-id>${MsoUtils.xmlEscape(serviceInstanceId)}</service-instance-id>
127                         </request-info>
128                         <volume-inputs>
129                                 <volume-group-id>${MsoUtils.xmlEscape(volumeGroupId)}</volume-group-id>
130                                 <volume-group-name>${MsoUtils.xmlEscape(volGrpName)}</volume-group-name>
131                                 <vnf-type>${MsoUtils.xmlEscape(vnfType)}</vnf-type>
132                                 <vf-module-model-name>${MsoUtils.xmlEscape(requestMap.requestDetails.modelInfo.modelName)}</vf-module-model-name>
133                                 <asdc-service-model-version>${MsoUtils.xmlEscape(asdcServiceModelVersion)}</asdc-service-model-version>
134                                 <aic-cloud-region>${MsoUtils.xmlEscape(requestMap.requestDetails.cloudConfiguration.lcpCloudRegionId)}</aic-cloud-region>
135                                 <tenant-id>${MsoUtils.xmlEscape(requestMap.requestDetails.cloudConfiguration.tenantId)}</tenant-id>
136                                 <service-id>${MsoUtils.xmlEscape(serviceId)}</service-id>
137                                 <backout-on-failure>${MsoUtils.xmlEscape(backoutOnFailure)}</backout-on-failure>
138                                 <model-customization-id>${MsoUtils.xmlEscape(modelCustomizationId)}</model-customization-id>
139                         </volume-inputs>
140                         <volume-params>
141                                 $userParamsNode
142                         </volume-params>
143                 </volume-request>
144                 """
145                 // return a pretty-print of the volume-request xml without the preamble
146                 return groovy.xml.XmlUtil.serialize(xmlReq.normalize().replaceAll("\t", "").replaceAll("\n", "")).replaceAll("(<\\?[^<]*\\?>\\s*[\\r\\n]*)?", "") 
147         }
148         
149         /**
150          * A common method that can be used to build volume-params node from a map. 
151          * @param Map userParams
152          * @return
153          */
154         public String buildUserParams(userParams) {
155                 if (userParams == null) return ""
156                 def xml = ""
157                 def key = ""
158                 def value = ""
159                 userParams.each {it ->
160                         key = it.name.replaceAll(/\B[A-Z]/) { '_' + it }.toLowerCase()
161                         value = it.value
162                         xml += "<param name=\"${key}\">${MsoUtils.xmlEscape(value)}</param>"
163                 }
164
165                 return xml
166         }
167
168         /**
169          * A common method that can be used to extract 'requestDetails' 
170          * @param String json
171          * @return String json requestDetails  
172          */
173         @Deprecated
174         public getJsonRequestDetails(String jsonInput) {
175                 String rtn = ""
176                 if (jsonInput.isEmpty() || jsonInput == null) {
177                         return rtn
178                 } else {
179                         def jsonMapObject = new JsonSlurper().parseText(jsonInput)
180                         if (jsonMapObject instanceof Map) {
181                                 String jsonString = new JsonBuilder(jsonMapObject.requestDetails)
182                                 rtn = '{'+"requestDetails"+":"+jsonString+'}'
183                                 return rtn
184                         } else {
185                             return rtn
186                         }       
187                 }
188         }
189         
190         /**
191          * A common method that can be used to extract 'requestDetails' in Xml
192          * @param String json
193          * @return String xml requestDetails
194          */
195         @Deprecated
196         public getJsonRequestDetailstoXml(String jsonInput) {
197                 String rtn = null
198                 def jsonString = getJsonRequestDetails(jsonInput)
199                 if (jsonString == null) {
200                         return rtn
201                 } else {
202                     JSONObject jsonObj = new JSONObject(jsonString)
203                         return XmlTool.normalize(XML.toString(jsonObj))
204                 }
205         }
206         
207         /**
208          * Create a network-request XML using a map
209          * @param execution 
210          * @param xmlRequestDetails - requestDetails in xml 
211          * @return
212          * Note: See latest version: createXmlNetworkRequestInstance()
213          */
214
215         public String createXmlNetworkRequestInfra(execution, def networkJsonIncoming) {
216         
217                 def requestId = execution.getVariable("requestId")
218                 def serviceInstanceId = execution.getVariable("serviceInstanceId")
219                 def requestAction = execution.getVariable("requestAction")
220                 def networkId = (execution.getVariable("networkId")) != null ? execution.getVariable("networkId") : ""
221                 
222                 def jsonSlurper = new JsonSlurper()
223                 try {
224                         Map reqMap = jsonSlurper.parseText(networkJsonIncoming)
225                         def instanceName =  reqMap.requestDetails.requestInfo.instanceName
226                         def modelCustomizationId =  reqMap.requestDetails.modelInfo.modelCustomizationId
227                         if (modelCustomizationId == null) {
228                                 modelCustomizationId =  reqMap.requestDetails.modelInfo.modelCustomizationUuid !=null ?  
229                                                         reqMap.requestDetails.modelInfo.modelCustomizationUuid : ""
230                         }
231                         def modelName = reqMap.requestDetails.modelInfo.modelName
232                         def lcpCloudRegionId = reqMap.requestDetails.cloudConfiguration.lcpCloudRegionId
233                         def tenantId = reqMap.requestDetails.cloudConfiguration.tenantId
234                         def serviceId = reqMap.requestDetails.requestInfo.productFamilyId 
235                         def suppressRollback = reqMap.requestDetails.requestInfo.suppressRollback.toString()
236                         def backoutOnFailure = "true"
237                         if(suppressRollback != null){
238                                 if (suppressRollback == true || suppressRollback == "true") {
239                                         backoutOnFailure = "false"
240                                 } else if (suppressRollback == false || suppressRollback == "false") {
241                                         backoutOnFailure = "true"
242                                 }
243                         }
244                 
245                         //def userParams = reqMap.requestDetails.requestParameters.userParams
246                         //def userParamsNode = buildUserParams(userParams)
247                         def userParams = reqMap.requestDetails?.requestParameters?.userParams
248                         def userParamsNode = ''
249                         if(userParams != null) {
250                                 userParamsNode = buildUserParams(userParams)
251                         }
252                         
253                         //'sdncVersion' = current, '1610' (non-RPC SDNC) or '1702' (RPC SDNC)
254                         def sdncVersion =  execution.getVariable("sdncVersion")
255                         
256                         String xmlReq = """
257                         <network-request xmlns="http://www.w3.org/2001/XMLSchema"> 
258                          <request-info> 
259                     <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
260                                 <action>${MsoUtils.xmlEscape(requestAction)}</action> 
261                                 <source>VID</source> 
262                                 <service-instance-id>${MsoUtils.xmlEscape(serviceInstanceId)}</service-instance-id>
263                          </request-info> 
264                          <network-inputs>
265                                 <network-id>${MsoUtils.xmlEscape(networkId)}</network-id> 
266                                 <network-name>${MsoUtils.xmlEscape(instanceName)}</network-name> 
267                                 <network-type>${MsoUtils.xmlEscape(modelName)}</network-type>
268                                 <modelCustomizationId>${MsoUtils.xmlEscape(modelCustomizationId)}</modelCustomizationId> 
269                                 <aic-cloud-region>${MsoUtils.xmlEscape(lcpCloudRegionId)}</aic-cloud-region> 
270                                 <tenant-id>${MsoUtils.xmlEscape(tenantId)}</tenant-id>
271                                 <service-id>${MsoUtils.xmlEscape(serviceId)}</service-id> 
272                                 <backout-on-failure>${MsoUtils.xmlEscape(backoutOnFailure)}</backout-on-failure>
273                 <sdncVersion>${MsoUtils.xmlEscape(sdncVersion)}</sdncVersion>
274                          </network-inputs>
275                          <network-params>
276                                 ${userParamsNode}
277                          </network-params>
278                         </network-request>
279                         """
280                         // return a pretty-print of the volume-request xml without the preamble
281                         return groovy.xml.XmlUtil.serialize(xmlReq.normalize().replaceAll("\t", "").replaceAll("\n", "")).replaceAll("(<\\?[^<]*\\?>\\s*[\\r\\n]*)?", "")
282
283                 } catch(Exception e) {
284                         logger.debug("{} {}", "Error in Vid Utils", e.getCause())
285                         e.printStackTrace();
286                         throw e
287                 }
288         }
289
290         /**
291          * Create a network-request XML using a map,
292          * @param execution
293          * @return
294          */
295         public String createXmlNetworkRequestInstance(execution) {
296
297                 def networkModelUuid = ""
298                 def networkModelName = ""
299                 def networkModelVersion = ""
300                 def networkModelCustomizationUuid = ""
301                 def networkModelInvariantUuid = ""
302                 
303                 // verify the DB Catalog response JSON structure
304                 def networkModelInfo = execution.getVariable("networkModelInfo")
305                 def jsonSlurper = new JsonSlurper()
306                 if (networkModelInfo != null) {
307                         try {
308                                 Map modelMap = jsonSlurper.parseText(networkModelInfo)
309                                 if (modelMap != null) {
310                                         if (networkModelInfo.contains("modelUuid")) {
311                                                 networkModelUuid = modelMap.modelUuid !=null ? modelMap.modelUuid : ""
312                                         }
313                                         if (networkModelInfo.contains("modelName")) {
314                                                 networkModelName = modelMap.modelName !=null ? modelMap.modelName : ""
315                                         }
316                                         if (networkModelInfo.contains("modelVersion")) {
317                                                 networkModelVersion = modelMap.modelVersion !=null ? modelMap.modelVersion : ""
318                                         }
319                                         if (networkModelInfo.contains("modelCustomizationUuid")) {
320                                                 networkModelCustomizationUuid = modelMap.modelCustomizationUuid !=null ? modelMap.modelCustomizationUuid : ""
321                                         }
322                                         if (networkModelInfo.contains("modelInvariantUuid")) {
323                                                 networkModelInvariantUuid = modelMap.modelInvariantUuid !=null ? modelMap.modelInvariantUuid : ""
324                                         }
325                                 }
326                         } catch (Exception ex) {
327                         throw ex
328                         }
329                 }               
330                 
331                 def serviceModelUuid = ""
332                 def serviceModelName = ""
333                 def serviceModelVersion = ""
334                 def serviceModelCustomizationUuid = ""
335                 def serviceModelInvariantUuid = ""
336                 
337                 // verify the DB Catalog response JSON structure
338                 def serviceModelInfo = execution.getVariable("serviceModelInfo")
339                 def jsonServiceSlurper = new JsonSlurper()
340                 if (serviceModelInfo != null) {
341                         try {
342                                 Map modelMap = jsonServiceSlurper.parseText(serviceModelInfo)
343                                 if (modelMap != null) {
344                                         if (serviceModelInfo.contains("modelUuid")) {
345                                                 serviceModelUuid = modelMap.modelUuid !=null ? modelMap.modelUuid : ""
346                                         }
347                                         if (serviceModelInfo.contains("modelName")) {
348                                                 serviceModelName = modelMap.modelName !=null ? modelMap.modelName : ""
349                                         }
350                                         if (serviceModelInfo.contains("modelVersion")) {
351                                                 serviceModelVersion = modelMap.modelVersion !=null ? modelMap.modelVersion : ""
352                                         }
353                                         if (serviceModelInfo.contains("modelCustomizationUuid")) {
354                                                 serviceModelCustomizationUuid = modelMap.modelCustomizationUuid !=null ? modelMap.modelCustomizationUuid : ""
355                                         }
356                                         if (serviceModelInfo.contains("modelInvariantUuid")) {
357                                                 serviceModelInvariantUuid = modelMap.modelInvariantUuid !=null ? modelMap.modelInvariantUuid : ""
358                                         }
359                                 }
360                         } catch (Exception ex) {
361                                 throw ex
362                         }
363                 }
364                 
365                 
366                 def subscriptionServiceType = execution.getVariable("subscriptionServiceType") != null ? execution.getVariable("subscriptionServiceType") : ""
367                 def globalSubscriberId = execution.getVariable("globalSubscriberId") != null ? execution.getVariable("globalSubscriberId") : ""
368                 def requestId = execution.getVariable("msoRequestId")
369                 def serviceInstanceId = execution.getVariable("serviceInstanceId") != null ? execution.getVariable("serviceInstanceId") : ""
370                 def networkId = (execution.getVariable("networkId")) != null ? execution.getVariable("networkId") : "" // optional
371                 def networkName =  execution.getVariable("networkName") != null ? execution.getVariable("networkName") : "" // optional
372                 def aicCloudReqion = execution.getVariable("lcpCloudRegionId") != null ? execution.getVariable("lcpCloudRegionId") : ""
373                 def tenantId = execution.getVariable("tenantId") != null ? execution.getVariable("tenantId") : ""
374                 def serviceId = execution.getVariable("productFamilyId") != null ? execution.getVariable("productFamilyId") : ""
375                 def failIfExist = execution.getVariable("failIfExists") != null ? execution.getVariable("failIfExists") : ""
376                 def suppressRollback = execution.getVariable("disableRollback")   
377                 def backoutOnFailure = "true"
378                 if(suppressRollback != null){
379                         if (suppressRollback == true || suppressRollback == "true") {
380                                 backoutOnFailure = "false"
381                         } else if (suppressRollback == false || suppressRollback == "false") {
382                                 backoutOnFailure = "true"
383                         }
384                 }
385                 
386                 //'sdncVersion' = current, '1610' (non-RPC SDNC) or '1702' (RPC SDNC)
387                 def sdncVersion =  execution.getVariable("sdncVersion")
388                 
389                 def source = "VID"
390                 def action = execution.getVariable("action")
391                                 
392                 def userParamsNode = ""
393                 def userParams = execution.getVariable("networkInputParams")
394                 if(userParams != null) {
395                    userParamsNode = buildUserParams(userParams)
396                 }
397                 
398                 String xmlReq = """
399                 <network-request xmlns="http://www.w3.org/2001/XMLSchema"> 
400                  <request-info> 
401             <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
402                         <action>${MsoUtils.xmlEscape(action)}</action> 
403                         <source>${MsoUtils.xmlEscape(source)}</source> 
404                         <service-instance-id>${MsoUtils.xmlEscape(serviceInstanceId)}</service-instance-id>
405                  </request-info> 
406                  <network-inputs> 
407                         <network-id>${MsoUtils.xmlEscape(networkId)}</network-id> 
408                         <network-name>${MsoUtils.xmlEscape(networkName)}</network-name> 
409                         <network-type>${MsoUtils.xmlEscape(networkModelName)}</network-type>
410                         <subscription-service-type>${MsoUtils.xmlEscape(subscriptionServiceType)}</subscription-service-type>
411             <global-customer-id>${MsoUtils.xmlEscape(globalSubscriberId)}</global-customer-id>
412                         <aic-cloud-region>${MsoUtils.xmlEscape(aicCloudReqion)}</aic-cloud-region> 
413                         <tenant-id>${MsoUtils.xmlEscape(tenantId)}</tenant-id>
414                         <service-id>${MsoUtils.xmlEscape(serviceId)}</service-id> 
415                         <backout-on-failure>${MsoUtils.xmlEscape(backoutOnFailure)}</backout-on-failure>
416                         <failIfExist>${MsoUtils.xmlEscape(failIfExist)}</failIfExist>
417             <networkModelInfo>
418               <modelName>${MsoUtils.xmlEscape(networkModelName)}</modelName>
419               <modelUuid>${MsoUtils.xmlEscape(networkModelUuid)}</modelUuid>
420               <modelInvariantUuid>${MsoUtils.xmlEscape(networkModelInvariantUuid)}</modelInvariantUuid>            
421               <modelVersion>${MsoUtils.xmlEscape(networkModelVersion)}</modelVersion>
422               <modelCustomizationUuid>${MsoUtils.xmlEscape(networkModelCustomizationUuid)}</modelCustomizationUuid>
423                     </networkModelInfo>
424             <serviceModelInfo>
425               <modelName>${MsoUtils.xmlEscape(serviceModelName)}</modelName>
426               <modelUuid>${MsoUtils.xmlEscape(serviceModelUuid)}</modelUuid>
427               <modelInvariantUuid>${MsoUtils.xmlEscape(serviceModelInvariantUuid)}</modelInvariantUuid>            
428               <modelVersion>${MsoUtils.xmlEscape(serviceModelVersion)}</modelVersion>
429               <modelCustomizationUuid>${MsoUtils.xmlEscape(serviceModelCustomizationUuid)}</modelCustomizationUuid>
430              
431                     </serviceModelInfo>                                                                                                 
432             <sdncVersion>${MsoUtils.xmlEscape(sdncVersion)}</sdncVersion>                    
433                  </network-inputs>
434                  <network-params>
435                         ${userParamsNode}
436                  </network-params> 
437                 </network-request>
438                 """
439                 // return a pretty-print of the volume-request xml without the preamble
440                 return groovy.xml.XmlUtil.serialize(xmlReq.normalize().replaceAll("\t", "").replaceAll("\n", "")).replaceAll("(<\\?[^<]*\\?>\\s*[\\r\\n]*)?", "")
441                         
442         }
443         
444         /**
445          * Create a vnf-request XML using a map
446          * @param requestMap - map created from VID JSON 
447          * @param action
448          * @return
449          */
450         public String createXmlVfModuleRequest(execution, Map requestMap, String action, String serviceInstanceId) {
451                                 
452                 //def relatedInstanceList = requestMap.requestDetails.relatedInstanceList
453                 
454                 //relatedInstanceList.each {
455                 //      if (it.relatedInstance.modelInfo.modelType == 'vnf') {
456                 //              vnfType = it.relatedInstance.modelInfo.modelName
457                 //              vnfId = it.relatedInstance.modelInfo.modelInvariantId
458                 //      }
459                 //}
460                 
461                 def vnfName = ''
462                 def asdcServiceModelInfo = ''
463                                 
464                 def relatedInstanceList = requestMap.requestDetails?.relatedInstanceList
465                 
466                 
467                 if (relatedInstanceList != null) {
468                         relatedInstanceList.each {
469                                 if (it.relatedInstance.modelInfo?.modelType == 'service') {
470                                         asdcServiceModelInfo = it.relatedInstance.modelInfo?.modelVersion
471                                 }
472                                 if (it.relatedInstance.modelInfo.modelType == 'vnf') {
473                                         vnfName = it.relatedInstance.instanceName ?: ''
474                                 }
475                         }
476                 }
477                 
478                 def vnfType = execution.getVariable('vnfType')
479                 def vnfId = execution.getVariable('vnfId')
480
481                 def vfModuleId = execution.getVariable('vfModuleId')
482                 def volumeGroupId = execution.getVariable('volumeGroupId')
483                 def userParams = requestMap.requestDetails?.requestParameters?.userParams
484                 
485                 
486                 def userParamsNode = ''
487                 if(userParams != null) {
488                         userParamsNode = buildUserParams(userParams)
489                 }
490                 
491                 def isBaseVfModule = "false"
492                 if (execution.getVariable('isBaseVfModule') == true) {
493                         isBaseVfModule = "true"         
494                 }
495                 
496                 def requestId = execution.getVariable("mso-request-id")         
497                 def vfModuleName = requestMap.requestDetails?.requestInfo?.instanceName ?: ''
498                 def vfModuleModelName = requestMap.requestDetails?.modelInfo?.modelName ?: ''
499                 def suppressRollback = requestMap.requestDetails?.requestInfo?.suppressRollback
500                 
501                 def backoutOnFailure = ""
502                 if(suppressRollback != null){
503                         if ( suppressRollback == true) {
504                                 backoutOnFailure = "false"
505                         } else if ( suppressRollback == false) {
506                                 backoutOnFailure = "true"
507                         }
508                 }
509                 
510                 def serviceId = requestMap.requestDetails?.requestParameters?.serviceId ?: ''
511                 def aicCloudRegion = requestMap.requestDetails?.cloudConfiguration?.lcpCloudRegionId ?: ''
512                 def tenantId = requestMap.requestDetails?.cloudConfiguration?.tenantId ?: ''
513                 def personaModelId = requestMap.requestDetails?.modelInfo?.modelInvariantUuid ?: ''
514                 def personaModelVersion = requestMap.requestDetails?.modelInfo?.modelUuid ?: ''
515                 def modelCustomizationId = requestMap.requestDetails?.modelInfo?.modelCustomizationUuid ?: ''
516                 
517                 String xmlReq = """
518                 <vnf-request>
519                         <request-info>
520                                 <request-id>${MsoUtils.xmlEscape(requestId)}</request-id>
521                                 <action>${MsoUtils.xmlEscape(action)}</action>
522                                 <source>VID</source>
523                                 <service-instance-id>${MsoUtils.xmlEscape(serviceInstanceId)}</service-instance-id>
524                         </request-info>
525                         <vnf-inputs>
526                                 <!-- not in use in 1610 -->
527                                 <vnf-name>${MsoUtils.xmlEscape(vnfName)}</vnf-name>                                     
528                                 <vnf-type>${MsoUtils.xmlEscape(vnfType)}</vnf-type>
529                                 <vnf-id>${MsoUtils.xmlEscape(vnfId)}</vnf-id>
530                                 <volume-group-id>${MsoUtils.xmlEscape(volumeGroupId)}</volume-group-id>
531                                 <vf-module-id>${MsoUtils.xmlEscape(vfModuleId)}</vf-module-id>
532                                 <vf-module-name>${MsoUtils.xmlEscape(vfModuleName)}</vf-module-name>                            
533                                 <vf-module-model-name>${MsoUtils.xmlEscape(vfModuleModelName)}</vf-module-model-name>
534                                 <model-customization-id>${MsoUtils.xmlEscape(modelCustomizationId)}</model-customization-id>
535                                 <is-base-vf-module>${MsoUtils.xmlEscape(isBaseVfModule)}</is-base-vf-module>
536                                 <asdc-service-model-version>${MsoUtils.xmlEscape(asdcServiceModelInfo)}</asdc-service-model-version>
537                                 <aic-cloud-region>${MsoUtils.xmlEscape(aicCloudRegion)}</aic-cloud-region>                              
538                                 <tenant-id>${MsoUtils.xmlEscape(tenantId)}</tenant-id>
539                                 <service-id>${MsoUtils.xmlEscape(serviceId)}</service-id>
540                                 <backout-on-failure>${MsoUtils.xmlEscape(backoutOnFailure)}</backout-on-failure>
541                                 <persona-model-id>${MsoUtils.xmlEscape(personaModelId)}</persona-model-id>
542                                 <persona-model-version>${MsoUtils.xmlEscape(personaModelVersion)}</persona-model-version>
543                         </vnf-inputs>
544                         <vnf-params>
545                                 $userParamsNode
546                         </vnf-params>
547                 </vnf-request>
548                 """
549         
550                 // return a pretty-print of the volume-request xml without the preamble
551                 return groovy.xml.XmlUtil.serialize(xmlReq.normalize().replaceAll("\t", "").replaceAll("\n", "")).replaceAll("(<\\?[^<]*\\?>\\s*[\\r\\n]*)?", "") 
552         }
553         
554
555 }