2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package com.att.bpm.scripts;
23 import org.apache.commons.lang3.*
25 import groovy.xml.XmlUtil
26 import javax.xml.parsers.DocumentBuilder
27 import javax.xml.parsers.DocumentBuilderFactory
28 import javax.xml.transform.Transformer
29 import javax.xml.transform.TransformerFactory
30 import javax.xml.transform.TransformerException
31 import javax.xml.transform.dom.DOMSource
32 import javax.xml.transform.stream.StreamResult
34 import org.camunda.bpm.engine.delegate.BpmnError
35 import org.camunda.bpm.engine.runtime.Execution
36 import org.w3c.dom.Document
37 import org.w3c.dom.Element
39 import org.w3c.dom.NamedNodeMap
40 import org.w3c.dom.Node
41 import org.w3c.dom.NodeList;
42 import org.xml.sax.InputSource
43 import org.apache.commons.lang3.*
44 import org.camunda.bpm.engine.delegate.BpmnError
45 import org.camunda.bpm.engine.runtime.Execution
46 import org.w3c.dom.Document
47 import org.w3c.dom.Element
49 import org.w3c.dom.NamedNodeMap
50 import org.w3c.dom.Node
51 import org.w3c.dom.NodeList;
52 import org.xml.sax.InputSource
56 * This groovy class supports the any Network processes that need the methods defined here.
60 public MsoUtils utils = new MsoUtils()
61 private AbstractServiceTaskProcessor taskProcessor
63 public NetworkUtils(AbstractServiceTaskProcessor taskProcessor) {
64 this.taskProcessor = taskProcessor
69 * This method returns the string for Network request
70 * V2 for Contrail 3.x will populate cloud-region data in same cloudSiteId filed
71 * Network adapter will handle it properly
72 * @param requestId either 'request-id' or 'att-mso-request-id'
73 * @param requestInput the request in the process
74 * @param queryIdResponse the response of REST AAI query by Id
75 * @param routeCollection the collection
76 * @param policyFqdns the policy
77 * @param tableCollection the collection
78 * @param cloudRegionId the cloud-region-region
79 * @return String request
81 def CreateNetworkRequestV2(execution, requestId, messageId, requestInput, queryIdResponse, routeCollection, policyFqdns, tableCollection, cloudRegionId, backoutOnFailure, source) {
82 String createNetworkRequest = null
83 if(requestInput!=null && queryIdResponse!=null) {
84 String serviceInstanceId = ""
85 String sharedValue = ""
86 String externalValue = ""
88 if (source == "VID") {
89 sharedValue = utils.getNodeText1(queryIdResponse, "is-shared-network") != null ? utils.getNodeText1(queryIdResponse, "is-shared-network") : "false"
90 externalValue = utils.getNodeText1(queryIdResponse, "is-external-network") != null ? utils.getNodeText1(queryIdResponse, "is-external-network") : "false"
91 serviceInstanceId = utils.getNodeText1(requestInput, "service-instance-id")
93 } else { // source = 'PORTAL'
94 sharedValue = getParameterValue(requestInput, "shared")
95 externalValue = getParameterValue(requestInput, "external")
96 serviceInstanceId = utils.getNodeText1(requestInput, "service-instance-id") != null ? utils.getNodeText1(requestInput, "service-instance-id") : ""
99 String networkParams = ""
100 if (utils.nodeExists(requestInput, "network-params")) {
101 String netParams = utils.getNodeXml(requestInput, "network-params", false).replace("tag0:","").replace(":tag0","")
102 networkParams = buildParams(netParams)
105 String failIfExists = "false"
107 String cloudRegion = cloudRegionId
108 String tenantId = utils.getNodeText1(requestInput, "tenant-id")
111 String networkName = utils.getNodeText1(queryIdResponse, "network-name")
112 String networkId = utils.getNodeText1(queryIdResponse, "network-id")
113 String networkType = utils.getNodeText1(queryIdResponse, "network-type")
117 if (utils.nodeExists(queryIdResponse, "subnets")) {
118 def subnetsGroup = utils.getNodeXml(queryIdResponse, "subnets", false)
119 subnets = buildSubnets(subnetsGroup)
122 String physicalNetworkName = ""
123 physicalNetworkName = utils.getNodeText1(queryIdResponse, "physical-network-name")
125 String vlansCollection = buildVlans(queryIdResponse)
127 String notificationUrl = "" //TODO - is this coming from URN? What variable/value to use?
128 //String notificationUrl = execution.getVariable("URN_?????") //TODO - is this coming from URN? What variable/value to use?
130 createNetworkRequest = """
131 <createNetworkRequest>
132 <cloudSiteId>${cloudRegion}</cloudSiteId>
133 <tenantId>${tenantId}</tenantId>
134 <networkId>${networkId}</networkId>
135 <networkName>${networkName}</networkName>
136 <networkType>${networkType}</networkType>
137 <networkTechnology>CONTRAIL</networkTechnology>
138 <providerVlanNetwork>
139 <physicalNetworkName>${physicalNetworkName}</physicalNetworkName >
141 </providerVlanNetwork>
143 <shared>${sharedValue}</shared>
144 <external>${externalValue}</external>
150 <skipAAI>true</skipAAI>
151 <backout>${backoutOnFailure}</backout>
152 <failIfExists>${failIfExists}</failIfExists>
155 <requestId>${requestId}</requestId>
156 <serviceInstanceId>${serviceInstanceId}</serviceInstanceId>
158 <messageId>${messageId}</messageId>
159 <notificationUrl>${notificationUrl}</notificationUrl>
160 </createNetworkRequest>
163 return createNetworkRequest
168 * This method returns the string for Network request
169 * V2 for Contrail 3.x will populate cloud-region data in same cloudSiteId filed
170 * Network adapter will handle it properly
171 * @param requestId either 'request-id' or 'att-mso-request-id'
172 * @param requestInput the request in the process
173 * @param queryIdResponse the response of REST AAI query by Id
174 * @param routeCollection the collection
175 * @param policyFqdns the policy
176 * @param cloudRegionId the cloud-region-region
177 * @return String request
179 def UpdateNetworkRequestV2(execution, requestId, messageId, requestInput, queryIdResponse, routeCollection, policyFqdns, tableCollection, cloudRegionId, backoutOnFailure, source) {
180 String updateNetworkRequest = null
181 if(requestInput!=null && queryIdResponse!=null) {
182 String serviceInstanceId = ""
183 String sharedValue = ""
184 String externalValue = ""
186 if (source == "VID") {
187 sharedValue = utils.getNodeText1(queryIdResponse, "is-shared-network") != null ? utils.getNodeText1(queryIdResponse, "is-shared-network") : "false"
188 externalValue = utils.getNodeText1(queryIdResponse, "is-external-network") != null ? utils.getNodeText1(queryIdResponse, "is-external-network") : "false"
189 serviceInstanceId = utils.getNodeText1(requestInput, "service-instance-id")
191 } else { // source = 'PORTAL'
192 sharedValue = getParameterValue(requestInput, "shared")
193 externalValue = getParameterValue(requestInput, "external")
194 serviceInstanceId = utils.getNodeText1(requestInput, "service-instance-id") != null ? utils.getNodeText1(requestInput, "service-instance-id") : ""
197 String failIfExists = "false"
199 String cloudRegion = cloudRegionId
200 String tenantId = utils.getNodeText1(requestInput, "tenant-id")
203 String networkName = utils.getNodeText1(queryIdResponse, "network-name")
204 String networkId = utils.getNodeText1(queryIdResponse, "network-id")
205 String networkType = utils.getNodeText1(queryIdResponse, "network-type")
209 if (utils.nodeExists(queryIdResponse, "subnets")) {
210 def subnetsGroup = utils.getNodeXml(queryIdResponse, "subnets", false)
211 subnets = buildSubnets(subnetsGroup)
214 String networkParams = ""
215 if (utils.nodeExists(requestInput, "network-params")) {
216 String netParams = utils.getNodeXml(requestInput, "network-params", false).replace("tag0:","").replace(":tag0","")
217 networkParams = buildParams(netParams)
220 String networkStackId = utils.getNodeText1(queryIdResponse, "heat-stack-id")
221 if (networkStackId == 'null' || networkStackId == "" || networkStackId == null) {
222 networkStackId = "force_update"
225 String physicalNetworkName = utils.getNodeText1(queryIdResponse, "physical-network-name")
226 String vlansCollection = buildVlans(queryIdResponse)
228 updateNetworkRequest =
229 """<updateNetworkRequest>
230 <cloudSiteId>${cloudRegion}</cloudSiteId>
231 <tenantId>${tenantId}</tenantId>
232 <networkId>${networkId}</networkId>
233 <networkStackId>${networkStackId}</networkStackId>
234 <networkName>${networkName}</networkName>
235 <networkType>${networkType}</networkType>
236 <networkTypeVersion/>
237 <networkTechnology>CONTRAIL</networkTechnology>
238 <providerVlanNetwork>
239 <physicalNetworkName>${physicalNetworkName}</physicalNetworkName>
241 </providerVlanNetwork>
243 <shared>${sharedValue}</shared>
244 <external>${externalValue}</external>
250 <skipAAI>true</skipAAI>
251 <backout>${backoutOnFailure}</backout>
252 <failIfExists>${failIfExists}</failIfExists>
256 <requestId>${requestId}</requestId>
257 <serviceInstanceId>${serviceInstanceId}</serviceInstanceId>
259 <messageId>${messageId}</messageId>
260 <notificationUrl></notificationUrl>
261 </updateNetworkRequest>""".trim()
264 return updateNetworkRequest
269 * This method returns the string for Create Volume Request payload
270 * @param groupId the volume-group-id
271 * @param volumeName the volume-group-name
272 * @param vnfType the vnf-type
273 * @param tenantId the value of relationship-key 'tenant.tenant-id'
274 * @return String request payload
276 def String CreateNetworkVolumeRequest(groupId, volumeName, vnfType, tenantId) {
278 String requestPayload =
279 """<volume-group xmlns="http://org.openecomp.aai.inventory/v6">
280 <volume-group-id>${groupId}</volume-group-id>
281 <volume-group-name>${volumeName}</volume-group-name>
282 <heat-stack-id></heat-stack-id>
283 <vnf-type>${vnfType}</vnf-type>
284 <orchestration-status>Pending</orchestration-status>
287 <related-to>tenant</related-to>
289 <relationship-key>tenant.tenant-id</relationship-key>
290 <relationship-value>${tenantId}</relationship-value>
296 return requestPayload
299 def String createCloudRegionVolumeRequest(groupId, volumeName, vnfType, tenantId, cloudRegion, namespace) {
301 String requestPayload =
302 """<volume-group xmlns="${namespace}">
303 <volume-group-id>${groupId}</volume-group-id>
304 <volume-group-name>${volumeName}</volume-group-name>
305 <heat-stack-id></heat-stack-id>
306 <vnf-type>${vnfType}</vnf-type>
307 <orchestration-status>Pending</orchestration-status>
310 <related-to>tenant</related-to>
312 <relationship-key>tenant.tenant-id</relationship-key>
313 <relationship-value>${tenantId}</relationship-value>
316 <relationship-key>cloud-region.cloud-owner</relationship-key>
317 <relationship-value>att-aic</relationship-value>
320 <relationship-key>cloud-region.cloud-region-id</relationship-key>
321 <relationship-value>${cloudRegion}</relationship-value>
327 return requestPayload
330 def String createCloudRegionVolumeRequest(groupId, volumeName, vnfType, vnfId, tenantId, cloudRegion, namespace) {
332 String requestPayload =
333 """<volume-group xmlns="${namespace}">
334 <volume-group-id>${groupId}</volume-group-id>
335 <volume-group-name>${volumeName}</volume-group-name>
336 <heat-stack-id></heat-stack-id>
337 <vnf-type>${vnfType}</vnf-type>
338 <orchestration-status>Pending</orchestration-status>
341 <related-to>generic-vnf</related-to>
343 <relationship-key>generic-vnf.vnf-id</relationship-key>
344 <relationship-value>${vnfId}</relationship-value>
348 <related-to>tenant</related-to>
350 <relationship-key>tenant.tenant-id</relationship-key>
351 <relationship-value>${tenantId}</relationship-value>
354 <relationship-key>cloud-region.cloud-owner</relationship-key>
355 <relationship-value>att-aic</relationship-value>
358 <relationship-key>cloud-region.cloud-region-id</relationship-key>
359 <relationship-value>${cloudRegion}</relationship-value>
365 return requestPayload
370 * This method returns the string for Update Volume Request payload
371 * @param requeryAAIVolGrpNameResponse the response of query volume group name (in AAI)
372 * @param heatStackId the value of heat stack id
373 * @return String request payload
375 def String updateCloudRegionVolumeRequest(requeryAAIVolGrpNameResponse, heatStackId, namespace) {
376 String requestPayload = ""
377 if (requeryAAIVolGrpNameResponse != null) {
378 def groupId = utils.getNodeText(requeryAAIVolGrpNameResponse, "volume-group-id")
379 def volumeName = utils.getNodeText(requeryAAIVolGrpNameResponse, "volume-group-name")
380 def vnfType = utils.getNodeText(requeryAAIVolGrpNameResponse, "vnf-type")
381 def resourceVersion = utils.getNodeText(requeryAAIVolGrpNameResponse, "resource-version")
382 def relationshipList = ""
383 if (utils.nodeExists(requeryAAIVolGrpNameResponse, "relationship")) {
384 relationshipList = rebuildRelationship(requeryAAIVolGrpNameResponse)
388 """<volume-group xmlns="${namespace}">
389 <volume-group-id>${groupId}</volume-group-id>
390 <volume-group-name>${volumeName}</volume-group-name>
391 <heat-stack-id>${heatStackId}</heat-stack-id>
392 <vnf-type>${vnfType}</vnf-type>
393 <orchestration-status>Active</orchestration-status>
394 <resource-version>${resourceVersion}</resource-version>
399 return requestPayload
404 * This method returns the string for Update Volume Request payload
405 * @param requeryAAIVolGrpNameResponse the response of query volume group name (in AAI)
406 * @param heatStackId the value of heat stack id
407 * @return String request payload
409 def String UpdateNetworkVolumeRequest(requeryAAIVolGrpNameResponse, heatStackId) {
410 String requestPayload = ""
411 if (requeryAAIVolGrpNameResponse != null) {
412 def groupId = utils.getNodeText(requeryAAIVolGrpNameResponse, "volume-group-id")
413 def volumeName = utils.getNodeText(requeryAAIVolGrpNameResponse, "volume-group-name")
414 def vnfType = utils.getNodeText(requeryAAIVolGrpNameResponse, "vnf-type")
415 def resourceVersion = utils.getNodeText(requeryAAIVolGrpNameResponse, "resource-version")
416 def relationshipList = ""
417 if (utils.nodeExists(requeryAAIVolGrpNameResponse, "relationship")) {
418 relationshipList = rebuildRelationship(requeryAAIVolGrpNameResponse)
422 """<volume-group xmlns="http://org.openecomp.aai.inventory/v6">
423 <volume-group-id>${groupId}</volume-group-id>
424 <volume-group-name>${volumeName}</volume-group-name>
425 <heat-stack-id>${heatStackId}</heat-stack-id>
426 <vnf-type>${vnfType}</vnf-type>
427 <orchestration-status>Active</orchestration-status>
428 <resource-version>${resourceVersion}</resource-version>
433 return requestPayload
437 * This method returns the string for Create Contrail Network payload
438 * @param requeryIdAAIResponse the response from AAI query by id
439 * @param createNetworkResponse the response of create network
440 * @return String contrailNetworkCreatedUpdate
442 def ContrailNetworkCreatedUpdate(requeryIdAAIResponse, createNetworkResponse, schemaVersion) {
444 String contrailNetworkCreatedUpdate = ""
445 if(requeryIdAAIResponse!=null && createNetworkResponse!=null) {
447 def l3Network = utils.getNodeXml(requeryIdAAIResponse, "l3-network", false).replace("tag0:","").replace(":tag0","")
448 def createNetworkContrailResponse = ""
449 if (utils.nodeExists(createNetworkResponse, 'createNetworkResponse')) {
450 createNetworkContrailResponse = utils.getNodeXml(createNetworkResponse, "createNetworkResponse", false).replace("tag0:","").replace(":tag0","")
452 createNetworkContrailResponse = utils.getNodeXml(createNetworkResponse, "updateNetworkContrailResponse", false).replace("tag0:","").replace(":tag0","")
456 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",
457 "physical-network-name", "is-provider-network", "is-shared-network", "is-external-network"]
458 String rebuildNetworkElements = buildNetworkElements(l3Network, createNetworkContrailResponse, networkList)
461 def rebuildSubnetList = ""
462 if (utils.nodeExists(requeryIdAAIResponse, 'subnet')) {
463 rebuildSubnetList = buildSubnets(requeryIdAAIResponse, createNetworkResponse)
466 // rebuild 'segmentation-assignments'
467 def rebuildSegmentationAssignments = ""
468 if (utils.nodeExists(requeryIdAAIResponse, 'segmentation-assignments')) {
469 List elementList = ["segmentation-id"]
470 rebuildSegmentationAssignments = buildXMLElements(requeryIdAAIResponse, "", "segmentation-assignments", elementList)
473 // rebuild 'ctag-assignments' / rebuildCtagAssignments
474 def rebuildCtagAssignmentsList = ""
475 if (utils.nodeExists(requeryIdAAIResponse, 'ctag-assignment')) {
476 rebuildCtagAssignmentsList = rebuildCtagAssignments(requeryIdAAIResponse)
479 // rebuild 'relationship'
480 def relationshipList = ""
481 if (utils.nodeExists(requeryIdAAIResponse, 'relationship-list')) {
482 String rootRelationshipData = getFirstNodeXml(requeryIdAAIResponse, "relationship-list").drop(38).trim().replace("tag0:","").replace(":tag0","")
483 if (utils.nodeExists(rootRelationshipData, 'relationship')) {
484 relationshipList = rebuildRelationship(rootRelationshipData)
488 //Check for optional contrail network fqdn within CreateNetworkResponse
489 String contrailNetworkFQDN
490 if(utils.nodeExists(createNetworkResponse, "contrail-network-fqdn")){
491 contrailNetworkFQDN = utils.getNodeXml(createNetworkResponse, "contrail-network-fqdn")
492 contrailNetworkFQDN = utils.removeXmlNamespaces(contrailNetworkFQDN)
493 contrailNetworkFQDN = utils.removeXmlPreamble(contrailNetworkFQDN)
495 contrailNetworkFQDN = ""
498 contrailNetworkCreatedUpdate =
499 """<l3-network xmlns="${schemaVersion}">
500 ${rebuildNetworkElements}
502 ${rebuildSegmentationAssignments}
503 ${rebuildCtagAssignmentsList}
505 ${contrailNetworkFQDN}
506 </l3-network>""".trim()
509 return contrailNetworkCreatedUpdate
515 * This method returns the value for the name paramName.
516 * Ex: <network-params>
517 * <param name="shared">1</param>
518 * <param name="external">0</external>
521 * @param xmlInput the XML document
522 * @param paramName the param name (ex: 'shared')
523 * @return a param value for 'shared' (ex: '1')
525 def getParameterValue(xmlInput, paramName) {
528 def xml= new XmlSlurper().parseText(xmlInput)
529 rtn= xml.'**'.find {param->param.'@name'.text() == paramName}
539 * This method returns the name of param if found/match with paramName.
540 * Ex: <network-params>
541 * <param name="shared">1</param>
542 * <param name="external">0</external>
545 * @param xmlInput the XML document
546 * @param paramName the param name (ex: 'shared', )
547 * @return a param name for 'shared' (ex: 'shared' if found)
549 def getParameterName(xmlInput, paramName) {
552 def xml= new XmlSlurper().parseText(xmlInput)
554 rtn= xml.'**'.find {param->param.'@name' == paramName}.'@name'
555 } catch (Exception ex) {
559 if (rtn==null || rtn=="") {
567 * This method returns the networkParams xml string.
570 * <param name="shared">1</param>
571 * <param name="external">0</external>
577 * <external>0</external>
582 def buildParams(networkParams) {
584 def netParams = new XmlParser().parseText(networkParams)
586 def paramsList = netParams.'**'.findAll {param->param.'@name'}.'@name'
587 if (paramsList.size() > 0) {
588 build += "<networkParams>"
589 for (i in 0..paramsList.size()-1) {
590 def name = netParams.'**'.find {param->param.'@name' == paramsList[i]}.'@name'
591 def value= netParams.'**'.find {param->param.'@name' == paramsList[i]}.text()
592 build += "<${name}>${value}</${name}>"
594 build += "</networkParams>"
597 } catch (Exception ex) {
598 println ' buildParams error - ' + ex.getMessage()
604 def getVlans(xmlInput) {
606 if (xmlInput!=null) {
607 def vlansList = getListWithElements(xmlInput, 'vlans')
608 def vlansListSize = vlansList.size()
609 if (vlansListSize > 0) {
610 for (i in 0..vlansListSize-1) {
611 rtn += '<vlans>'+vlansList[i]+'</vlans>'
621 * This method returns the uri value for the vpn bindings.
622 * Return the a list of value of vpn binding in the <related-link> string.
624 * <relationship-list>
626 * <related-to>vpn-binding</related-to>
627 * <related-link>https://aai-app-e2e.test.att.com:8443/aai/v6/network/vpn-bindings/vpn-binding/85f015d0-2e32-4c30-96d2-87a1a27f8017/</related-link>
628 * <relationship-data>
629 * <relationship-key>vpn-binding.vpn-id</relationship-key>
630 * <relationship-value>85f015d0-2e32-4c30-96d2-87a1a27f8017</relationship-value>
631 * </relationship-data>
634 * <related-to>vpn-binding</related-to>
635 * <related-link>https://aai-ext1.test.att.com:8443/aai/v6/network/vpn-bindings/vpn-binding/24a4b507-853a-4a38-99aa-05fcc54be24d/</related-link>
636 * <relationship-data>
637 * <relationship-key>vpn-binding.vpn-id</relationship-key>
638 * <relationship-value>24a4b507-853a-4a38-99aa-05fcc54be24d</relationship-value>
639 * </relationship-data>
640 * <related-to-property>
641 * <property-key>vpn-binding.vpn-name</property-key>
642 * <property-value>oam_protected_net_6_MTN5_msotest1</property-value>
643 * </related-to-property>
645 * @param xmlInput the XML document
646 * @return a list of vpn binding values
647 * 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/']
650 def getVnfBindingObject(xmlInput) {
653 if (xmlInput!=null) {
654 def relationshipList = getListWithElements(xmlInput, 'relationship')
655 def relationshipListSize = relationshipList.size()
656 if (relationshipListSize > 0) {
657 for (i in 0..relationshipListSize-1) {
658 def relationshipXml = XmlUtil.serialize(relationshipList[i])
659 if (utils.getNodeText(relationshipXml, 'related-to') == "vpn-binding") {
660 def relatedLink = utils.getNodeText(relationshipXml, 'related-link')
661 if (relatedLink != null || relatedLink != "") {
662 rtn.add(relatedLink.substring(relatedLink.indexOf("/aai/"), relatedLink.length()))
671 * similar to VNF bindings method
672 * @param xmlInput the XML document
673 * @return a list of network policy values
674 * 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']
677 def getNetworkPolicyObject(xmlInput) {
680 if (xmlInput!=null) {
681 def relationshipList = getListWithElements(xmlInput, 'relationship')
682 def relationshipListSize = relationshipList.size()
683 if (relationshipListSize > 0) {
684 for (i in 0..relationshipListSize-1) {
685 def relationshipXml = XmlUtil.serialize(relationshipList[i])
686 if (utils.getNodeText(relationshipXml, 'related-to') == "network-policy") {
687 def relatedLink = utils.getNodeText(relationshipXml, 'related-link')
688 if (relatedLink != null || relatedLink != "") {
689 rtn.add(relatedLink.substring(relatedLink.indexOf("/aai/"), relatedLink.length()))
699 * similar to network policymethod
700 * @param xmlInput the XML document
701 * @return a list of network policy values
702 * ex: ['aai/v$/network/route-table-references/route-table-reference/refFQDN1', 'aai/v$/network/route-table-references/route-table-reference/refFQDN2']
705 def getNetworkTableRefObject(xmlInput) {
708 if (xmlInput!=null) {
709 def relationshipList = getListWithElements(xmlInput, 'relationship')
710 def relationshipListSize = relationshipList.size()
711 if (relationshipListSize > 0) {
712 for (i in 0..relationshipListSize-1) {
713 def relationshipXml = XmlUtil.serialize(relationshipList[i])
714 if (utils.getNodeText(relationshipXml, 'related-to') == "route-table-reference") {
715 def relatedLink = utils.getNodeText1(relationshipXml, 'related-link')
716 if (relatedLink != null || relatedLink != "") {
717 rtn.add(relatedLink.substring(relatedLink.indexOf("/aai/"), relatedLink.length()))
727 def isVfRelationshipExist(xmlInput) {
729 if (xmlInput!=null) {
730 def relationshipList = getListWithElements(xmlInput, 'relationship')
731 def relationshipListSize = relationshipList.size()
732 if (relationshipListSize > 0) {
733 for (i in 0..relationshipListSize-1) {
734 def relationshipXml = XmlUtil.serialize(relationshipList[i])
735 if (utils.getNodeText(relationshipXml, 'related-to') == "vf-module") {
745 def isInstanceValueMatch(linkResource, globalSubscriberId, serviceType) {
748 String globalSubscriberIdLink = linkResource.substring(linkResource.indexOf("/customer/")+10, linkResource.indexOf("/service-subscriptions"))
749 String serviceTypeLink = linkResource.substring(linkResource.indexOf("/service-subscription/")+22, linkResource.indexOf("/service-instances"))
750 if (globalSubscriberIdLink == globalSubscriberId) {
753 if (serviceTypeLink == serviceType) {
758 } catch (Exception ex) {
759 println 'Exception - ' + ex.getMessage()
765 def getListWithElements(xmlInput, groupName) {
767 if (xmlInput != null) {
768 def relationshipData = new XmlSlurper().parseText(xmlInput)
769 rtn = relationshipData.'**'.findAll {it.name() == groupName}
775 // build network single elements
776 def buildNetworkElements(l3Network, createNetworkContrailResponse, networkList) {
777 def replaceNetworkId = ""
778 def replaceNeutronNetworkId = ""
779 def replaceContrailNetworkFqdn = ""
780 if (l3Network != null && createNetworkContrailResponse != null) {
781 if (utils.nodeExists(l3Network, 'heat-stack-id')) {
782 replaceNetworkId = utils.getNodeText(l3Network, 'heat-stack-id')
784 if (utils.nodeExists(createNetworkContrailResponse, 'networkStackId')) {
785 replaceNetworkId = utils.getNodeText(createNetworkContrailResponse, 'networkStackId')
788 if (utils.nodeExists(l3Network, 'neutron-network-id')) {
789 replaceNeutronNetworkId = utils.getNodeText(l3Network, 'neutron-network-id')
791 if (utils.nodeExists(createNetworkContrailResponse, 'neutronNetworkId')) {
792 replaceNeutronNetworkId = utils.getNodeText(createNetworkContrailResponse, 'neutronNetworkId')
795 if (utils.nodeExists(l3Network, 'contrail-network-fqdn')) {
796 replaceContrailNetworkFqdn = utils.getNodeText(l3Network, 'contrail-network-fqdn')
798 if (utils.nodeExists(createNetworkContrailResponse, 'networkFqdn')) {
799 replaceContrailNetworkFqdn = utils.getNodeText(createNetworkContrailResponse, 'networkFqdn')
806 if (l3Network != null) {
807 for (element in networkList) {
808 def xml= new XmlSlurper().parseText(l3Network)
809 var = xml.'**'.find {it.name() == element}
811 if (element=="orchestration-status") {
812 xmlNetwork += "<"+element+">"+"active"+"</"+element+">"
814 if (element=="heat-stack-id") {
815 if (replaceNetworkId != "") {
816 xmlNetwork += "<"+element+">"+replaceNetworkId+"</"+element+">"
819 if (element=="neutron-network-id") {
820 if (replaceNeutronNetworkId != "") {
821 xmlNetwork += "<"+element+">"+replaceNeutronNetworkId+"</"+element+">"
824 if (element=="contrail-network-fqdn") {
825 if (replaceContrailNetworkFqdn != "") {
826 xmlNetwork += "<"+element+">"+replaceContrailNetworkFqdn+"</"+element+">"
831 if (element=="orchestration-status") {
832 xmlNetwork += "<"+element+">"+"active"+"</"+element+">"
834 xmlNetwork += "<"+element+">"+var.toString()+"</"+element+">"
843 def buildSubnets(requeryIdAAIResponse, createNetworkResponse) {
844 def rebuildingSubnets = ""
845 if (requeryIdAAIResponse != null && utils.nodeExists(requeryIdAAIResponse, 'subnets')) {
846 def subnetIdMapValue = ""
847 def subnetsGroup = utils.getNodeXml(requeryIdAAIResponse, "subnets", false)
848 def subnetsData = new XmlSlurper().parseText(subnetsGroup)
849 rebuildingSubnets += "<subnets>"
851 def subnets = subnetsData.'**'.findAll {it.name() == "subnet"}
852 def subnetsSize = subnets.size()
853 for (i in 0..subnetsSize-1) {
854 def subnet = subnets[i]
855 def subnetXml = XmlUtil.serialize(subnet)
856 def subnetList = ["subnet-id", "neutron-subnet-id", "gateway-address", "network-start-address", "cidr-mask", "ip-version", "orchestration-status", "dhcp-enabled", "dhcp-start", "dhcp-end", "resource-version", "subnet-name"]
857 rebuildingSubnets += buildSubNetworkElements(subnetXml, createNetworkResponse, subnetList, "subnet")
859 if (utils.nodeExists(subnetsData, 'relationship')) {
860 rebuildingSubnets = rebuildRelationship(requeryIdAAIResponse)
863 } catch (Exception ex) {
866 rebuildingSubnets += "</subnets>"
869 return rebuildingSubnets
872 def buildSubnets(queryIdResponse) {
873 def rebuildingSubnets = ""
874 def subnetsData = new XmlSlurper().parseText(queryIdResponse)
875 //rebuildingSubnets += "<subnets>"
877 def subnets = subnetsData.'**'.findAll {it.name() == "subnet"}
878 def subnetsSize = subnets.size()
879 for (i in 0..subnetsSize-1) {
880 def subnet = subnets[i]
881 def subnetXml = XmlUtil.serialize(subnet)
882 def subnetList = ["dhcp-start", "dhcp-end", "network-start-address", "cidr-mask", "dhcp-enabled", "gateway-address", "ip-version", "subnet-id", "subnet-name"]
883 rebuildingSubnets += buildSubNetworkElements(subnetXml, subnetList, "subnets")
884 //rebuildingSubnets += buildSubNetworkElements(subnetXml, subnetList, "")
886 } catch (Exception ex) {
889 //rebuildingSubnets += "</subnets>"
891 return rebuildingSubnets
895 // build subnet sub-network single elements
896 def buildSubNetworkElements(subnetXml, createNetworkResponse, elementList, parentName) {
899 if (parentName != "") {
900 xmlBuild += "<"+parentName+">"
902 if (subnetXml != null) {
903 for (element in elementList) {
904 def xml= new XmlSlurper().parseText(subnetXml)
905 var = xml.'**'.find {it.name() == element}
907 if (element=="orchestration-status") {
908 xmlBuild += "<"+element+">"+"active"+"</"+element+">"
909 } else { // "subnet-id", "neutron-subnet-id"
910 if (element=="subnet-id") {
911 if (utils.nodeExists(createNetworkResponse, "subnetMap")) {
912 xmlBuild += "<"+element+">"+var.toString()+"</"+element+">"
913 String neutronSubnetId = extractNeutSubId(createNetworkResponse, var.toString())
914 xmlBuild += "<neutron-subnet-id>"+neutronSubnetId+"</neutron-subnet-id>"
917 if (element=="neutron-subnet-id") {
920 xmlBuild += "<"+element+">"+var.toString()+"</"+element+">"
928 if (parentName != "") {
929 xmlBuild += "</"+parentName+">"
934 // build subnet sub-network single elements
935 def buildSubNetworkElements(subnetXml, elementList, parentName) {
938 if (parentName != "") {
939 xmlBuild += "<"+parentName+">"
941 if (subnetXml != null) {
942 def networkStartAddress = ""
943 for (element in elementList) {
944 def xml= new XmlSlurper().parseText(subnetXml)
945 var = xml.'**'.find {it.name() == element}
946 if (element == "dhcp-start") {
947 xmlBuild += "<allocationPools>"
948 if (var.toString() == 'null') {
949 xmlBuild += "<start>"+""+"</start>"
951 xmlBuild += "<start>"+var.toString()+"</start>"
954 if (element == "dhcp-end") {
955 if (var.toString() == 'null') {
956 xmlBuild += "<end>"+""+"</end>"
958 xmlBuild += "<end>"+var.toString()+"</end>"
960 xmlBuild += "</allocationPools>"
962 if (element == "network-start-address" || element == "cidr-mask") {
963 if (element == "network-start-address") {
964 networkStartAddress = var.toString()
966 if (element == "cidr-mask") {
967 xmlBuild += "<cidr>"+networkStartAddress+"/"+var.toString()+"</cidr>"
970 if (element == "dhcp-enabled") {
971 xmlBuild += "<enableDHCP>"+var.toString()+"</enableDHCP>"
973 if (element == "gateway-address") {
974 xmlBuild += "<gatewayIp>"+var.toString()+"</gatewayIp>"
976 if (element == "ip-version") {
977 xmlBuild += "<ipVersion>"+var.toString()+"</ipVersion>"
979 if (element == "subnet-id") {
980 xmlBuild += "<subnetId>"+var.toString()+"</subnetId>"
982 if ((element == "subnet-name") && (var != null)) {
983 xmlBuild += "<subnetName>"+var.toString()+"</subnetName>"
987 if (parentName != "") {
988 xmlBuild += "</"+parentName+">"
993 // rebuild ctag-assignments
994 def rebuildCtagAssignments(xmlInput) {
995 def rebuildingCtagAssignments = ""
996 if (xmlInput!=null) {
997 def ctagAssignmentsData = new XmlSlurper().parseText(xmlInput)
998 rebuildingCtagAssignments += "<ctag-assignments>"
999 def ctagAssignments = ctagAssignmentsData.'**'.findAll {it.name() == "ctag-assignment"}
1000 def ctagAssignmentsSize = ctagAssignments.size()
1001 for (i in 0..ctagAssignmentsSize-1) {
1002 def ctagAssignment = ctagAssignments[i]
1003 def ctagAssignmentXml = XmlUtil.serialize(ctagAssignment)
1004 rebuildingCtagAssignments += "<ctag-assignment>"
1005 List elementList = ["vlan-id-inner", "resource-version"]
1006 rebuildingCtagAssignments += buildXMLElements(ctagAssignmentXml, "" , "", elementList)
1007 if (utils.nodeExists(ctagAssignmentXml, 'relationship')) {
1008 rebuildingCtagAssignments += rebuildRelationship(ctagAssignmentXml)
1010 rebuildingCtagAssignments += "</ctag-assignment>"
1012 rebuildingCtagAssignments += "</ctag-assignments>"
1014 return rebuildingCtagAssignments
1017 // rebuild 'relationship-list'
1018 def rebuildRelationship(xmlInput) {
1019 def rebuildingSubnets = ""
1020 if (xmlInput!=null) {
1021 def subnetsData = new XmlSlurper().parseText(xmlInput)
1022 rebuildingSubnets += "<relationship-list>"
1023 def relationships = subnetsData.'**'.findAll {it.name() == "relationship"}
1024 def relationshipsSize = relationships.size()
1025 for (i in 0..relationshipsSize-1) {
1026 def relationship = relationships[i]
1027 def relationshipXml = XmlUtil.serialize(relationship)
1028 rebuildingSubnets += "<relationship>"
1029 def relationshipList = ["related-to", "related-link"]
1030 rebuildingSubnets += buildSubNetworkElements(relationshipXml, "", relationshipList, "")
1031 if (utils.nodeExists(relationshipXml, 'relationship-data')) {
1032 def relationshipDataXmlData = new XmlSlurper().parseText(relationshipXml)
1033 def relationshipsData = relationshipDataXmlData.'**'.findAll {it.name() == "relationship-data"}
1034 def relationshipsDataSize = relationshipsData.size()
1035 for (j in 0..relationshipsDataSize-1) {
1036 def relationshipData = relationshipsData[j]
1037 def relationshipDataXml = XmlUtil.serialize(relationshipData)
1038 def relationshipDataList = ["relationship-key", "relationship-value"]
1039 rebuildingSubnets += buildXMLElements(relationshipDataXml, "", "relationship-data", relationshipDataList)
1042 if (utils.nodeExists(relationshipXml, 'related-to-property')) {
1043 def relationshipDataXmlData = new XmlSlurper().parseText(relationshipXml)
1044 def relationshipsData = relationshipDataXmlData.'**'.findAll {it.name() == "related-to-property"}
1045 def relationshipsDataSize = relationshipsData.size()
1046 for (j in 0..relationshipsDataSize-1) {
1047 def relationshipData = relationshipsData[j]
1048 def relationshipDataXml = XmlUtil.serialize(relationshipData)
1049 def relationshipDataList = ["property-key", "property-value"]
1050 rebuildingSubnets += buildXMLElements(relationshipDataXml, "", "related-to-property", relationshipDataList)
1054 rebuildingSubnets += "</relationship>"
1056 rebuildingSubnets += "</relationship-list>"
1058 return rebuildingSubnets
1061 def buildVlans(queryIdResponse) {
1062 def rebuildingSubnets = "<vlans>"
1063 def subnetsData = new XmlSlurper().parseText(queryIdResponse)
1066 def subnets = subnetsData.'**'.findAll {it.name() == "segmentation-assignments"}
1067 def subnetsSize = subnets.size()
1068 for (i in 0..subnetsSize-1) {
1069 def subnet = subnets[i]
1070 def subnetXml = XmlUtil.serialize(subnet)
1072 String vlan = utils.getNodeText1(subnetXml, "segmentation-id")
1074 rebuildingSubnets += ","
1076 rebuildingSubnets += vlan
1078 } catch (Exception ex) {
1081 //rebuildingSubnets += "</subnets>"
1082 rebuildingSubnets += "</vlans>"
1084 return rebuildingSubnets
1087 /* Utility code to rebuild xml/elements in a list:
1088 * rebuild xml with 1) unbounded groups of elements; or
1089 * 2) one group of elements; or
1090 * 3) just one or more elements (in a list as argument)
1091 * @param xmlInput the XML document
1092 * @param parentName the parent name (ex: 'inputs')
1093 * @param childrenName the chilrendName (ex: 'entry' as unbounded/occurs>1)
1094 * @param elementList the element list of children (ex: 'key', 'value')
1095 * @return a string of rebuild xml
1100 * <ws:key>name</ws:key>
1101 * <ws:value>Edward</ws:value>
1104 * <ws:key>age</ws:key>
1105 * <ws:value>30</ws:value>
1108 * <ws:key>age</ws:key>
1109 * <ws:value>30</ws:value>
1113 * List elementList = ["key", "value"]
1114 * String rebuild = buildXMLElements(xmlInput, "inputs", "entry", elementList)
1116 * Ex 2: xmlInput // no parent tag
1117 * <ws:sdnc-request-header>
1118 * <ws:svc-request-id>fec8ec88-151a-45c9-ad60-8233e0fc8ff2</ws:svc-request-id>
1119 * <ws:svc-notification-url>https://msojra.mtsnj.aic.cip.att.com:8443/adapters/rest/SDNCNotify</ws:svc-notification-url>
1120 * <ws:svc-action>assign</ws:svc-action>
1121 * </ws:sdnc-request-header>
1123 * List elementList = ["svc-request-id", "svc-notification-url", "svc-action"]
1124 * String rebuild = buildXMLElements(xmlInput, "" , "sdnc-request-header", elementList) // no parent tag
1126 * Ex 3: xmlInput // elements one after another (with no parent & children tag)
1127 * <ws:test-id>myTestid</ws:test-id>
1128 * <ws:test-user>myUser</ws:test-user>
1130 * List elementList = ["test-id", "test-user"]
1131 * String rebuild = buildXMLElements(xmlInput, "" , "", elementList)
1134 def buildXMLElements(xmlInput, parentName, childrenName, elementList) {
1135 def varChildren = ""
1137 def xmlBuildUnbounded = ""
1138 if (parentName!="") {xmlBuildUnbounded += "<"+parentName+">" +'\n'}
1139 if (xmlInput != null) {
1140 def xml= new XmlSlurper().parseText(xmlInput)
1141 if (childrenName!="") {
1142 varChildren = xml.'**'.findAll {it.name() == childrenName}
1143 for (i in 0..varChildren.size()-1) {
1144 xmlBuildUnbounded += "<"+childrenName+">" +'\n'
1145 for (element in elementList) {
1146 var = varChildren[i].'*'.find {it.name() == element}
1148 xmlBuildUnbounded += "<"+element+">"+var.toString()+"</"+element+">" +'\n'
1151 xmlBuildUnbounded += "</"+childrenName+">" +'\n'
1154 for (element in elementList) {
1155 var = xml.'*'.find {it.name() == element}
1157 xmlBuildUnbounded += "<"+element+">"+var.toString()+"</"+element+">" +'\n'
1163 if (parentName!="") {xmlBuildUnbounded += "</"+parentName+">" +'\n'}
1164 return xmlBuildUnbounded
1167 def getFirstNodeXml(xmlInput, element){
1169 def nodeToSerialize = ""
1170 if (xmlInput != null) {
1171 def fxml= new XmlSlurper().parseText(xmlInput)
1172 if (utils.nodeExists(xmlInput, "payload")) {
1173 nodeToSerialize = fxml.'payload'.'l3-network'.'*'.find {it.name() == element}
1174 if (nodeToSerialize!=null) {
1175 nodeAsText = XmlUtil.serialize(nodeToSerialize)
1181 nodeToSerialize = fxml.'*'.find {it.name() == element}
1182 if (nodeToSerialize!=null) {
1183 nodeAsText = XmlUtil.serialize(nodeToSerialize)
1194 //TODO: This method still needs to be tested before using.
1196 * This method is similar to the gennetwork:ContrailNetworUpdateCompletedObject
1197 * BPEL method. It extracts all of the required subnet information
1198 * for each subnet listed with an orch status equal to the one provided
1199 * and puts the corresponding infomation with the appropriate node for
1200 * updating aai. The method sets the orch status for each subnet to active
1202 * @param subnetsXml the entire subnets xml
1203 * @param requestInput the request in the process
1204 * @param queryIdResponse the response of REST AAI query by Id
1205 * @param queryVpnBindingResponse the response of REST AAI query by vpn binding
1206 * @param routeCollection the collection of vpnBinding's 'global-route-target'
1207 * @return String request
1209 public String networkUpdateSubnetInfo(String subnetsXml, String networkResponseXml){
1212 StringBuilder sb = new StringBuilder()
1213 InputSource source = new InputSource(new StringReader(subnetsXml));
1214 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
1215 docFactory.setNamespaceAware(true)
1216 DocumentBuilder docBuilder = docFactory.newDocumentBuilder()
1217 Document xml = docBuilder.parse(source)
1218 NodeList nodeList = xml.getElementsByTagNameNS("*", "subnet")
1219 for (int x = 0; x < nodeList.getLength(); x++) {
1220 Node node = nodeList.item(x)
1222 if (node.getNodeType() == Node.ELEMENT_NODE) {
1223 Element eElement = (Element) node
1224 String subnetOrchStatus = eElement.getElementsByTagNameNS("*", "orchestration-status").item(0).getTextContent()
1225 if(subnetOrchStatus.equals("pending-create")){
1227 String subnetId = eElement.getElementsByTagNameNS("*", "subnet-id").item(0).getTextContent()
1228 def netAddress = eElement.getElementsByTagNameNS("*", "network-start-address").item(0).getTextContent()
1229 def mask = eElement.getElementsByTagNameNS("*", "cidr-mask").item(0).getTextContent()
1230 def dhcpEnabledSubnet = eElement.getElementsByTagNameNS("*", "dhcp-enabled").item(0).getTextContent()
1231 def gatewayAddress = eElement.getElementsByTagNameNS("*", "gateway-address").item(0).getTextContent()
1232 def ipVersion = eElement.getElementsByTagNameNS("*", "ip-version").item(0).getTextContent()
1233 def relationshipList = eElement.getElementsByTagNameNS("*", "relationship-list").item(0).getTextContent() //TODO: test this
1234 String neutronSubnetId = extractNeutSubId(networkResponseXml, subnetId)
1237 <subnetId>${subnetId}</subnetId>
1238 <neutron-subnet-id>${neutronSubnetId}</neutron-subnet-id>
1239 <gateway-address>${gatewayAddress}</gateway-address>
1240 <network-start-address>${netAddress}</network-start-address>
1241 <cidr-mask>${mask}</cidr-mask>
1242 <ip-Version>${ipVersion}</ip-Version>
1243 <orchestration-status>active</orchestration-status>
1244 <dhcp-enabled>${dhcpEnabledSubnet}</dhcp-enabled>
1245 <relationship-list>${relationshipList}</relationship-list>
1248 }else if(subnetOrchStatus.equals("pending-delete")){
1249 StringWriter writer = new StringWriter()
1250 Transformer transformer = TransformerFactory.newInstance().newTransformer()
1251 transformer.transform(new DOMSource(node), new StreamResult(writer))
1252 subnet = writer.toString()
1258 subnets = sb.append(subnet)
1261 subnets = utils.removeXmlPreamble(subnets)
1263 String subnetsList =
1273 * This method extracts the "value" node text for the the given subnet Id.
1275 * @param String inputSource - xml that contains the subnet id key and value
1276 * @param String subnetId - for which you want the value of
1278 * @return String value - node text of node named value associated with the given subnet id
1280 public String extractNeutSubId(String inputSource, String subnetId){
1283 InputSource source = new InputSource(new StringReader(inputSource));
1284 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
1285 docFactory.setNamespaceAware(true)
1286 DocumentBuilder docBuilder = docFactory.newDocumentBuilder()
1287 Document xml = docBuilder.parse(source)
1288 NodeList nodeList = xml.getElementsByTagNameNS("*", "entry")
1289 for (int x = 0; x < nodeList.getLength(); x++) {
1290 Node node = nodeList.item(x)
1292 if (node.getNodeType() == Node.ELEMENT_NODE) {
1293 Element eElement = (Element) node
1294 String key = eElement.getElementsByTagNameNS("*", "key").item(0).getTextContent()
1295 if(key.equals(subnetId)){
1296 value = eElement.getElementsByTagNameNS("*", "value").item(0).getTextContent()
1303 public boolean isRollbackEnabled (Execution execution, String payloadXml) {
1305 boolean rollbackEnabled = false
1306 boolean rollbackValueSet = false
1307 if (utils.nodeExists(payloadXml, "backout-on-failure")) {
1308 String backoutValue = utils.getNodeText1(payloadXml, "backout-on-failure")
1309 if (backoutValue != null && !backoutValue.isEmpty()) {
1310 if (backoutValue.equalsIgnoreCase("false")) {
1311 rollbackEnabled = false
1314 rollbackEnabled = true
1316 rollbackValueSet = true;
1320 if (!rollbackValueSet) {
1321 rollbackEnabled = execution.getVariable("URN_mso_rollback")
1323 return rollbackEnabled