Dynamic Cloud Owner Support
[so.git] / bpmn / MSOCommonBPMN / src / main / groovy / org / onap / so / bpmn / common / scripts / NetworkUtils.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  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.so.bpmn.common.scripts;
22
23 import javax.ws.rs.core.UriBuilder
24 import javax.xml.parsers.DocumentBuilder
25 import javax.xml.parsers.DocumentBuilderFactory
26 import javax.xml.transform.Transformer
27 import javax.xml.transform.TransformerFactory
28 import javax.xml.transform.dom.DOMSource
29 import javax.xml.transform.stream.StreamResult
30
31 import org.apache.commons.lang3.*
32 import org.camunda.bpm.engine.delegate.DelegateExecution
33 import org.onap.so.bpmn.core.UrnPropertiesReader
34 import org.onap.so.client.aai.AAIObjectType
35 import org.onap.so.client.aai.entities.uri.AAIResourceUri
36 import org.onap.so.client.aai.entities.uri.AAIUriFactory
37 import org.onap.so.logger.MsoLogger
38 import org.w3c.dom.Document
39 import org.w3c.dom.Element
40 import org.w3c.dom.Node
41 import org.w3c.dom.NodeList;
42 import org.xml.sax.InputSource
43
44 import groovy.xml.XmlUtil
45
46
47 /**
48  * This groovy class supports the any Network processes that need the methods defined here.
49  */
50 class NetworkUtils {
51         private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, NetworkUtils.class);
52
53
54         public MsoUtils utils = new MsoUtils()
55         private AbstractServiceTaskProcessor taskProcessor
56
57         public NetworkUtils(AbstractServiceTaskProcessor taskProcessor) {
58                 this.taskProcessor = taskProcessor
59         }
60
61         /**
62          * This method returns the string for Network request
63          * V2 for Contrail 3.x will populate cloud-region data in same cloudSiteId filed
64          * Network adapter will handle it properly
65          * @param requestId either 'request-id' or 'mso-request-id'
66          * @param requestInput the request in the process
67          * @param queryIdResponse the response of REST AAI query by Id
68          * @param routeCollection the collection
69          * @param policyFqdns the policy
70          * @param tableCollection the collection
71          * @param cloudRegionId the cloud-region-region
72          * @return String request
73          */
74         def CreateNetworkRequestV2(execution, requestId, messageId, requestInput, queryIdResponse, routeCollection, policyFqdns, tableCollection, cloudRegionId, backoutOnFailure, source) {
75                 String createNetworkRequest = null
76                 if(requestInput!=null && queryIdResponse!=null) {
77                                 String serviceInstanceId = ""
78                                 String sharedValue = ""
79                                 String externalValue = ""
80
81                                 if (source == "VID") {
82                                         sharedValue = utils.getNodeText(queryIdResponse, "is-shared-network") != null ? utils.getNodeText(queryIdResponse, "is-shared-network") : "false"
83                                         externalValue = utils.getNodeText(queryIdResponse, "is-external-network") != null ? utils.getNodeText(queryIdResponse, "is-external-network") : "false"
84                                         serviceInstanceId = utils.getNodeText(requestInput, "service-instance-id")
85
86                                 } else { // source = 'PORTAL'
87                                         sharedValue = getParameterValue(requestInput, "shared")
88                                         externalValue = getParameterValue(requestInput, "external")
89                                         serviceInstanceId = utils.getNodeText(requestInput, "service-instance-id") != null ? utils.getNodeText(requestInput, "service-instance-id") : ""
90                                 }
91
92                                 String networkParams = ""
93                                 if (utils.nodeExists(requestInput, "network-params")) {
94                                         String netParams = utils.getNodeXml(requestInput, "network-params", false).replace("tag0:","").replace(":tag0","")
95                                         networkParams = buildParams(netParams)
96                                 }
97
98                                 String failIfExists = "false"
99                                 // requestInput
100                                 String cloudRegion = cloudRegionId
101                                 String tenantId = utils.getNodeText(requestInput, "tenant-id")
102
103                                 String networkType = ""
104                                 String modelCustomizationUuid = ""
105                                 if (utils.nodeExists(requestInput, "networkModelInfo")) {
106                                         String networkModelInfo = utils.getNodeXml(requestInput, "networkModelInfo", false).replace("tag0:","").replace(":tag0","")
107                                         networkType = utils.getNodeText(networkModelInfo, "modelName")
108                                         modelCustomizationUuid = utils.getNodeText(networkModelInfo, "modelCustomizationUuid")
109                                 } else {
110                                         networkType = utils.getNodeText(queryIdResponse, "network-type")
111                                         modelCustomizationUuid = utils.getNodeText(requestInput, "modelCustomizationId")
112                                 }
113
114                                 // queryIdResponse
115                                 String networkName = utils.getNodeText(queryIdResponse, "network-name")
116                                 String networkId = utils.getNodeText(queryIdResponse, "network-id")
117                                 String networkTechnology = utils.getNodeText(queryIdResponse, "network-technology")
118
119                                 // contrailNetwork - networkTechnology = 'Contrail' vs. 'AIC_SR_IOV')
120                                 String contrailNetwork = ""
121                                 if (networkTechnology.contains('Contrail') || networkTechnology.contains('contrail') || networkTechnology.contains('CONTRAIL')) {
122                                         contrailNetwork = """<contrailNetwork>
123                                                                <shared>${MsoUtils.xmlEscape(sharedValue)}</shared>
124                                                                <external>${MsoUtils.xmlEscape(externalValue)}</external>
125                                                                ${routeCollection}
126                                                                ${policyFqdns}
127                                                                ${tableCollection}
128                                                          </contrailNetwork>"""
129                                         networkTechnology = "CONTRAIL"    // replace
130                             }
131
132                                 // rebuild subnets
133                                 String subnets = ""
134                                 if (utils.nodeExists(queryIdResponse, "subnets")) {
135                                         def subnetsGroup = utils.getNodeXml(queryIdResponse, "subnets", false)
136                                         subnets = buildSubnets(subnetsGroup)
137                                 }
138
139                                 String physicalNetworkName = ""
140                                 physicalNetworkName = utils.getNodeText(queryIdResponse, "physical-network-name")
141
142                                 String vlansCollection = buildVlans(queryIdResponse)
143
144                                 String notificationUrl = ""                                   //TODO - is this coming from URN? What variable/value to use?
145                                 //String notificationUrl = execution.getVariable("URN_?????") //TODO - is this coming from URN? What variable/value to use?
146
147                                 createNetworkRequest = """
148                                                                 <createNetworkRequest>
149                                                                         <cloudSiteId>${MsoUtils.xmlEscape(cloudRegion)}</cloudSiteId>
150                                                                         <tenantId>${MsoUtils.xmlEscape(tenantId)}</tenantId>
151                                                                         <networkId>${MsoUtils.xmlEscape(networkId)}</networkId>
152                                                                         <networkName>${MsoUtils.xmlEscape(networkName)}</networkName>
153                                                                         <networkType>${MsoUtils.xmlEscape(networkType)}</networkType>
154                                                                         <modelCustomizationUuid>${MsoUtils.xmlEscape(modelCustomizationUuid)}</modelCustomizationUuid>
155                                                                         <networkTechnology>${MsoUtils.xmlEscape(networkTechnology)}</networkTechnology>
156                                                                         <providerVlanNetwork>
157                                                                                 <physicalNetworkName>${MsoUtils.xmlEscape(physicalNetworkName)}</physicalNetworkName >
158                                                                                 ${vlansCollection}
159                                                                         </providerVlanNetwork>
160                                     ${contrailNetwork}
161                                                                         ${subnets}
162                                                                         <skipAAI>true</skipAAI>
163                                                                         <backout>${MsoUtils.xmlEscape(backoutOnFailure)}</backout>
164                                                                         <failIfExists>${MsoUtils.xmlEscape(failIfExists)}</failIfExists>
165                                                                         ${networkParams}
166                                                                         <msoRequest>
167                                                                                 <requestId>${MsoUtils.xmlEscape(requestId)}</requestId>
168                                                                                 <serviceInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</serviceInstanceId>
169                                                                 </msoRequest>
170                                                                         <messageId>${MsoUtils.xmlEscape(messageId)}</messageId>
171                                                                         <notificationUrl>${MsoUtils.xmlEscape(notificationUrl)}</notificationUrl>
172                                                                 </createNetworkRequest>
173                                                                 """.trim()
174                 }
175                 return createNetworkRequest
176
177         }
178
179         /**
180          * This method returns the string for Network request
181          * V2 for Contrail 3.x will populate cloud-region data in same cloudSiteId filed
182          * Network adapter will handle it properly
183          * @param requestId either 'request-id' or 'mso-request-id'
184          * @param requestInput the request in the process
185          * @param queryIdResponse the response of REST AAI query by Id
186          * @param routeCollection the collection
187          * @param policyFqdns the policy
188          * @param cloudRegionId the cloud-region-region
189          * @return String request
190          */
191         def UpdateNetworkRequestV2(execution, requestId, messageId, requestInput, queryIdResponse, routeCollection, policyFqdns, tableCollection, cloudRegionId, backoutOnFailure, source) {
192                 String updateNetworkRequest = null
193                 if(requestInput!=null && queryIdResponse!=null) {
194                                 String serviceInstanceId = ""
195                                 String sharedValue = ""
196                                 String externalValue = ""
197
198                                 if (source == "VID") {
199                                         sharedValue = utils.getNodeText(queryIdResponse, "is-shared-network") != null ? utils.getNodeText(queryIdResponse, "is-shared-network") : "false"
200                                         externalValue = utils.getNodeText(queryIdResponse, "is-external-network") != null ? utils.getNodeText(queryIdResponse, "is-external-network") : "false"
201                                         serviceInstanceId = utils.getNodeText(requestInput, "service-instance-id")
202
203                                 } else { // source = 'PORTAL'
204                                         sharedValue = getParameterValue(requestInput, "shared")
205                                         externalValue = getParameterValue(requestInput, "external")
206                                         serviceInstanceId = utils.getNodeText(requestInput, "service-instance-id") != null ? utils.getNodeText(requestInput, "service-instance-id") : ""
207                                 }
208
209                                 String failIfExists = "false"
210                                 // requestInput
211                                 String cloudRegion = cloudRegionId
212                                 String tenantId = utils.getNodeText(requestInput, "tenant-id")
213
214                                 // queryIdResponse
215                                 String networkName = utils.getNodeText(queryIdResponse, "network-name")
216                                 String networkId = utils.getNodeText(queryIdResponse, "network-id")
217                                 
218                                 String networkType = ""
219                                 String modelCustomizationUuid = ""
220                                 if (utils.nodeExists(requestInput, "networkModelInfo")) {
221                                         String networkModelInfo = utils.getNodeXml(requestInput, "networkModelInfo", false).replace("tag0:","").replace(":tag0","")
222                                         networkType = utils.getNodeText(networkModelInfo, "modelName")
223                                         modelCustomizationUuid = utils.getNodeText(networkModelInfo, "modelCustomizationUuid")
224                                 } else {
225                                         networkType = utils.getNodeText(queryIdResponse, "network-type")
226                                         modelCustomizationUuid = utils.getNodeText(requestInput, "modelCustomizationId")
227                                 }
228
229                                 // rebuild subnets
230                                 String subnets = ""
231                                 if (utils.nodeExists(queryIdResponse, "subnets")) {
232                                         def subnetsGroup = utils.getNodeXml(queryIdResponse, "subnets", false)
233                                         subnets = buildSubnets(subnetsGroup)
234                                 }
235
236                                 String networkParams = ""
237                                 if (utils.nodeExists(requestInput, "network-params")) {
238                                         String netParams = utils.getNodeXml(requestInput, "network-params", false).replace("tag0:","").replace(":tag0","")
239                                         networkParams = buildParams(netParams)
240                                 }
241
242                                 String networkStackId = utils.getNodeText(queryIdResponse, "heat-stack-id")
243                                 if (networkStackId == 'null' || networkStackId == "" || networkStackId == null) {
244                                         networkStackId = "force_update"
245                                 }
246
247                                 String physicalNetworkName = utils.getNodeText(queryIdResponse, "physical-network-name")
248                                 String vlansCollection = buildVlans(queryIdResponse)
249
250                                 updateNetworkRequest =
251                          """<updateNetworkRequest>
252                                                                 <cloudSiteId>${MsoUtils.xmlEscape(cloudRegion)}</cloudSiteId>
253                                                                 <tenantId>${MsoUtils.xmlEscape(tenantId)}</tenantId>
254                                                                 <networkId>${MsoUtils.xmlEscape(networkId)}</networkId>
255                                                         <networkStackId>${MsoUtils.xmlEscape(networkStackId)}</networkStackId>
256                                                                 <networkName>${MsoUtils.xmlEscape(networkName)}</networkName>
257                                                                 <networkType>${MsoUtils.xmlEscape(networkType)}</networkType>
258                                                                 <modelCustomizationUuid>${MsoUtils.xmlEscape(modelCustomizationUuid)}</modelCustomizationUuid>
259                                                                 <networkTypeVersion/>
260                                                                 <networkTechnology>CONTRAIL</networkTechnology>
261                                                                 <providerVlanNetwork>
262                                                                         <physicalNetworkName>${MsoUtils.xmlEscape(physicalNetworkName)}</physicalNetworkName>
263                                                                         ${vlansCollection}
264                                                                 </providerVlanNetwork>
265                                                                 <contrailNetwork>
266                                                                         <shared>${MsoUtils.xmlEscape(sharedValue)}</shared>
267                                                                         <external>${MsoUtils.xmlEscape(externalValue)}</external>
268                                                                         ${routeCollection}
269                                                                         ${policyFqdns}
270                                                                         ${tableCollection}
271                                                                 </contrailNetwork>
272                                                                 ${subnets}
273                                                                 <skipAAI>true</skipAAI>
274                                                                 <backout>${MsoUtils.xmlEscape(backoutOnFailure)}</backout>
275                                                                 <failIfExists>${MsoUtils.xmlEscape(failIfExists)}</failIfExists>
276                                                                         ${networkParams}
277
278                                                                 <msoRequest>
279                                                                   <requestId>${MsoUtils.xmlEscape(requestId)}</requestId>
280                                                                   <serviceInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</serviceInstanceId>
281                                                                 </msoRequest>
282                                                                 <messageId>${MsoUtils.xmlEscape(messageId)}</messageId>
283                                                                 <notificationUrl></notificationUrl>
284                                                         </updateNetworkRequest>""".trim()
285
286                 }
287                 return updateNetworkRequest
288
289         }
290
291         /**
292          * This method returns the string for Create Volume Request payload
293          * @param groupId the volume-group-id
294          * @param volumeName the volume-group-name
295          * @param vnfType the vnf-type
296          * @param tenantId the value of relationship-key 'tenant.tenant-id'
297          * @return String request payload
298          */
299         def String CreateNetworkVolumeRequest(groupId, volumeName, vnfType, tenantId) {
300
301                 String requestPayload =
302                 """<volume-group xmlns="http://org.onap.so/v6">
303                                 <volume-group-id>${MsoUtils.xmlEscape(groupId)}</volume-group-id>
304                                 <volume-group-name>${MsoUtils.xmlEscape(volumeName)}</volume-group-name>
305                                 <heat-stack-id></heat-stack-id>
306                                 <vnf-type>${MsoUtils.xmlEscape(vnfType)}</vnf-type>
307                                 <orchestration-status>Pending</orchestration-status>
308                                 <relationship-list>
309                                    <relationship>
310                                            <related-to>tenant</related-to>
311                                            <relationship-data>
312                                                    <relationship-key>tenant.tenant-id</relationship-key>
313                                                    <relationship-value>${MsoUtils.xmlEscape(tenantId)}</relationship-value>
314                                            </relationship-data>
315                                    </relationship>
316                            </relationship-list>
317                    </volume-group>"""
318
319                 return requestPayload
320         }
321         
322         def String createCloudRegionVolumeRequest(groupId, volumeName, vnfType, vnfId, tenantId, cloudOwner, cloudRegion, namespace, modelCustomizationId) {
323                 
324                 String requestPayload =
325                 """<volume-group xmlns="${namespace}">
326                         <volume-group-id>${MsoUtils.xmlEscape(groupId)}</volume-group-id>
327                         <volume-group-name>${MsoUtils.xmlEscape(volumeName)}</volume-group-name>
328                         <heat-stack-id></heat-stack-id>
329                         <vnf-type>${MsoUtils.xmlEscape(vnfType)}</vnf-type>
330                         <orchestration-status>Pending</orchestration-status>
331                         <vf-module-model-customization-id>${MsoUtils.xmlEscape(modelCustomizationId)}</vf-module-model-customization-id>
332                         <relationship-list>
333                                 <relationship>
334                                    <related-to>generic-vnf</related-to>
335                                    <relationship-data>
336                                            <relationship-key>generic-vnf.vnf-id</relationship-key>
337                                            <relationship-value>${MsoUtils.xmlEscape(vnfId)}</relationship-value>
338                                    </relationship-data>
339                            </relationship>
340                            <relationship>
341                                    <related-to>tenant</related-to>
342                                    <relationship-data>
343                                            <relationship-key>tenant.tenant-id</relationship-key>
344                                            <relationship-value>${MsoUtils.xmlEscape(tenantId)}</relationship-value>
345                                    </relationship-data>
346                                    <relationship-data>
347                                            <relationship-key>cloud-region.cloud-owner</relationship-key>
348                                            <relationship-value>${cloudOwner}</relationship-value>
349                                    </relationship-data>
350                                    <relationship-data>
351                                            <relationship-key>cloud-region.cloud-region-id</relationship-key>
352                                            <relationship-value>${MsoUtils.xmlEscape(cloudRegion)}</relationship-value>
353                                    </relationship-data>
354                            </relationship>
355                    </relationship-list>
356                 </volume-group>"""
357
358                 return requestPayload
359         }
360
361
362         /**
363          * This method returns the string for Update Volume Request payload
364          * @param requeryAAIVolGrpNameResponse the response of query volume group name (in AAI)
365           * @param heatStackId the value of heat stack id
366          * @return String request payload
367          */
368         def String updateCloudRegionVolumeRequest(requeryAAIVolGrpNameResponse, heatStackId, namespace, modelCustomizationId) {
369                 String requestPayload = ""
370                 if (requeryAAIVolGrpNameResponse != null) {
371                         def groupId = utils.getNodeText(requeryAAIVolGrpNameResponse, "volume-group-id")
372                         def volumeName = utils.getNodeText(requeryAAIVolGrpNameResponse, "volume-group-name")
373                         def vnfType = utils.getNodeText(requeryAAIVolGrpNameResponse, "vnf-type")
374                         def resourceVersion = utils.getNodeText(requeryAAIVolGrpNameResponse, "resource-version")
375                         def relationshipList = ""
376                         if (utils.nodeExists(requeryAAIVolGrpNameResponse, "relationship")) {
377                                 relationshipList = rebuildRelationship(requeryAAIVolGrpNameResponse)
378                         }
379
380                         requestPayload =
381                                 """<volume-group xmlns="${namespace}">
382                                         <volume-group-id>${MsoUtils.xmlEscape(groupId)}</volume-group-id>
383                                         <volume-group-name>${MsoUtils.xmlEscape(volumeName)}</volume-group-name>
384                                         <heat-stack-id>${MsoUtils.xmlEscape(heatStackId)}</heat-stack-id>
385                                         <vnf-type>${MsoUtils.xmlEscape(vnfType)}</vnf-type>
386                                         <orchestration-status>Active</orchestration-status>
387                                         <resource-version>${MsoUtils.xmlEscape(resourceVersion)}</resource-version>
388                                         <vf-module-model-customization-id>${MsoUtils.xmlEscape(modelCustomizationId)}</vf-module-model-customization-id>
389                                         ${relationshipList}
390                                  </volume-group>"""
391                 }
392
393                 return requestPayload
394         }
395
396
397         /**
398          * This method returns the string for Update Volume Request payload
399          * @param requeryAAIVolGrpNameResponse the response of query volume group name (in AAI)
400          * @param heatStackId the value of heat stack id
401          * @return String request payload
402          */
403         def String UpdateNetworkVolumeRequest(requeryAAIVolGrpNameResponse, heatStackId) {
404                 String requestPayload = ""
405                 if (requeryAAIVolGrpNameResponse != null) {
406                         def groupId = utils.getNodeText(requeryAAIVolGrpNameResponse, "volume-group-id")
407                         def volumeName = utils.getNodeText(requeryAAIVolGrpNameResponse, "volume-group-name")
408                         def vnfType = utils.getNodeText(requeryAAIVolGrpNameResponse, "vnf-type")
409                         def resourceVersion = utils.getNodeText(requeryAAIVolGrpNameResponse, "resource-version")
410                         def relationshipList = ""
411                         if (utils.nodeExists(requeryAAIVolGrpNameResponse, "relationship")) {
412                                 relationshipList = rebuildRelationship(requeryAAIVolGrpNameResponse)
413                         }
414
415                         requestPayload =
416                                 """<volume-group xmlns="http://org.onap.so/v6">
417                                         <volume-group-id>${MsoUtils.xmlEscape(groupId)}</volume-group-id>
418                                         <volume-group-name>${MsoUtils.xmlEscape(volumeName)}</volume-group-name>
419                                         <heat-stack-id>${MsoUtils.xmlEscape(heatStackId)}</heat-stack-id>
420                                         <vnf-type>${MsoUtils.xmlEscape(vnfType)}</vnf-type>
421                                         <orchestration-status>Active</orchestration-status>
422                                         <resource-version>${MsoUtils.xmlEscape(resourceVersion)}</resource-version>
423                                         ${relationshipList}
424                                  </volume-group>"""
425                 }
426
427                 return requestPayload
428         }
429
430         /**
431          * This method returns the string for Create Contrail Network payload
432          * @param requeryIdAAIResponse the response from AAI query by id
433          * @param createNetworkResponse the response of create network
434          * @return String contrailNetworkCreatedUpdate
435          */
436         def ContrailNetworkCreatedUpdate(requeryIdAAIResponse, createNetworkResponse, schemaVersion) {
437
438                 String contrailNetworkCreatedUpdate = ""
439                 if(requeryIdAAIResponse!=null && createNetworkResponse!=null) {
440
441                         def l3Network = utils.getNodeXml(requeryIdAAIResponse, "l3-network", false).replace("tag0:","").replace(":tag0","")
442                         def createNetworkContrailResponse = ""
443                         if (utils.nodeExists(createNetworkResponse, 'createNetworkResponse')) {
444                            createNetworkContrailResponse = utils.getNodeXml(createNetworkResponse, "createNetworkResponse", false).replace("tag0:","").replace(":tag0","")
445                         } else {
446                            createNetworkContrailResponse = utils.getNodeXml(createNetworkResponse, "updateNetworkContrailResponse", false).replace("tag0:","").replace(":tag0","")
447                         }
448
449                         // rebuild network
450                         def networkList = ["network-id", "network-name", "network-type", "network-role", "network-technology", "neutron-network-id", "is-bound-to-vpn", "service-id", "network-role-instance", "resource-version", "resource-model-uuid", "orchestration-status", "heat-stack-id", "mso-catalog-key", "contrail-network-fqdn",
451                                                              "physical-network-name", "is-provider-network", "is-shared-network", "is-external-network"]
452                         String rebuildNetworkElements = buildNetworkElements(l3Network, createNetworkContrailResponse, networkList)
453
454                         // rebuild 'subnets'
455                         def rebuildSubnetList = ""
456                         if (utils.nodeExists(requeryIdAAIResponse, 'subnet')) {
457                              rebuildSubnetList = buildSubnets(requeryIdAAIResponse, createNetworkResponse)
458                         }
459
460                         // rebuild 'segmentation-assignments'
461                         def rebuildSegmentationAssignments = ""
462                         if (utils.nodeExists(requeryIdAAIResponse, 'segmentation-assignments')) {
463                                 List elementList = ["segmentation-id", "resource-version"]
464                                 if (utils.nodeExists(requeryIdAAIResponse, 'segmentation-assignment')) {  // new tag
465                                     rebuildSegmentationAssignments =  buildXMLElements(requeryIdAAIResponse, "segmentation-assignments", "segmentation-assignment", elementList)
466                                 } else {
467                                    rebuildSegmentationAssignments =  buildXMLElements(requeryIdAAIResponse, "", "segmentation-assignments", elementList)
468                                 }   
469                         }
470
471                         // rebuild 'ctag-assignments' / rebuildCtagAssignments
472                         def rebuildCtagAssignmentsList = ""
473                         if (utils.nodeExists(requeryIdAAIResponse, 'ctag-assignment')) {
474                                 rebuildCtagAssignmentsList = rebuildCtagAssignments(requeryIdAAIResponse)
475                         }
476
477                         // rebuild 'relationship'
478                         def relationshipList = ""
479                         if (utils.nodeExists(requeryIdAAIResponse, 'relationship-list')) {
480                                 String rootRelationshipData = getFirstNodeXml(requeryIdAAIResponse, "relationship-list").drop(38).trim().replace("tag0:","").replace(":tag0","")
481                                 if (utils.nodeExists(rootRelationshipData, 'relationship')) {
482                                         relationshipList = rebuildRelationship(rootRelationshipData)
483                                 }
484                         }
485
486                         //Check for optional contrail network fqdn within CreateNetworkResponse
487                         String contrailNetworkFQDN
488                         if(utils.nodeExists(createNetworkResponse, "contrail-network-fqdn")){
489                                 contrailNetworkFQDN = utils.getNodeXml(createNetworkResponse, "contrail-network-fqdn")
490                                 contrailNetworkFQDN = utils.removeXmlNamespaces(contrailNetworkFQDN)
491                                 contrailNetworkFQDN = utils.removeXmlPreamble(contrailNetworkFQDN)
492                         }else{
493                                 contrailNetworkFQDN = ""
494                         }
495
496                         contrailNetworkCreatedUpdate =
497                                  """<l3-network xmlns="${schemaVersion}">
498                                                 ${rebuildNetworkElements}
499                                                 ${rebuildSubnetList}
500                                                 ${rebuildSegmentationAssignments}
501                                                 ${rebuildCtagAssignmentsList}
502                                                 ${relationshipList}
503                                                 ${contrailNetworkFQDN}
504                                       </l3-network>""".trim()
505
506                 }
507                         return contrailNetworkCreatedUpdate
508         }
509
510
511
512         /**
513          * This method returns the value for the name paramName.
514          *   Ex:   <network-params>
515          *            <param name="shared">1</param>
516          *            <param name="external">0</external>
517          *         </network-params>
518          *
519          * @param xmlInput the XML document
520          * @param paramName the param name (ex: 'shared')
521          * @return a param value for 'shared' (ex: '1')
522          */
523         def getParameterValue(xmlInput, paramName) {
524                 def rtn=""
525                 if(xmlInput!=null){
526                         def xml= new XmlSlurper().parseText(xmlInput)
527                         rtn= xml.'**'.find {param->param.'@name'.text() == paramName}
528                 }
529                 if (rtn==null) {
530                         return ""
531                 } else {
532                    return rtn
533                 }
534         }
535
536         /**
537          * This method returns the name of param if found/match with paramName.
538          *   Ex:   <network-params>
539          *            <param name="shared">1</param>
540          *            <param name="external">0</external>
541          *         </network-params>
542          *
543          * @param xmlInput the XML document
544          * @param paramName the param name (ex: 'shared', )
545          * @return a param name for 'shared' (ex: 'shared' if found)
546          */
547         def getParameterName(xmlInput, paramName) {
548                 def rtn=""
549                 if(xmlInput!=null){
550                         def xml= new XmlSlurper().parseText(xmlInput)
551                         try {
552                                 rtn= xml.'**'.find {param->param.'@name' == paramName}.'@name'
553                         } catch (Exception ex) {
554                             rtn=""
555                         }
556                 }
557                 if (rtn==null || rtn=="") {
558                         return ""
559                 } else {
560                    return rtn
561                 }
562         }
563
564         /**
565          * This method returns the networkParams xml string.
566          *   Ex: input:
567          *         <network-params>
568          *            <param name="shared">1</param>
569          *            <param name="external">0</external>
570          *         </network-params>
571          *
572          *   Sample result:
573          *         <networkParams>
574      *            <shared>1</shared>
575      *            <external>0</external>
576      *         </networkParams>
577      *
578          */
579
580         def buildParams(networkParams) {
581                 def build = ""
582                         def netParams = new XmlParser().parseText(networkParams)
583                         try {
584                                 def paramsList = netParams.'**'.findAll {param->param.'@name'}.'@name'
585                                 if (paramsList.size() > 0) {
586                                         build += "<networkParams>"
587                                         for (i in 0..paramsList.size()-1) {
588                         def name = netParams.'**'.find {param->param.'@name' == paramsList[i]}.'@name'
589                                                 def value= netParams.'**'.find {param->param.'@name' == paramsList[i]}.text()
590                                                 build += "<${name}>${MsoUtils.xmlEscape(value)}</${name}>"
591                                         }
592                                         build += "</networkParams>"
593                                 }
594
595                         } catch (Exception ex) {
596                                 println ' buildParams error - ' + ex.getMessage()
597                                 build = ""
598                         }
599                 return build
600         }
601
602         def getVlans(xmlInput) {
603                 def rtn = ""
604                 if (xmlInput!=null) {
605                         def vlansList = getListWithElements(xmlInput, 'vlans')
606                         def vlansListSize = vlansList.size()
607                         if (vlansListSize > 0) {
608                                 for (i in 0..vlansListSize-1) {
609                                    rtn += '<vlans>'+vlansList[i]+'</vlans>'
610                                 }
611                         }
612                 }
613                 return rtn
614
615
616         }
617
618         /**
619          * This method returns the uri value for the vpn bindings.
620          * Return the a list of value of vpn binding in the <related-link> string.
621          * Ex.
622          *   <relationship-list>
623          *      <relationship>
624          *          <related-to>vpn-binding</related-to>
625          *          <related-link>https://aai-app-e2e.test.openecomp.com:8443/aai/v6/network/vpn-bindings/vpn-binding/85f015d0-2e32-4c30-96d2-87a1a27f8017/</related-link>
626          *          <relationship-data>
627          *             <relationship-key>vpn-binding.vpn-id</relationship-key>
628          *             <relationship-value>85f015d0-2e32-4c30-96d2-87a1a27f8017</relationship-value>
629          *          </relationship-data>
630          *       </relationship>
631          *              <relationship>
632          *              <related-to>vpn-binding</related-to>
633          *                      <related-link>https://aai-ext1.test.openecomp.com:8443/aai/v6/network/vpn-bindings/vpn-binding/24a4b507-853a-4a38-99aa-05fcc54be24d/</related-link>
634          *                      <relationship-data>
635          *                         <relationship-key>vpn-binding.vpn-id</relationship-key>
636          *                         <relationship-value>24a4b507-853a-4a38-99aa-05fcc54be24d</relationship-value>
637          *                  </relationship-data>
638          *                      <related-to-property>
639          *                        <property-key>vpn-binding.vpn-name</property-key>
640          *                        <property-value>oam_protected_net_6_MTN5_msotest1</property-value>
641          *                      </related-to-property>
642          *              </relationship>
643          * @param xmlInput the XML document
644          * @return a list of vpn binding values
645          *            ex: ['aai/v6/network/vpn-bindings/vpn-binding/85f015d0-2e32-4c30-96d2-87a1a27f8017/', 'aai/v6/network/vpn-bindings/vpn-binding/c980a6ef-3b88-49f0-9751-dbad8608d0a6/']
646          *
647          **/
648         def getVnfBindingObject(xmlInput) {
649                 //def rtn = null
650                 List rtn = []
651                 if (xmlInput!=null) {
652                         def relationshipList = getListWithElements(xmlInput, 'relationship')
653                         def relationshipListSize = relationshipList.size()
654                         if (relationshipListSize > 0) {
655                                 for (i in 0..relationshipListSize-1) {
656                                    def relationshipXml = XmlUtil.serialize(relationshipList[i])
657                                    if (utils.getNodeText(relationshipXml, 'related-to') == "vpn-binding") {
658                                           def relatedLink = utils.getNodeText(relationshipXml, 'related-link')
659                                           if (relatedLink != null || relatedLink != "") {
660                                                  rtn.add(relatedLink.substring(relatedLink.indexOf("/aai/"), relatedLink.length()))
661                                           }
662                                    }
663                                 }
664                         }
665                 }
666                 return rtn
667         }
668         /**
669          * similar to VNF bindings method
670         * @param xmlInput the XML document
671         * @return a list of network policy values
672         *            ex: ['aai/v$/network/network-policies/network-policy/cee6d136-e378-4678-a024-2cd15f0ee0cg', 'aai/v$/network/network-policies/network-policy/cee6d136-e378-4678-a024-2cd15f0ee0cg']
673         *
674         **/
675         def getNetworkPolicyObject(xmlInput) {
676                 //def rtn = null
677                 List rtn = []
678                 if (xmlInput!=null) {
679                         def relationshipList = getListWithElements(xmlInput, 'relationship')
680                         def relationshipListSize = relationshipList.size()
681                         if (relationshipListSize > 0) {
682                                 for (i in 0..relationshipListSize-1) {
683                                    def relationshipXml = XmlUtil.serialize(relationshipList[i])
684                                    if (utils.getNodeText(relationshipXml, 'related-to') == "network-policy") {
685                                           def relatedLink = utils.getNodeText(relationshipXml, 'related-link')
686                                           if (relatedLink != null || relatedLink != "") {
687                                                  rtn.add(relatedLink.substring(relatedLink.indexOf("/aai/"), relatedLink.length()))
688                                           }
689                                    }
690                                 }
691                         }
692                 }
693                 return rtn
694         }
695
696         /**
697          * similar to network policymethod
698         * @param xmlInput the XML document
699         * @return a list of network policy values
700         *            ex: ['aai/v$/network/route-table-references/route-table-reference/refFQDN1', 'aai/v$/network/route-table-references/route-table-reference/refFQDN2']
701         *
702         **/
703         def getNetworkTableRefObject(xmlInput) {
704                 //def rtn = null
705                 List rtn = []
706                 if (xmlInput!=null) {
707                         def relationshipList = getListWithElements(xmlInput, 'relationship')
708                         def relationshipListSize = relationshipList.size()
709                         if (relationshipListSize > 0) {
710                                 for (i in 0..relationshipListSize-1) {
711                                    def relationshipXml = XmlUtil.serialize(relationshipList[i])
712                                    if (utils.getNodeText(relationshipXml, 'related-to') == "route-table-reference") {
713                                           def relatedLink = utils.getNodeText(relationshipXml, 'related-link')
714                                           if (relatedLink != null || relatedLink != "") {
715                                                  rtn.add(relatedLink.substring(relatedLink.indexOf("/aai/"), relatedLink.length()))
716                                           }
717                                    }
718                                 }
719                         }
720                 }
721                 return rtn
722         }
723
724         /**
725          * similar to network policymethod
726         * @param xmlInput the XML document
727         * @return a list of IDs for related VNF instances
728         *
729         **/
730         def getRelatedVnfIdList(xmlInput) {
731                 //def rtn = null
732                 List rtn = []
733                 if (xmlInput!=null) {
734                         def relationshipList = getListWithElements(xmlInput, 'relationship')
735                         def relationshipListSize = relationshipList.size()
736                         if (relationshipListSize > 0) {
737                                 for (i in 0..relationshipListSize-1) {
738                                    def relationshipXml = XmlUtil.serialize(relationshipList[i])
739                                    if (utils.getNodeText(relationshipXml, 'related-to') == "generic-vnf") {
740                                           def relatedLink = utils.getNodeText(relationshipXml, 'related-link')
741                                           if (relatedLink != null || relatedLink != "") {
742                                                  if (relatedLink.substring(relatedLink.indexOf("/generic-vnf/")+13, relatedLink.length()).contains('/')) {
743                                                          rtn.add(relatedLink.substring(relatedLink.indexOf("/generic-vnf/")+13, relatedLink.length()-1))
744                                                  } else {
745                                                      rtn.add(relatedLink.substring(relatedLink.indexOf("/generic-vnf/")+13, relatedLink.length()))
746                                                  }
747                                           }
748                                    }
749                                 }
750                         }
751                 }
752                 return rtn
753         }
754
755         /**
756          * similar to network policymethod
757         * @param xmlInput the XML document
758         * @return a list of IDs for related Network instances
759         *
760         **/
761         def getRelatedNetworkIdList(xmlInput) {
762                 //def rtn = null
763                 List rtn = []
764                 if (xmlInput!=null) {
765                         def relationshipList = getListWithElements(xmlInput, 'relationship')
766                         def relationshipListSize = relationshipList.size()
767                         if (relationshipListSize > 0) {
768                                 for (i in 0..relationshipListSize-1) {
769                                    def relationshipXml = XmlUtil.serialize(relationshipList[i])
770                                    if (utils.getNodeText(relationshipXml, 'related-to') == "l3-network") {
771                                           def relatedLink = utils.getNodeText(relationshipXml, 'related-link')
772                                           if (relatedLink != null || relatedLink != "") {
773                                                  if (relatedLink.substring(relatedLink.indexOf("/l3-network/")+12, relatedLink.length()).contains('/')) {
774                                                          rtn.add(relatedLink.substring(relatedLink.indexOf("/l3-network/")+12, relatedLink.length()-1))
775                                                  } else {
776                                                      rtn.add(relatedLink.substring(relatedLink.indexOf("/l3-network/")+12, relatedLink.length()))
777                                                  }
778                                           }
779                                    }
780                                 }
781                         }
782                 }
783                 return rtn
784         }
785
786         def isVfRelationshipExist(xmlInput) {
787                 Boolean rtn = false
788                 if (xmlInput!=null) {
789                         def relationshipList = getListWithElements(xmlInput, 'relationship')
790                         def relationshipListSize = relationshipList.size()
791                         if (relationshipListSize > 0) {
792                                 for (i in 0..relationshipListSize-1) {
793                                    def relationshipXml = XmlUtil.serialize(relationshipList[i])
794                                    if (utils.getNodeText(relationshipXml, 'related-to') == "vf-module") {
795                                              rtn = true
796                                    }
797                                 }
798                         }
799                 }
800                 return rtn
801
802         }
803
804         def getCloudRegion(xmlInput) {
805                 String lcpCloudRegion = ""
806                 if (xmlInput!=null) {
807                         def relationshipList = getListWithElements(xmlInput, 'relationship')
808                         def relationshipListSize = relationshipList.size()
809                         if (relationshipListSize > 0) {
810                                 for (i in 0..relationshipListSize-1) {
811                                    def relationshipXml = XmlUtil.serialize(relationshipList[i])
812                                    if (utils.getNodeText(relationshipXml, 'related-to') == "cloud-region") {
813                                           def relatedLink = utils.getNodeText(relationshipXml, 'related-link')
814                                           if (relatedLink != null || relatedLink != "") {
815                                                 AAIResourceUri aaiUri = AAIUriFactory.createResourceFromExistingURI(AAIObjectType.CLOUD_REGION, UriBuilder.fromUri(relatedLink).build())
816                                                 lcpCloudRegion = aaiUri.getURIKeys().getOrDefault("cloud-region", "")
817                                           }
818                                    }
819                                 }
820                         }
821                 }
822                 return lcpCloudRegion
823         }
824
825         def getTenantId(xmlInput) {
826                 String tenantId = ""
827                 if (xmlInput!=null) {
828                         def relationshipList = getListWithElements(xmlInput, 'relationship')
829                         def relationshipListSize = relationshipList.size()
830                         if (relationshipListSize > 0) {
831                                 for (i in 0..relationshipListSize-1) {
832                                    def relationshipXml = XmlUtil.serialize(relationshipList[i])
833                                    if (utils.getNodeText(relationshipXml, 'related-to') == "tenant") {
834                                           def relatedLink = utils.getNodeText(relationshipXml, 'related-link')
835                                           if (relatedLink != null || relatedLink != "") {
836                                                  tenantId = relatedLink.substring(relatedLink.indexOf("/tenant/")+8, relatedLink.length())
837                                                  if (tenantId.contains('/')) {
838                                                          tenantId = relatedLink.substring(relatedLink.indexOf("/tenant/")+8, relatedLink.length()-1)
839                                                  }
840                                           }
841                                    }
842                                 }
843                         }
844                 }
845                 return tenantId
846         }
847
848         def isInstanceValueMatch(linkResource, globalSubscriberId, serviceType) {
849                 Boolean rtn = false
850                 try {
851                         String globalSubscriberIdLink = linkResource.substring(linkResource.indexOf("/customer/")+10, linkResource.indexOf("/service-subscriptions"))
852                         String serviceTypeLink = linkResource.substring(linkResource.indexOf("/service-subscription/")+22, linkResource.indexOf("/service-instances"))
853                         if (globalSubscriberIdLink == globalSubscriberId) {
854                                         rtn = true
855                         } else {
856                                 if (serviceTypeLink == serviceType) {
857                                         rtn = true
858                                 }
859                         }
860
861                 } catch (Exception ex) {
862                     println 'Exception - ' + ex.getMessage()
863                         return false
864                 }
865         return rtn
866         }
867
868         def getListWithElements(xmlInput, groupName) {
869                 def rtn = ""
870                 if (xmlInput != null) {
871                         def relationshipData = new XmlSlurper().parseText(xmlInput)
872                         rtn = relationshipData.'**'.findAll {it.name() == groupName}
873                 }
874                 return rtn
875
876         }
877
878         // build network single elements
879         def buildNetworkElements(l3Network, createNetworkContrailResponse, networkList) {
880                 def replaceNetworkId = ""
881                 def replaceNeutronNetworkId = ""
882                 def replaceContrailNetworkFqdn = ""
883                 if (l3Network != null && createNetworkContrailResponse != null) {
884                         if (utils.nodeExists(l3Network, 'heat-stack-id')) {
885                                 replaceNetworkId = utils.getNodeText(l3Network, 'heat-stack-id')
886                         } else {
887                                 if (utils.nodeExists(createNetworkContrailResponse, 'networkStackId')) {
888                                         replaceNetworkId = utils.getNodeText(createNetworkContrailResponse, 'networkStackId')
889                                 }
890                         }
891                         if (utils.nodeExists(l3Network, 'neutron-network-id')) {
892                                 replaceNeutronNetworkId = utils.getNodeText(l3Network, 'neutron-network-id')
893                         } else {
894                                 if (utils.nodeExists(createNetworkContrailResponse, 'neutronNetworkId')) {
895                                         replaceNeutronNetworkId = utils.getNodeText(createNetworkContrailResponse, 'neutronNetworkId')
896                                 }
897                         }
898                         if (utils.nodeExists(l3Network, 'contrail-network-fqdn')) {
899                                 replaceContrailNetworkFqdn = utils.getNodeText(l3Network, 'contrail-network-fqdn')
900                         } else {
901                                 if (utils.nodeExists(createNetworkContrailResponse, 'networkFqdn')) {
902                                         replaceContrailNetworkFqdn = utils.getNodeText(createNetworkContrailResponse, 'networkFqdn')
903                                 }
904                         }
905                 }
906
907                 String var = ""
908                 def xmlNetwork = ""
909                 if (l3Network != null) {
910                         for (element in networkList) {
911                                 def xml= new XmlSlurper().parseText(l3Network)
912                                 var = xml.'**'.find {it.name() == element}
913                                 if (var == null) {
914                                         if (element=="orchestration-status") {
915                                                 if (var.toString() == 'pending-create' || var.toString() == 'PendingCreate') {
916                                                         xmlNetwork += "<"+element+">"+"Created"+"</"+element+">"
917                                             } else { //pending-update or PendingUpdate
918                                                         xmlNetwork += "<"+element+">"+"Active"+"</"+element+">"
919                                             }
920                                         }       
921                                         if (element=="heat-stack-id") {
922                                                 if (replaceNetworkId != "") {
923                                                         xmlNetwork += "<"+element+">"+replaceNetworkId+"</"+element+">"
924                                                 }
925                                         }
926                                         if (element=="neutron-network-id") {
927                                                 if (replaceNeutronNetworkId != "") {
928                                                         xmlNetwork += "<"+element+">"+replaceNeutronNetworkId+"</"+element+">"
929                                                 }
930                                         }
931                                         if (element=="contrail-network-fqdn") {
932                                                 if (replaceContrailNetworkFqdn != "") {
933                                                         xmlNetwork += "<"+element+">"+replaceContrailNetworkFqdn+"</"+element+">"
934                                                 }
935                                         }
936
937                                 } else {
938                                         if (element=="orchestration-status") {
939                                            if (element=="orchestration-status") {
940                                                   if (var.toString() == 'pending-create' || var.toString() == 'PendingCreate') {
941                                                       xmlNetwork += "<"+element+">"+"Created"+"</"+element+">"
942                                                   } else { //pending-update or PendingUpdate
943                                                           xmlNetwork += "<"+element+">"+"Active"+"</"+element+">"
944                                                   }
945                                            }   
946                                     } else {
947                                     xmlNetwork += "<"+element+">"+var.toString()+"</"+element+">"
948                                         }
949                                 }       
950                          }
951                 }
952                 return xmlNetwork
953         }
954
955         def buildSubnets(requeryIdAAIResponse, createNetworkResponse) {
956                 def rebuildingSubnets = ""
957                 if (requeryIdAAIResponse != null && utils.nodeExists(requeryIdAAIResponse, 'subnets')) {
958                         def subnetIdMapValue = ""
959                         def subnetsGroup = utils.getNodeXml(requeryIdAAIResponse, "subnets", false)
960                         def subnetsData = new XmlSlurper().parseText(subnetsGroup)
961                         rebuildingSubnets += "<subnets>"
962                         try {
963                                 def subnets = subnetsData.'**'.findAll {it.name() == "subnet"}
964                                 def subnetsSize = subnets.size()
965                                 for (i in 0..subnetsSize-1) {
966                                    def subnet = subnets[i]
967                                    def subnetXml = XmlUtil.serialize(subnet)
968                                    def orchestrationStatus = utils.getNodeText(subnetXml, "orchestration-status")
969                                    if (orchestrationStatus == "PendingDelete" || orchestrationStatus == "pending-delete") {
970                                            // skip, do not include in processing, remove!!!
971                                    } else {
972                                       def subnetList = ["subnet-id", "neutron-subnet-id", "gateway-address", "network-start-address", "cidr-mask", "ip-version", "orchestration-status", "dhcp-enabled", "dhcp-start", "dhcp-end", "subnet-role", "resource-version", "subnet-name", "ip-assignment-direction", "host-routes"]
973                                       rebuildingSubnets += buildSubNetworkElements(subnetXml, createNetworkResponse, subnetList, "subnet")
974                                    }      
975                                 }
976                                 if (utils.nodeExists(subnetsData, 'relationship')) {
977                                         rebuildingSubnets = rebuildRelationship(requeryIdAAIResponse)
978                                 }
979
980                         } catch (Exception ex) {
981                                 // error
982                         } finally {
983                                 rebuildingSubnets += "</subnets>"
984                         }
985                 }
986                 return rebuildingSubnets
987         }
988
989         def buildSubnets(queryIdResponse) {
990                 def rebuildingSubnets = ""
991                 def subnetsData = new XmlSlurper().parseText(queryIdResponse)
992                 //rebuildingSubnets += "<subnets>"
993                 try {
994                         def subnets = subnetsData.'**'.findAll {it.name() == "subnet"}
995                         def subnetsSize = subnets.size()
996                         for (i in 0..subnetsSize-1) {
997                            def subnet = subnets[i]
998                            def subnetXml = XmlUtil.serialize(subnet)
999                            def orchestrationStatus = utils.getNodeText(subnetXml, "orchestration-status")
1000                            if (orchestrationStatus == "pending-delete" || orchestrationStatus == "PendingDelete") {
1001                                    // skip, do not include in processing, remove!!!
1002                            } else {
1003                                         def subnetList = ["dhcp-start", "dhcp-end", "network-start-address", "cidr-mask", "dhcp-enabled", "gateway-address", "ip-version", "subnet-id", "subnet-name", "ip-assignment-direction", "host-routes"]
1004                                         rebuildingSubnets += buildSubNetworkElements(subnetXml, subnetList, "subnets")
1005                                         //rebuildingSubnets += buildSubNetworkElements(subnetXml, subnetList, "")
1006                            }    
1007                         }
1008                 } catch (Exception ex) {
1009                    //
1010                 } finally {
1011                   //rebuildingSubnets += "</subnets>"
1012                 }
1013                 return rebuildingSubnets
1014         }
1015
1016
1017         // build subnet sub-network single elements
1018         def buildSubNetworkElements(subnetXml, createNetworkResponse, elementList, parentName) {
1019                 String var = ""
1020                 def xmlBuild = ""
1021                 if (parentName != "") {
1022                    xmlBuild += "<"+parentName+">"
1023                 }
1024                 if (subnetXml != null) {
1025                         for (element in elementList) {
1026                           def xml= new XmlSlurper().parseText(subnetXml)
1027                           var = xml.'**'.find {it.name() == element}
1028                           if (var != null) {
1029                                  if (element=="orchestration-status") {
1030                                         if(var.toString() == 'pending-create' || var.toString() == 'PendingCreate') {   
1031                                                 xmlBuild += "<"+element+">"+"Created"+"</"+element+">"
1032                                         } else { // pending-update or PendingUpdate'
1033                                            xmlBuild += "<"+element+">"+"Active"+"</"+element+">"
1034                                         }
1035                                  } else { // "subnet-id", "neutron-subnet-id"
1036                                          if (element=="subnet-id") {
1037                                                  if (utils.nodeExists(createNetworkResponse, "subnetMap")) {
1038                                                          xmlBuild += "<"+element+">"+var.toString()+"</"+element+">"
1039                                                          String neutronSubnetId = extractNeutSubId(createNetworkResponse, var.toString())
1040                                                          xmlBuild += "<neutron-subnet-id>"+neutronSubnetId+"</neutron-subnet-id>"
1041                                                  }
1042                                          } else {
1043                                              if (element=="neutron-subnet-id") {
1044                                // skip
1045                                                  } else {
1046                                                          if (element=="host-routes") {
1047                                                                  if (subnetXml.contains("host-routes")) {
1048                                                                          List elementRoute = ["host-route-id", "route-prefix", "next-hop", "next-hop-type", "resource-version"]
1049                                                                          xmlBuild += buildXMLElements(subnetXml, "host-routes", "host-route", elementRoute)
1050                                                                  }
1051                                                          } else {         
1052                                                                 xmlBuild += "<"+element+">"+var.toString()+"</"+element+">"
1053                                                          }        
1054                                                  }
1055                                          }
1056                                  }
1057                           }
1058                         }
1059
1060                 }
1061                 if (parentName != "") {
1062                    xmlBuild += "</"+parentName+">"
1063                 }
1064                 return xmlBuild
1065         }
1066
1067         // build subnet sub-network single elements
1068         def buildSubNetworkElements(subnetXml, elementList, parentName) {
1069                 def var = ""
1070                 def xmlBuild = ""
1071                 if (parentName != "") {
1072                         xmlBuild += "<"+parentName+">"
1073                  }
1074                 if (subnetXml != null) {
1075                     def networkStartAddress = ""
1076                         for (element in elementList) {
1077                                 def xml= new XmlSlurper().parseText(subnetXml)
1078                                 var = xml.'**'.find {it.name() == element}
1079                                 if (element == "dhcp-start") {
1080                                         xmlBuild += "<allocationPools>"
1081                                         if (var.toString() == 'null') {
1082                                                 xmlBuild += "<start>"+""+"</start>"
1083                                         } else {
1084                                                 xmlBuild += "<start>"+var.toString()+"</start>"
1085                                         }
1086                                 }
1087                                 if (element == "dhcp-end") {
1088                                         if (var.toString() == 'null') {
1089                                                 xmlBuild += "<end>"+""+"</end>"
1090                                         } else {
1091                                                 xmlBuild += "<end>"+var.toString()+"</end>"
1092                                         }
1093                                         xmlBuild += "</allocationPools>"
1094                                 }
1095                                 if (element == "network-start-address" || element == "cidr-mask") {
1096                                         if (element == "network-start-address") {
1097                                                 networkStartAddress = var.toString()
1098                                         }
1099                                         if (element == "cidr-mask") {
1100                                                 xmlBuild += "<cidr>"+networkStartAddress+"/"+var.toString()+"</cidr>"
1101                                         }
1102                                 }
1103                                 if (element == "dhcp-enabled") {
1104                                         xmlBuild += "<enableDHCP>"+var.toString()+"</enableDHCP>"
1105                                 }
1106                                 if (element == "gateway-address") {
1107                                         xmlBuild += "<gatewayIp>"+var.toString()+"</gatewayIp>"
1108                                 }
1109                                 if (element == "ip-version") {
1110                                         String ipVersion = getIpvVersion(var.toString())
1111                                         xmlBuild += "<ipVersion>"+ipVersion+"</ipVersion>"
1112                                 }
1113                                 if (element == "subnet-id") {
1114                                         xmlBuild += "<subnetId>"+var.toString()+"</subnetId>"
1115                                 }
1116                                 if ((element == "subnet-name") && (var != null)) {
1117                                         xmlBuild += "<subnetName>"+var.toString()+"</subnetName>"
1118                                 }
1119                                 if ((element == "ip-assignment-direction") && (var != null)) {
1120                                         xmlBuild += "<addrFromStart>"+var.toString()+"</addrFromStart>"
1121                                 }
1122                                 if (element == "host-routes") {
1123                                         def routes = ""
1124                                         if (subnetXml.contains("host-routes")) {
1125                                                 routes = buildHostRoutes(subnetXml)
1126                                         }
1127                                         xmlBuild += routes 
1128                                 }       
1129                                 
1130                         }
1131                 }
1132                 if (parentName != "") {
1133                         xmlBuild += "</"+parentName+">"
1134                  }
1135                 return xmlBuild
1136         }
1137
1138         // rebuild host-routes
1139         def buildHostRoutes(subnetXml) {
1140                 List  routeElementList = ["host-route-id", "route-prefix", "next-hop", "next-hop-type", "resource-version"]
1141                 def hostRoutes = buildXMLElements(subnetXml, "host-routes", "host-route", routeElementList)
1142                 def buildHostRoutes = ""
1143                 def var = ""
1144                 if (hostRoutes!=null) {
1145                         def routesData = new XmlSlurper().parseText(hostRoutes)
1146                         def routes = routesData.'**'.findAll {it.name() == "host-route"}
1147                         def routesSize = routes.size()
1148                         for (i in 0..routesSize-1) {
1149                            buildHostRoutes += "<hostRoutes>"
1150                            def route = routes[i]
1151                            def routeXml = XmlUtil.serialize(route)
1152                            List  elementList = ["route-prefix", "next-hop"]
1153                            for (element in elementList) {
1154                                    def xml= new XmlSlurper().parseText(routeXml)
1155                                    var = xml.'**'.find {it.name() == element}
1156                                    if (element == "route-prefix") {
1157                                            buildHostRoutes += "<prefix>"+var.toString()+"</prefix>"
1158                                    }
1159                                    if (element == "next-hop") {
1160                                            buildHostRoutes += "<nextHop>"+var.toString()+"</nextHop>"
1161                                    }
1162                            }
1163                            buildHostRoutes += "</hostRoutes>"
1164                         }   
1165                 }               
1166                 return buildHostRoutes          
1167                 
1168         }
1169         
1170         // rebuild ctag-assignments
1171         def rebuildCtagAssignments(xmlInput) {
1172                 def rebuildingCtagAssignments = ""
1173                 if (xmlInput!=null) {
1174                         def ctagAssignmentsData = new XmlSlurper().parseText(xmlInput)
1175                         rebuildingCtagAssignments += "<ctag-assignments>"
1176                         def ctagAssignments = ctagAssignmentsData.'**'.findAll {it.name() == "ctag-assignment"}
1177                         def ctagAssignmentsSize = ctagAssignments.size()
1178                         for (i in 0..ctagAssignmentsSize-1) {
1179                                 def ctagAssignment = ctagAssignments[i]
1180                                 def ctagAssignmentXml = XmlUtil.serialize(ctagAssignment)
1181                                 rebuildingCtagAssignments += "<ctag-assignment>"
1182                                 List elementList = ["vlan-id-inner", "resource-version"]
1183                                 rebuildingCtagAssignments +=  buildXMLElements(ctagAssignmentXml, ""      , "", elementList)
1184                                 if (utils.nodeExists(ctagAssignmentXml, 'relationship')) {
1185                                         rebuildingCtagAssignments += rebuildRelationship(ctagAssignmentXml)
1186                                 }
1187                                 rebuildingCtagAssignments += "</ctag-assignment>"
1188                         }
1189                         rebuildingCtagAssignments += "</ctag-assignments>"
1190                 }
1191                 return rebuildingCtagAssignments
1192         }
1193
1194         // rebuild 'relationship-list'
1195         def rebuildRelationship(xmlInput) {
1196                 def rebuildingSubnets = ""
1197                 if (xmlInput!=null) {
1198                         def subnetsData = new XmlSlurper().parseText(xmlInput)
1199                         rebuildingSubnets += "<relationship-list>"
1200                         def relationships = subnetsData.'**'.findAll {it.name() == "relationship"}
1201                         def relationshipsSize = relationships.size()
1202                         for (i in 0..relationshipsSize-1) {
1203                                 def relationship = relationships[i]
1204                                 def relationshipXml = XmlUtil.serialize(relationship)
1205                                 rebuildingSubnets += "<relationship>"
1206                                 def relationshipList = ["related-to", "related-link"]
1207                                 rebuildingSubnets += buildSubNetworkElements(relationshipXml, "", relationshipList, "")
1208                                 if (utils.nodeExists(relationshipXml, 'relationship-data')) {
1209                                         def relationshipDataXmlData = new XmlSlurper().parseText(relationshipXml)
1210                                         def relationshipsData = relationshipDataXmlData.'**'.findAll {it.name() == "relationship-data"}
1211                                         def relationshipsDataSize = relationshipsData.size()
1212                                         for (j in 0..relationshipsDataSize-1) {
1213                                                 def relationshipData = relationshipsData[j]
1214                                                 def relationshipDataXml = XmlUtil.serialize(relationshipData)
1215                                                 def relationshipDataList =  ["relationship-key", "relationship-value"]
1216                                                 rebuildingSubnets += buildXMLElements(relationshipDataXml, "", "relationship-data", relationshipDataList)
1217                                         }
1218                                 }
1219                                 if (utils.nodeExists(relationshipXml, 'related-to-property')) {
1220                                         def relationshipDataXmlData = new XmlSlurper().parseText(relationshipXml)
1221                                         def relationshipsData = relationshipDataXmlData.'**'.findAll {it.name() == "related-to-property"}
1222                                         def relationshipsDataSize = relationshipsData.size()
1223                                         for (j in 0..relationshipsDataSize-1) {
1224                                                 def relationshipData = relationshipsData[j]
1225                                                 def relationshipDataXml = XmlUtil.serialize(relationshipData)
1226                                                 def relationshipDataList =  ["property-key", "property-value"]
1227                                                 rebuildingSubnets += buildXMLElements(relationshipDataXml, "", "related-to-property", relationshipDataList)
1228                                         }
1229                                 }
1230
1231                                 rebuildingSubnets += "</relationship>"
1232                         }
1233                         rebuildingSubnets += "</relationship-list>"
1234                 }
1235                 return rebuildingSubnets
1236         }
1237
1238         def buildVlans(queryIdResponse) {
1239                 def rebuildingSubnets = "<vlans>"
1240                 def subnetsData = new XmlSlurper().parseText(queryIdResponse)
1241
1242                 try {
1243                         def subnets = subnetsData.'**'.findAll {it.name() == "segmentation-assignments"}
1244                         def subnetsSize = subnets.size()
1245                         for (i in 0..subnetsSize-1) {
1246                            def subnet = subnets[i]
1247                            def subnetXml = XmlUtil.serialize(subnet)
1248
1249                            String vlan = utils.getNodeText(subnetXml, "segmentation-id")
1250                            if (i>0){
1251                                    rebuildingSubnets += ","
1252                            }
1253                            rebuildingSubnets += vlan
1254                         }
1255                 } catch (Exception ex) {
1256                    //
1257                 } finally {
1258                   //rebuildingSubnets += "</subnets>"
1259                 rebuildingSubnets += "</vlans>"
1260                 }
1261                 return rebuildingSubnets
1262         }
1263
1264         /* Utility code to rebuild xml/elements in a list:
1265          * rebuild xml with 1) unbounded groups of elements; or
1266          *                  2) one group of elements; or
1267          *                  3) just one or more elements (in a list as argument)
1268          * @param xmlInput the XML document
1269          * @param parentName the parent name  (ex: 'inputs')
1270          * @param childrenName the chilrendName (ex: 'entry' as unbounded/occurs>1)
1271          * @param elementList the element list of children (ex: 'key', 'value')
1272          * @return a string of rebuild xml
1273          *
1274          * Ex 1: xmlInput:
1275          *    <ws:inputs>
1276          *       <ws:entry>
1277          *          <ws:key>name</ws:key>
1278          *          <ws:value>Edward</ws:value>
1279          *       </ws:entry>
1280          *       <ws:entry>
1281          *          <ws:key>age</ws:key>
1282          *          <ws:value>30</ws:value>
1283          *       </ws:entry>
1284          *       <ws:entry>
1285          *          <ws:key>age</ws:key>
1286          *          <ws:value>30</ws:value>
1287          *       </ws:entry>
1288          *    <ws:/inputs>
1289          * Usage:
1290          * List elementList = ["key", "value"]
1291          * String rebuild =  buildXMLElements(xmlInput, "inputs", "entry", elementList)
1292          *
1293          * Ex 2: xmlInput // no parent tag
1294          *   <ws:sdnc-request-header>
1295          *    <ws:svc-request-id>fec8ec88-151a-45c9-ad60-8233e0fc8ff2</ws:svc-request-id>
1296          *    <ws:svc-notification-url>https://localhost:8443/adapters/rest/SDNCNotify</ws:svc-notification-url>
1297          *    <ws:svc-action>assign</ws:svc-action>
1298          *   </ws:sdnc-request-header>
1299          * Usage:
1300          * List elementList = ["svc-request-id", "svc-notification-url", "svc-action"]
1301          * String rebuild =  buildXMLElements(xmlInput, ""      , "sdnc-request-header", elementList)  // no parent tag
1302          *
1303          * Ex 3: xmlInput // elements one after another (with no parent & children tag)
1304          * <ws:test-id>myTestid</ws:test-id>
1305          * <ws:test-user>myUser</ws:test-user>
1306          * Usage:
1307          * List elementList = ["test-id", "test-user"]
1308          * String rebuild =  buildXMLElements(xmlInput, ""      , "", elementList)
1309          *
1310          */
1311         def buildXMLElements(xmlInput, parentName, childrenName, elementList) {
1312                 def varChildren = ""
1313                 def var = ""
1314                 def xmlBuildUnbounded = ""
1315                 if (parentName!="") {xmlBuildUnbounded += "<"+parentName+">" +'\n'}
1316                 if (xmlInput != null) {
1317                         def xml= new XmlSlurper().parseText(xmlInput)
1318                         if (childrenName!="") {
1319                                 varChildren = xml.'**'.findAll {it.name() == childrenName}
1320                                 for (i in 0..varChildren.size()-1) {
1321                                         xmlBuildUnbounded += "<"+childrenName+">" +'\n'
1322                                         for (element in elementList) {
1323                                                 var = varChildren[i].'*'.find {it.name() == element}
1324                                            if (var != null) {
1325                                                   xmlBuildUnbounded += "<"+element+">"+var.toString()+"</"+element+">" +'\n'
1326                                            }
1327                                         }
1328                                         xmlBuildUnbounded += "</"+childrenName+">" +'\n'
1329                                 }
1330                         } else {
1331                                 for (element in elementList) {
1332                                         var = xml.'*'.find {it.name() == element}
1333                                         if (var != null) {
1334                                                 xmlBuildUnbounded += "<"+element+">"+var.toString()+"</"+element+">" +'\n'
1335                                         }
1336                                 }
1337                         }
1338
1339                 }
1340                 if (parentName!="") {xmlBuildUnbounded += "</"+parentName+">" +'\n'}
1341                 return xmlBuildUnbounded
1342          }
1343
1344         def getFirstNodeXml(xmlInput, element){
1345                 def nodeAsText = ""
1346                 def nodeToSerialize =  ""
1347                 if (xmlInput != null) {
1348                         def fxml= new XmlSlurper().parseText(xmlInput)
1349                         if (utils.nodeExists(xmlInput, "payload")) {
1350                                 nodeToSerialize = fxml.'payload'.'l3-network'.'*'.find {it.name() == element}
1351                                 if (nodeToSerialize!=null) {
1352                                         nodeAsText = XmlUtil.serialize(nodeToSerialize)
1353                                 } else {
1354                                     nodeAsText = ""
1355                                 }
1356
1357                         } else {
1358                                 nodeToSerialize = fxml.'*'.find {it.name() == element}
1359                                 if (nodeToSerialize!=null) {
1360                                         nodeAsText = XmlUtil.serialize(nodeToSerialize)
1361                                 } else {
1362                                         nodeAsText = ""
1363                                 }
1364
1365                         }
1366                 }
1367                 return nodeAsText
1368
1369         }
1370
1371 //TODO: This method still needs to be tested before using.
1372         /**
1373          *
1374          * This method is similar to the gennetwork:ContrailNetworUpdateCompletedObject
1375          * BPEL method.  It extracts all of the required subnet information
1376          * for each subnet listed with an orch status equal to the one provided
1377          * and puts the corresponding infomation with the appropriate node for
1378          * updating aai. The method sets the orch status for each subnet to active
1379          *
1380          * @param subnetsXml the entire subnets xml
1381          * @param requestInput the request in the process
1382          * @param queryIdResponse the response of REST AAI query by Id
1383          * @param queryVpnBindingResponse the response of REST AAI query by vpn binding
1384          * @param routeCollection the collection of vpnBinding's 'global-route-target'
1385          * @return String request
1386          */
1387         public String networkUpdateSubnetInfo(String subnetsXml, String networkResponseXml){
1388
1389                         String subnets = ""
1390                         StringBuilder sb = new StringBuilder()
1391                         InputSource source = new InputSource(new StringReader(subnetsXml));
1392                         DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
1393                         docFactory.setNamespaceAware(true)
1394                         DocumentBuilder docBuilder = docFactory.newDocumentBuilder()
1395                         Document xml = docBuilder.parse(source)
1396                         NodeList nodeList = xml.getElementsByTagNameNS("*", "subnet")
1397                         for (int x = 0; x < nodeList.getLength(); x++) {
1398                                 Node node = nodeList.item(x)
1399                                 String subnet = ""
1400                                 if (node.getNodeType() == Node.ELEMENT_NODE) {
1401                                         Element eElement = (Element) node
1402                                         String subnetOrchStatus = eElement.getElementsByTagNameNS("*", "orchestration-status").item(0).getTextContent()
1403                                         if(subnetOrchStatus.equals("pending-create")){
1404
1405                                                 String subnetId = eElement.getElementsByTagNameNS("*", "subnet-id").item(0).getTextContent()
1406                                                 def netAddress = eElement.getElementsByTagNameNS("*", "network-start-address").item(0).getTextContent()
1407                                                 def mask = eElement.getElementsByTagNameNS("*", "cidr-mask").item(0).getTextContent()
1408                                                 def dhcpEnabledSubnet = eElement.getElementsByTagNameNS("*", "dhcp-enabled").item(0).getTextContent()
1409                                                 def gatewayAddress = eElement.getElementsByTagNameNS("*", "gateway-address").item(0).getTextContent()
1410                                                 def ipVersion = eElement.getElementsByTagNameNS("*", "ip-version").item(0).getTextContent()
1411                                                 def relationshipList =  eElement.getElementsByTagNameNS("*", "relationship-list").item(0).getTextContent() //TODO: test this
1412                                                 String neutronSubnetId = extractNeutSubId(networkResponseXml, subnetId)
1413                                                 subnet =
1414                                                 """<subnet>
1415                                         <subnetId>${MsoUtils.xmlEscape(subnetId)}</subnetId>
1416                                         <neutron-subnet-id>${MsoUtils.xmlEscape(neutronSubnetId)}</neutron-subnet-id>
1417                                         <gateway-address>${MsoUtils.xmlEscape(gatewayAddress)}</gateway-address>
1418                                         <network-start-address>${MsoUtils.xmlEscape(netAddress)}</network-start-address>
1419                                         <cidr-mask>${MsoUtils.xmlEscape(mask)}</cidr-mask>
1420                                         <ip-Version>${MsoUtils.xmlEscape(ipVersion)}</ip-Version>
1421                                         <orchestration-status>active</orchestration-status>
1422                                         <dhcp-enabled>${MsoUtils.xmlEscape(dhcpEnabledSubnet)}</dhcp-enabled>
1423                                         <relationship-list>${relationshipList}</relationship-list>
1424                                         </subnet>"""
1425
1426                                         }else if(subnetOrchStatus.equals("pending-delete")){
1427                                                 StringWriter writer = new StringWriter()
1428                                                 Transformer transformer = TransformerFactory.newInstance().newTransformer()
1429                                                 transformer.transform(new DOMSource(node), new StreamResult(writer))
1430                                                 subnet = writer.toString()
1431
1432                                         }else{
1433                                                 subnet = ""
1434                                         }
1435                                 }
1436                                 subnets = sb.append(subnet)
1437                         }
1438
1439                         subnets = utils.removeXmlPreamble(subnets)
1440
1441                         String subnetsList =
1442                         """<subnets>
1443                         ${subnets}
1444                         </subnets>"""
1445
1446                         return subnetsList
1447         }
1448
1449
1450         /**
1451          *
1452          * This method extracts the "value" node text for the the given subnet Id.
1453          *
1454          * @param String inputSource - xml that contains the subnet id key and value
1455          * @param String subnetId - for which you want the value of
1456
1457          * @return String value - node text of node named value associated with the given subnet id
1458          */
1459         public String extractNeutSubId(String inputSource, String subnetId){
1460
1461                                 String value = ""
1462                                 InputSource source = new InputSource(new StringReader(inputSource));
1463                                 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
1464                                 docFactory.setNamespaceAware(true)
1465                                 DocumentBuilder docBuilder = docFactory.newDocumentBuilder()
1466                                 Document xml = docBuilder.parse(source)
1467                                 NodeList nodeList = xml.getElementsByTagNameNS("*", "entry")
1468                                 for (int x = 0; x < nodeList.getLength(); x++) {
1469                                         Node node = nodeList.item(x)
1470                                         String subnet = ""
1471                                         if (node.getNodeType() == Node.ELEMENT_NODE) {
1472                                                 Element eElement = (Element) node
1473                                                 String key = eElement.getElementsByTagNameNS("*", "key").item(0).getTextContent()
1474                                                 if(key.equals(subnetId)){
1475                                                         value = eElement.getElementsByTagNameNS("*", "value").item(0).getTextContent()
1476                                                 }
1477                                         }
1478                                 }
1479                                 return value
1480                         }
1481
1482         public boolean isRollbackEnabled (DelegateExecution execution, String payloadXml) {
1483
1484                 def rollbackEnabled = false
1485                 def rollbackValueSet = false
1486                 if (utils.nodeExists(payloadXml, "backout-on-failure")) {
1487                         String backoutValue = utils.getNodeText(payloadXml, "backout-on-failure")
1488                         if (backoutValue != null && !backoutValue.isEmpty()) {
1489                                 if (backoutValue.equalsIgnoreCase("false")) {
1490                                         rollbackEnabled = false
1491                                 }
1492                                 else {
1493                                         rollbackEnabled = true
1494                                 }
1495                                 rollbackValueSet = true;
1496                         }
1497                 }
1498
1499                 if (!rollbackValueSet) {
1500
1501                         if (UrnPropertiesReader.getVariable("mso.rollback", execution) != null) {
1502                             rollbackEnabled = UrnPropertiesReader.getVariable("mso.rollback", execution).toBoolean()
1503                         }
1504                 }
1505                 return rollbackEnabled
1506         }
1507         
1508         
1509         /**
1510          * This method extracts the version for the the given ip-version.
1511          *
1512          * @param String ipvVersion - IP protocols version (ex: ipv4 or ipv6 or 4 or 6)
1513          * @return String version - digit version (ex: 4 or 6)
1514          */
1515         
1516         public String getIpvVersion (String ipvVersion) {
1517                 
1518                 String version = ""
1519                 try {
1520                         if (ipvVersion.isNumber()) {
1521                                 version = ipvVersion
1522                         } else {
1523                                 version = ipvVersion.substring(ipvVersion.indexOf("ipv")+3)
1524                                 if (!version.isNumber()) {
1525                                         version = ipvVersion
1526                                 }
1527                         }
1528                 } catch (Exception ex) {
1529                         version = ipvVersion  
1530                 }
1531                 return version
1532         }
1533 }