Removed MsoLogger class
[so.git] / bpmn / MSOCommonBPMN / src / main / groovy / org / onap / so / bpmn / common / scripts / MsoUtils.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.bpmn.common.scripts
24
25 import org.onap.so.logger.ErrorCode
26
27 import java.text.SimpleDateFormat
28
29 import org.apache.commons.codec.binary.Base64
30 import org.apache.commons.lang3.StringEscapeUtils
31 import org.onap.so.bpmn.core.BPMNLogger
32 import org.onap.so.bpmn.core.xml.XmlTool
33 import org.onap.so.logger.MessageEnum
34 import org.slf4j.Logger
35 import org.slf4j.LoggerFactory
36 import org.onap.so.utils.CryptoUtils
37 import org.slf4j.MDC
38 import org.w3c.dom.Element
39
40 import groovy.util.slurpersupport.NodeChild
41 import groovy.xml.XmlUtil
42
43 class MsoUtils {
44     private static final Logger logger = LoggerFactory.getLogger( MsoUtils.class);
45
46         def initializeEndPoints(execution){
47                 // use this placeholder to initialize end points, if called independently, this need to be set
48                 execution.setVariable("AAIEndPoint","http://localhost:28080/SoapUIMocks")
49         }
50
51         /**
52          * Returns the unescaped contents of element
53          *
54          * @param xmlInput
55          * @param element
56          * @return
57          */
58         def getNodeText(xmlInput,element){
59                 def rtn=null
60                 if(xmlInput!=null){
61                         def xml= new XmlSlurper().parseText(xmlInput)
62                         rtn= xml.'**'.find{node->node.name()==element}
63                         if (rtn != null){
64                                 rtn=rtn.text()
65                         }
66                 }
67                 return rtn
68         }
69         def getMultNodes(xmlInput, element){
70                 def nodes=null
71                 if(xmlInput!=null){
72                         def xml= new XmlSlurper().parseText(xmlInput)
73                         nodes = xml.'**'.findAll{ node-> node.name() == element }*.text()
74                 }
75                 return nodes
76         }
77         /**
78          * Note: this uses XmlParser instead of XmlSlurper, thus it is not as
79          * efficient because it instantiates the whole DOM tree.
80          * @param xmlInput
81          * @param element
82          * @return a list of Nodes, or {@code null} if <i>xmlInput</i> is {@code null}
83          */
84         def getMultNodeObjects(xmlInput, element){
85                 def nodes=null
86                 if(xmlInput!=null){
87                         def xml= new XmlParser().parseText(xmlInput)
88                         nodes = xml.'**'.findAll{ node-> node.name() == element }
89                 }
90                 return nodes
91         }
92         
93         def getNodeXml(xmlInput,element){
94                 return getNodeXml(xmlInput, element, true)
95         }
96         def getNodeXml(xmlInput,element,incPreamble){
97                 def fxml= new XmlSlurper().parseText(xmlInput)
98                 NodeChild nodeToSerialize = fxml.'**'.find {it.name() == element}
99                 if(nodeToSerialize==null){
100                         return ""
101                 }
102                 def nodeAsText = XmlUtil.serialize(nodeToSerialize)
103                 if (!incPreamble) {
104                         nodeAsText = removeXmlPreamble(nodeAsText)
105                 }
106
107                 return unescapeNodeContents(nodeToSerialize, nodeAsText)
108         }
109         
110         def unescapeNodeContents(NodeChild node, String text) {
111                 if (!node.childNodes().hasNext()) {
112                         return StringEscapeUtils.unescapeXml(text)
113                 } else {
114                         return text
115                 }
116         }
117
118         def nodeExists(xmlInput,element){
119                 try {
120                         def fxml= new XmlSlurper().parseText(xmlInput)
121                         def nodeToSerialize = fxml.'**'.find {it.name() == element}
122                         return nodeToSerialize!=null
123                 } catch(Exception e) {
124                         return false
125                 }
126         }
127
128         
129         /***** Utilities when using XmlParser *****/
130         
131         /**
132          * Convert a Node into a String by deserializing it and formatting it.
133          *
134          * @param node Node to be converted.
135          * @return the Node as a String.
136          */
137         def String nodeToString(Node node) {
138                 def String nodeAsString = groovy.xml.XmlUtil.serialize(node)
139                 nodeAsString = removeXmlPreamble(nodeAsString)
140                 return formatXml(nodeAsString)
141         }
142         
143         /**
144          * Get the specified child Node of the specified parent. If there are
145          * multiple children of the same name, only the first one is returned.
146          * If there are no children with the specified name, 'null' is returned.
147          * 
148          * @param parent Parent Node in which to find a child.
149          * @param childNodeName Name of the child Node to get.
150          * @return the (first) child Node with the specified name or 'null'
151          * if a child Node with the specified name does not exist.
152          */
153         def Node getChildNode(Node parent, String childNodeName) {
154                 def NodeList nodeList = getIdenticalChildren(parent, childNodeName)
155                 if (nodeList.size() == 0) {
156                         return null
157                 } else {
158                         return nodeList.get(0)
159                 }
160         }
161         
162         /**
163          * Get the textual value of the specified child Node of the specified parent.
164          * If there are no children with the specified name, 'null' is returned.
165          * 
166          * @param parent Parent Node in which to find a child.
167          * @param childNodeName Name of the child Node whose value to get.
168          * @return the textual value of child Node with the specified name or 'null'
169          * if a child Node with the specified name does not exist.
170          */
171         def String getChildNodeText(Node parent, String childNodeName) {
172                 def Node childNode = getChildNode(parent, childNodeName)
173                 if (childNode == null) {
174                         return null
175                 } else {
176                         return childNode.text()
177                 }
178         }
179         
180         /**
181          * Get all of the child nodes from the specified parent that have the
182          * specified name.  The returned NodeList could be empty.
183          * 
184          * @param parent Parent Node in which to find children.
185          * @param childNodeName Name of the children to get.
186          * @return a NodeList of all the children from the parent with the specified
187          * name. The list could be empty.
188          */
189         def NodeList getIdenticalChildren(Node parent, String childNodeName) {
190                 return (NodeList) parent.get(childNodeName)
191         }
192
193         /***** End of Utilities when using XmlParser *****/
194
195         
196         /** these are covered under the common function above**/
197         def getSubscriberName(xmlInput,element){
198                 def rtn=null
199                 if(xmlInput!=null){
200                         def xml= new XmlSlurper().parseText(xmlInput)
201                         rtn= xml.'**'.find{node->node.name()==element}.text()
202                 } 
203                 return rtn
204         }
205         def getTenantInformation(xmlInput,element){
206                 def xml= new XmlSlurper().parseText(xmlInput)
207                 def nodeToSerialize = xml.'**'.find {it.name() == 'service-information'}
208                 def nodeAsText = XmlUtil.serialize(nodeToSerialize)
209                 return nodeAsText
210         }
211         def getServiceInstanceId(xmlInput,element){
212                 def xml= new XmlSlurper().parseText(xmlInput)
213                 return ( xml.'**'.find{node->node.name()==element}.text() )
214         }
215         //for aai tenant url
216         def searchResourceLink(xmlInput, resourceType){
217                 def fxml= new XmlSlurper().parseText(xmlInput)
218                 def element = fxml.'**'.find {it.'resource-type' == resourceType}
219                 return (element == null) ? null : element.'resource-link'.text()
220         }
221
222         def searchMetaData(xmlInput, searchName, searchValue){
223                 def fxml= new XmlSlurper().parseText(xmlInput)
224                 def ret = fxml.'**'.find {it.metaname.text() == searchName && it.metaval.text() == searchValue}
225                 if(ret != null){
226                         return ret.parent().parent()
227                 }
228                 return ret
229         }
230         
231         def searchMetaDataNode(fxml, searchName, searchValue){
232                 def ret = fxml.'**'.find {it.metaname.text() == searchName && it.metaval.text() == searchValue}
233                 if(ret != null){
234                         return ret.parent().parent()
235                 }
236                 return ret
237         }
238         
239         // for Trinity L3 add/delete bonding
240         def getPBGFList(isDebugLogEnabled, xmlInput){
241                 log("DEBUG", "getPBGFList: xmlInput " + xmlInput,isDebugLogEnabled)
242                 ArrayList myNodes = new ArrayList()
243                 if(nodeExists(xmlInput,"nbnc-response-information")){
244                 def respInfo=getNodeXml(xmlInput,"nbnc-response-information", false)
245                 if(respInfo!=null){
246                         def fxml= new XmlSlurper().parseText(respInfo)
247                         fxml.'virtual-datacenter-list'.each { vdc ->
248                                 //we only want to add two BGF per VDC, BGF1 and BGF2
249                                         def routerList = vdc.'router-list'.first()
250                                         routerList.each{ myList ->
251                                                 def physNodes  = myList.'**'.findAll {it.'border-element-tangibility'.text() =~ /PHYSICAL/}
252                                                 def nodeToAdd
253                                                 physNodes.each{
254                                                         if(nodeToAdd==null){
255                                                                 nodeToAdd = it
256                                                         }else{
257                                                                 def beid = nodeToAdd.'border-element-id'.text() +
258                                                                          " " + nodeToAdd.'border-element-type'.text() +
259                                                                          " and " +
260                                                                          it.'border-element-id'.text() +
261                                                                          " " + it.'border-element-type'.text()
262                                                                 def mytag = nodeToAdd.'border-element-id'
263                                                                 mytag[0].replaceBody(beid)
264                                                         }
265                                                 }
266                                                 def mytag = nodeToAdd.'vlan-id'
267                                                 def ind = mytag.text().indexOf('.')
268                                                 if(ind >= 0){
269                                                         def vlan = mytag.text().substring(0,ind)
270                                                         mytag[0].replaceBody(vlan)
271                                                 }
272                                                 myNodes.add(XmlUtil.serialize(nodeToAdd))
273                                         }
274                                         
275                         }
276                 }
277                                 
278                         return myNodes
279                 }else{
280                         return null
281                 }
282         }
283         
284         def getPBGFList(xmlInput){
285                 getPBGFList("false", xmlInput)
286         }
287         
288         def getMetaVal(node, name){
289                 try{
290                         return node.'**'.find {it.metaname.text() == name}.metaval.text()
291                 }catch(Exception e){
292                         return null
293                 }
294         }
295
296         def log(logmode,logtxt,isDebugLogEnabled="false"){
297                 if ("INFO"==logmode) {
298                         logger.info(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, logtxt, "BPMN");
299                 } else if ("WARN"==logmode) {
300                         logger.warn ("{} {} {} {} {}", MessageEnum.BPMN_GENERAL_WARNING.toString(), logtxt, "BPMN",
301                                         ErrorCode.UnknownError.getValue(), logtxt);
302                 } else if ("ERROR"==logmode) {
303                     logger.error("{} {} {} {} {}", MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(), logtxt, "BPMN",
304                                         ErrorCode.UnknownError.getValue(), logtxt);
305
306                 } else {
307                         BPMNLogger.debug(isDebugLogEnabled, logtxt);
308                 }
309         }
310
311         def logContext(requestId, serviceInstanceId){
312 //              msoLogger.setLogContext(requestId, serviceInstanceId);
313         }
314         
315         def logMetrics(elapsedTime, logtxt){
316                 
317 //              msoLogger.recordMetricEvent (elapsedTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
318 //                      logtxt, "BPMN", MsoLogger.getServiceName(), null);
319         }
320
321         def logAudit(logtxt){
322                 long startTime = System.currentTimeMillis();
323                 
324 //              msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, logtxt);
325         }
326         
327         // headers: header - name-value
328         def getHeaderNameValue(xmlInput, nameAttribute){
329                 def rtn=null
330                 if(xmlInput!=null){
331                         def xml= new XmlSlurper().parseText(xmlInput)
332                         rtn= xml.'**'.find {header->header.'@name'.text() == nameAttribute}.'@value'
333                 }
334                 return rtn
335         }
336         
337         /**
338          * Gets the children of the specified element.
339          */
340         public String getChildNodes(xmlInput, element) {
341                 def xml= new XmlSlurper().parseText(xmlInput)
342                 def thisElement = xml.'**'.find {it.name() == element}
343                 StringBuilder out = new StringBuilder()
344                 if (thisElement != null) {
345                         thisElement.children().each() {
346                                 String nodeAsText = removeXmlPreamble(XmlUtil.serialize(it))
347                                 if (out.length() > 0) {
348                                         out.append(System.lineSeparator())
349                                 }
350                                 out.append(nodeAsText)
351                         }
352                 }
353                 return out.toString();
354         }
355         
356         /**
357          * Encodes a value so it can be used inside an XML text element.
358          * 
359          * <b>Will double encode</b>
360          * @param s the string to encode
361          * @return the encoded string
362          */
363         public static String xmlEscape(Object value) {
364                 return XmlTool.encode(value)
365         }
366         
367         /**
368          * Removes the preamble, if present, from an XML document.
369          * Also, for historical reasons, this also trims leading and trailing
370          * whitespace from the resulting document.  TODO: remove the trimming
371          * and fix unit tests that depend on EXACT xml format.
372          * @param xml the XML document
373          * @return a possibly modified document
374          */
375         public String removeXmlPreamble(def xml) {
376                 if (xml == null) {
377                         return null
378                 }
379
380                 return XmlTool.removePreamble(xml).trim()
381         }
382
383         /**
384          * Removes namespaces and namespace declarations from an XML document.
385          * @param xml the XML document
386          * @return a possibly modified document
387          */
388         public String removeXmlNamespaces(def xml) {
389                 return XmlTool.removeNamespaces(xml);
390         }
391
392         /**
393          * Use formatXml instead.  Note: this method inserts an XML preamble.
394          */
395         @Deprecated
396         def formatXML(xmlInput) {
397                 def parseXml = null
398                 def formatXml = null
399                 if (xmlInput !=null) {
400                         parseXml = new XmlParser().parseText(xmlInput)
401                         formatXml = XmlUtil.serialize(parseXml)
402                 }
403         }
404
405         /**
406          * Reformats an XML document. The result will not contain an XML preamble
407          * or a trailing newline.
408          * @param xml the XML document
409          * @return a reformatted document
410          */
411         public String formatXml(def xml) {
412                 return XmlTool.normalize(xml);
413         }
414         
415         // build single elements
416         def buildElements(xmlInput, elementList, parentName) {
417                 String var = ""
418                 def xmlBuild = ""
419                 if (parentName != "") {
420                    xmlBuild += "<tns2:"+parentName+">"
421                 }   
422                 if (xmlInput != null) {
423                            for (element in elementList) {
424                               def xml= new XmlSlurper().parseText(xmlInput)
425                               var = xml.'**'.find {it.name() == element}
426                                   if (var != null) {
427                                  xmlBuild += "<tns2:"+element+">"+var.toString()+"</tns2:"+element+">"
428                                   } 
429                            }
430                 }
431                 if (parentName != "") {
432                    xmlBuild += "</tns2:"+parentName+">"
433                 }   
434                 return xmlBuild
435         }
436         
437         // build the Unbounded elements
438         def buildElementsUnbounded(xmlInput, elementList, parentName) {
439                 def varParents = ""
440                 def var = ""
441                 def xmlBuildUnbounded = ""
442                 if (xmlInput != null) {
443                         def xml= new XmlSlurper().parseText(xmlInput)
444                         varParents = xml.'**'.findAll {it.name() == parentName}
445                         //println " Unbounded ${parentName} - varParent.Size() - " + varParents.size()
446                         for (i in 0..varParents.size()-1) {
447                                 if (parentName != "") {
448                                         xmlBuildUnbounded += "<tns2:"+parentName+">"
449                                  }
450                                 for (element in elementList) {
451                                         var = varParents[i].'*'.find {it.name() == element}
452                                    if (var != null) {
453                                           xmlBuildUnbounded += "<tns2:"+element+">"+var.toString()+"</tns2:"+element+">"
454                                           //println " i = " + i + ", element: " + element + " = " + var.toString()
455                                    }
456                                 }
457                                 if (parentName != "") {
458                                         xmlBuildUnbounded += "</tns2:"+parentName+">"
459                                  }
460                         }
461                 }
462                 return xmlBuildUnbounded
463          }
464         
465         // Build l2-homing-information
466         def buildL2HomingInformation(xmlInput) {
467                 def elementsL2HomingList = ["evc-name", "topology", "preferred-aic-clli","aic-version"]
468                 def rebuildL2Home = ''
469                 if (xmlInput != null) {
470                         rebuildL2Home = buildElements(xmlInput, elementsL2HomingList, "l2-homing-information")
471                 }
472                 return rebuildL2Home
473         }
474         
475         // Build internet-evc-access-information
476         def buildInternetEvcAccessInformation(xmlInput) {
477                 def elementsInternetEvcAccessInformationList = ["internet-evc-speed-value", "internet-evc-speed-units", "ip-version"]
478                 def rebuildInternetEvcAccess = ''
479                 if (xmlInput != null) {
480                         rebuildInternetEvcAccess = buildElements(xmlInput, elementsInternetEvcAccessInformationList, "internet-evc-access-information")
481                 }
482                 return rebuildInternetEvcAccess
483         }
484         
485         // Build ucpe-vms-service-information
486         def buildUcpeVmsServiceInformation(xmlInput) {
487                 def rebuildUcpeVmsServiceInformation = ''
488                 if (xmlInput != null) {
489                         def ucpeVmsServiceInformation = getNodeXml(xmlInput, "ucpe-vms-service-information").drop(38).trim()
490                         rebuildUcpeVmsServiceInformation = "<tns2:ucpe-vms-service-information>"
491                         // transport-service-information
492                         rebuildUcpeVmsServiceInformation += "<tns2:transport-service-information>"
493                         def transportServiceInformation = getNodeXml(ucpeVmsServiceInformation, "transport-service-information").drop(38).trim()
494                         def elementsTransportServiceInformationList = ["transport-service-type"]
495                         rebuildUcpeVmsServiceInformation += buildElements(transportServiceInformation, elementsTransportServiceInformationList, "")
496                         try { // optional
497                                 def accessCircuitInfoList = ["access-circuit-id", "dual-mode"]
498                                 rebuildUcpeVmsServiceInformation += buildElementsUnbounded(transportServiceInformation, accessCircuitInfoList, "access-circuit-info")
499                         } catch (Exception e) {
500                            log("ERROR", " Optional - Exception ACCESS-CIRCUIT-INFO - 'access-circuit-info' ")
501                         }
502                         rebuildUcpeVmsServiceInformation += "</tns2:transport-service-information>"
503                         // ucpe-information
504                         def elementsUcpeInformationList = ["ucpe-host-name", "ucpe-activation-code", "out-of-band-management-modem" ]
505                         rebuildUcpeVmsServiceInformation += buildElements(ucpeVmsServiceInformation, elementsUcpeInformationList, "ucpe-information")
506                         // vnf-list
507                         rebuildUcpeVmsServiceInformation += "<tns2:vnf-list>"
508                         def vnfListList = ["vnf-instance-id", "vnf-sequence-number", "vnf-type", "vnf-vendor", "vnf-model", "vnf-id", "prov-status", "operational-state", "orchestration-status", "equipment-role" ]
509                         rebuildUcpeVmsServiceInformation += buildElementsUnbounded(ucpeVmsServiceInformation, vnfListList, "vnf-information")
510                         rebuildUcpeVmsServiceInformation += "</tns2:vnf-list>"
511                         rebuildUcpeVmsServiceInformation += "</tns2:ucpe-vms-service-information>"
512                 }
513                 log("DEBUG", " rebuildUcpeVmsServiceInformation - " + rebuildUcpeVmsServiceInformation)
514                 return rebuildUcpeVmsServiceInformation
515         }
516         
517     // Build internet-service-change-details
518         def buildInternetServiceChangeDetails(xmlInput) {
519                 def rebuildInternetServiceChangeDetails = ""
520                 if (xmlInput != null) {
521                     try { // optional
522                                 def internetServiceChangeDetails = getNodeXml(xmlInput, "internet-service-change-details").drop(38).trim()
523                                 rebuildInternetServiceChangeDetails = "<tns:internet-service-change-details>"
524                                 rebuildInternetServiceChangeDetails += buildElements(internetServiceChangeDetails, ["internet-evc-speed-value"], "")
525                                 rebuildInternetServiceChangeDetails += buildElements(internetServiceChangeDetails, ["internet-evc-speed-units"], "")
526                                 rebuildInternetServiceChangeDetails += buildElements(internetServiceChangeDetails, ["v4-vr-lan-address"], "")
527                                 rebuildInternetServiceChangeDetails += buildElements(internetServiceChangeDetails, ["v4-vr-lan-prefix-length"], "")
528                                 try { // optional
529                                    def tProvidedV4LanPublicPrefixesChangesList = ["request-index", "v4-next-hop-address", "v4-lan-public-prefix", "v4-lan-public-prefix-length"]
530                                    rebuildInternetServiceChangeDetails += buildElementsUnbounded(internetServiceChangeDetails, tProvidedV4LanPublicPrefixesChangesList, "t-provided-v4-lan-public-prefixes")
531                                 } catch (Exception e) {
532                                    log("ERROR"," Optional - Exception in INTERNET-SERVICE-CHANGE-DETAILS 't-provided-v4-lan-public-prefixes ")
533                             }
534                                 try { // optional
535                                   def tProvidedV6LanPublicPrefixesChangesList = ["request-index", "v6-next-hop-address", "v6-lan-public-prefix", "v6-lan-public-prefix-length"]
536                                   rebuildInternetServiceChangeDetails += buildElementsUnbounded(internetServiceChangeDetails, tProvidedV6LanPublicPrefixesChangesList, "t-provided-v6-lan-public-prefixes")
537                                 } catch (Exception e) {
538                                         log("ERROR"," Optional - Exception INTERNET-SERVICE-CHANGE-DETAILS 't-provided-v6-lan-public-prefixes ")
539                                 }
540                                 rebuildInternetServiceChangeDetails += "</tns:internet-service-change-details>"
541                         } catch (Exception e) {
542                                 log("ERROR", " Optional - Exception INTERNET-SERVICE-CHANGE-DETAILS 'internet-service-change-details' ")
543                         }
544                 }
545             return rebuildInternetServiceChangeDetails
546         }               
547         
548         // Build vr-lan 
549         def buildVrLan(xmlInput) {
550                 
551                 def rebuildVrLan = ''
552                 if (xmlInput != null) {
553                         
554                         rebuildVrLan = "<tns2:vr-lan>"
555                         def vrLan = getNodeXml(xmlInput, "vr-lan").drop(38).trim()
556                         rebuildVrLan += buildElements(vrLan, ["routing-protocol"], "")
557                         
558                         // vr-lan-interface
559                         def rebuildVrLanInterface = "<tns2:vr-lan-interface>"
560                         def vrLanInterface = getNodeXml(vrLan, "vr-lan-interface").drop(38).trim()
561                         rebuildVrLanInterface += buildVrLanInterfacePartial(vrLanInterface)
562                         
563                          // dhcp
564                          def dhcp = getNodeXml(vrLan, "dhcp").drop(38).trim()
565                          def rebuildDhcp = buildDhcp(dhcp)
566                          rebuildVrLanInterface += rebuildDhcp
567                          
568                          // pat
569                          def pat = getNodeXml(vrLan, "pat").drop(38).trim()
570                          def rebuildPat = buildPat(pat)
571                          rebuildVrLanInterface += rebuildPat
572                          
573                          // nat
574                          def rebuildNat = ""
575                          try { // optional
576                                 def nat = getNodeXml(vrLan, "nat").drop(38).trim()
577                                 rebuildNat = buildNat(nat)
578                          } catch (Exception e) {
579                                  log("ERROR", " Optional - Exception 'nat' ")
580                          }
581                          rebuildVrLanInterface += rebuildNat
582                                                                                 
583                          // firewall-lite
584                          def firewallLite = getNodeXml(vrLan, "firewall-lite").drop(38).trim()
585                          def rebuildFirewallLite = buildFirewallLite(firewallLite)
586                          rebuildVrLanInterface += rebuildFirewallLite
587                          
588                          // static-routes
589                          def rebuildStaticRoutes = ""
590                          try { // optional 
591                                  def staticRoutes = getNodeXml(vrLan, "static-routes").drop(38).trim()
592                                  rebuildStaticRoutes = buildStaticRoutes(staticRoutes)
593                         } catch (Exception e) {
594                                  log("ERROR", " Optional - Exception 'static-routes' ")
595                         }
596                         rebuildVrLanInterface += rebuildStaticRoutes
597                          
598                    rebuildVrLan += rebuildVrLanInterface
599                    rebuildVrLan += "</tns2:vr-lan-interface>"
600                    rebuildVrLan += "</tns2:vr-lan>"
601                         
602                 }
603                 log("DEBUG", " rebuildVrLan - " + rebuildVrLan)
604                 return rebuildVrLan             
605         }
606         
607         // Build vr-lan-interface
608         def buildVrLanInterfacePartial(xmlInput) {
609                 def rebuildingVrLanInterface = ''
610                 if (xmlInput != null) {
611                         def vrLanInterfaceList = ["vr-designation", "v4-vr-lan-prefix", "v4-vr-lan-address", "v4-vr-lan-prefix-length", "v6-vr-lan-prefix", "v6-vr-lan-address", "v6-vr-lan-prefix-length", "v4-vce-loopback-address", "v6-vce-wan-address"]
612                         rebuildingVrLanInterface += buildElements(xmlInput, vrLanInterfaceList, "")
613                         rebuildingVrLanInterface += "<tns2:v4-public-lan-prefixes>"
614                         try { // optional
615                                 def tProvidedV4LanPublicPrefixes = getNodeXml(xmlInput, "v4-public-lan-prefixes").drop(38).trim()
616                                 def tProvidedV4LanPublicPrefixesList = ["request-index", "v4-next-hop-address", "v4-lan-public-prefix", "v4-lan-public-prefix-length" ]
617                                 rebuildingVrLanInterface += buildElementsUnbounded(xmlInput, tProvidedV4LanPublicPrefixesList, "t-provided-v4-lan-public-prefixes")
618                         } catch (Exception ex) {
619                                 log("ERROR", " Optional - Exception VR-LAN INTERFACE 'v4-public-lan-prefixes' ")
620                         }
621                         rebuildingVrLanInterface += "</tns2:v4-public-lan-prefixes>"
622                         rebuildingVrLanInterface += "<tns2:v6-public-lan-prefixes>"
623                         try { // optional
624                                 def tProvidedV6LanPublicPrefixes = getNodeXml(xmlInput, "v6-public-lan-prefixes").drop(38).trim()
625                                 def tProvidedV6LanPublicPrefixesList = ["request-index", "v6-next-hop-address", "v6-lan-public-prefix", "v6-lan-public-prefix-length" ]
626                                 rebuildingVrLanInterface += buildElementsUnbounded(xmlInput, tProvidedV6LanPublicPrefixesList, "t-provided-v6-lan-public-prefixes")
627                         } catch (Exception e) {
628                                 log("ERROR", " Optional - Exception VR-LAN INTERFACE 'v6-public-lan-prefixes' ")
629                         }
630                         rebuildingVrLanInterface += "</tns2:v6-public-lan-prefixes>"
631                 }
632                 log("DEBUG", " rebuildingVrLanInterface - " + rebuildingVrLanInterface)
633                 return rebuildingVrLanInterface
634         }
635         
636         // Build dhcp
637         def buildDhcp(xmlInput) {
638                 def rebuildingDhcp = ''
639                 if (xmlInput != null) {
640                         def dhcpData = new XmlSlurper().parseText(xmlInput)
641                         rebuildingDhcp = "<tns2:dhcp>"
642                         def dhcpList1 = ["v4-dhcp-server-enabled", "v6-dhcp-server-enabled", "use-v4-default-pool", "v4-dhcp-default-pool-prefix", "v4-dhcp-default-pool-prefix-length"]
643                         rebuildingDhcp += buildElements(xmlInput, dhcpList1, "")
644                         try { // optional
645                                 def excludedV4DhcpAddressesFromDefaultPoolList = ["excluded-v4-address"]
646                                 rebuildingDhcp += buildElementsUnbounded(xmlInput, excludedV4DhcpAddressesFromDefaultPoolList, "excluded-v4-dhcp-addresses-from-default-pool")
647                         } catch (Exception e) {
648                                 log("ERROR", " Optional - Exception DHCP 'excluded-v4-dhcp-addresses-from-default-pool' ")
649                         }
650                         try { // optional
651                                 def v4DhcpPools = dhcpData.'**'.findAll {it.name() == "v4-dhcp-pools"}
652                                 def v4DhcpPoolsSize = v4DhcpPools.size()
653                                 // println " v4DhcpPoolsSize = " + v4DhcpPools.size()
654                                 for (i in 0..v4DhcpPoolsSize-1) {
655                                         def v4DhcpPool = v4DhcpPools[i]
656                                         def v4DhcpPoolXml = XmlUtil.serialize(v4DhcpPool)
657                                         rebuildingDhcp += "<tns2:v4-dhcp-pools>"
658                                         def v4DhcpPoolsList1 = ["v4-dhcp-pool-prefix", "v4-dhcp-pool-prefix-length" ]
659                                         rebuildingDhcp += buildElements(v4DhcpPoolXml, v4DhcpPoolsList1, "")
660                                         try { // optional
661                                            def excludedV4AddressesList = ["excluded-v4-address"]
662                                            rebuildingDhcp += buildElementsUnbounded(v4DhcpPoolXml, excludedV4AddressesList, "excluded-v4-addresses")
663                                         } catch (Exception e) {
664                                            log("ERROR", " Optional - Exception DHCP 'excluded-v4-addresses' ")
665                                         }
666                                         def v4DhcpPoolsList2 = ["v4-dhcp-relay-gateway-address", "v4-dhcp-relay-next-hop-address"]
667                                         rebuildingDhcp += buildElements(v4DhcpPoolXml, v4DhcpPoolsList2, "")
668                                         rebuildingDhcp += "</tns2:v4-dhcp-pools>"
669                                  }
670                          } catch (Exception e) {
671                                   log("ERROR"," Optional - Exception DHCP 'v4-dhcp-pools' ")
672                          }
673                          def dhcpList2 = ["use-v6-default-pool", "v6-dhcp-default-pool-prefix", "v6-dhcp-default-pool-prefix-length"]
674                          rebuildingDhcp += buildElements(xmlInput, dhcpList2, "")
675                          try { // optional
676                                  def excludedV6DhcpAddressesFromDdefaultPoolList = ["excluded-v6-address"]
677                                  rebuildingDhcp += buildElementsUnbounded(xmlInput, excludedV6DhcpAddressesFromDdefaultPoolList, "excluded-v6-dhcp-addresses-from-default-pool")
678                          } catch (Exception e) {
679                            log("ERROR", " Optional - Exception DHCP 'excluded-v6-dhcp-addresses-from-default-pool' ")
680                          }
681                          try { // optional
682                                  def v6DhcpPools = dhcpData.'**'.findAll {it.name() == "v6-dhcp-pools"}
683                                  def v6DhcpPoolsSize = v6DhcpPools.size()
684                                  //println " v6DhcpPoolsSize = " + v6DhcpPools.size()
685                                  for (i in 0..v6DhcpPoolsSize-1) {
686                                         def v6DhcpPool = v6DhcpPools[i]
687                                         def v6DhcpPoolXml = XmlUtil.serialize(v6DhcpPool)
688                                         rebuildingDhcp += "<tns2:v6-dhcp-pools>"
689                                         def v6DhcpPoolsList1 = ["v6-dhcp-pool-prefix", "v6-dhcp-pool-prefix-length"]
690                                         rebuildingDhcp += buildElements(v6DhcpPoolXml, v6DhcpPoolsList1, "")
691                                         try { // optional
692                                                 def excludedV6AddressesList = ["excluded-v6-address"]
693                                                 rebuildingDhcp += buildElementsUnbounded(v6DhcpPoolXml, excludedV6AddressesList, "excluded-v6-addresses")
694                                         } catch (Exception e) {
695                                                          log("ERROR", " Optional - Exception DHCP 'excluded-v6-addresses' ")
696                                         }
697                                         def v6DhcpPoolsList2 = ["v6-dhcp-relay-gateway-address", "v6-dhcp-relay-next-hop-address"]
698                                         rebuildingDhcp += buildElements(v6DhcpPoolXml, v6DhcpPoolsList2, "")
699                                         rebuildingDhcp += "</tns2:v6-dhcp-pools>"
700                                  }
701                          } catch (Exception e) {
702                                  log("ERROR", " Optional - Exception DHCP 'v6-dhcp-pools' ")
703                          }
704                          rebuildingDhcp += "</tns2:dhcp>"
705                 }        
706                 log("DEBUG", " rebuildingDhcp - " + rebuildingDhcp)
707                 return rebuildingDhcp
708         }       
709
710         // Build pat
711         def buildPat(xmlInput) {
712                  def rebuildingPat = ''
713                  if (xmlInput != null) {
714                          rebuildingPat = "<tns2:pat>"
715                          def patList = ["v4-pat-enabled", "use-v4-default-pool", "v4-pat-default-pool-prefix", "v4-pat-default-pool-prefix-length"]
716                          rebuildingPat += buildElements(xmlInput, patList, "")
717                          try { // optional
718                                  def v4PatPools = getNodeXml(xmlInput, "v4-pat-pools").drop(38).trim()
719                                  def v4PatPoolsList = ["v4-pat-pool-prefix", "v4-pat-pool-prefix-length", "v4-pat-pool-next-hop-address"]
720                                  rebuildingPat += buildElementsUnbounded(xmlInput, v4PatPoolsList, "v4-pat-pools")
721                          } catch (Exception e) {
722                                 log("ERROR", " Optional - Exception 'v4-pat-pool-next-hop-address' ")
723                          }
724                          rebuildingPat += "</tns2:pat>"
725                  }
726                  log("DEBUG", " rebuildingPat - " + rebuildingPat)
727              return rebuildingPat
728     }
729         
730         // Build nat
731         def buildNat(xmlInput) {
732                 def rebuildingNat = ''
733                 if (xmlInput != null) {
734                         rebuildingNat = "<tns2:nat>"
735                         rebuildingNat += buildElements(xmlInput, ["v4-nat-enabled"], "")
736                         try { // optional
737                          def v4NatMappingEntries = getNodeXml(xmlInput, "v4-nat-mapping-entries").drop(38).trim()
738                          def v4NatMappingEntriesList = ["v4-nat-internal", "v4-nat-next-hop-address", "v4-nat-external"]
739                          rebuildingNat += buildElementsUnbounded(xmlInput, v4NatMappingEntriesList, "v4-nat-mapping-entries")
740                         } catch (Exception e) {
741                            log("ERROR", " Optional - Exception 'v4-nat-external' ")
742                         }
743                         rebuildingNat += "</tns2:nat>"
744                 }
745                 log("DEBUG", " rebuildingNat - " + rebuildingNat)
746             return rebuildingNat
747         }                               
748         
749         // Build firewall-lite
750         def buildFirewallLite(xmlInput) {
751                 def rebuildingFirewallLite = ''
752                 
753                 if (xmlInput != null) {
754                         
755                         def firewallLiteData = new XmlSlurper().parseText(xmlInput)
756                         rebuildingFirewallLite = "<tns2:firewall-lite>"
757                         def firewallLiteList = ["stateful-firewall-lite-v4-enabled", "stateful-firewall-lite-v6-enabled"]
758                         rebuildingFirewallLite += buildElements(xmlInput, firewallLiteList, "")
759                         
760                          try { // optional
761                                  def v4FirewallPacketFilters = firewallLiteData.'**'.findAll {it.name() == "v4-firewall-packet-filters"}
762                                  def v4FirewallPacketFiltersSize = v4FirewallPacketFilters.size()
763                                  //println " v4FirewallPacketFiltersSize = " + v4FirewallPacketFilters.size()
764                                  for (i in 0..v4FirewallPacketFiltersSize-1) {
765                                def v4FirewallPacketFilter = v4FirewallPacketFilters[i]
766                                def v4FirewallPacketFilterXml = XmlUtil.serialize(v4FirewallPacketFilter)
767                                    rebuildingFirewallLite += "<tns2:v4-firewall-packet-filters>"
768                                    def v4FirewallPacketFiltersList = ["v4-firewall-prefix", "v4-firewall-prefix-length", "allow-icmp-ping"]
769                                    rebuildingFirewallLite += buildElements(v4FirewallPacketFilterXml, v4FirewallPacketFiltersList, "")
770                                    try {  // optional
771                                   def udpPortsList = ["port-number"]
772                                           rebuildingFirewallLite += buildElementsUnbounded(v4FirewallPacketFilterXml, udpPortsList, "udp-ports")
773                                    } catch (Exception e) {
774                                           log("ERROR", " Optional - Exception FIREWALL-LITE v4 'udp-ports' ")
775                                    }
776                                    try {  // optional
777                                           def tcpPortsList =  ["port-number"]
778                                           rebuildingFirewallLite += buildElementsUnbounded(v4FirewallPacketFilterXml, tcpPortsList, "tcp-ports")
779                                    } catch (Exception e) {
780                                       log("ERROR", " Optional - Exception FIREWALL-LITE v4 'tcp-ports' ")
781                                    }
782                                    rebuildingFirewallLite += "</tns2:v4-firewall-packet-filters>"
783                                  }
784                          } catch (Exception e) {
785                                  log("ERROR", " Optional - Exception FIREWALL-LITE 'v4-firewall-packet-filters' ")
786                          }
787                          
788                          try { // optional
789                                  def v6FirewallPacketFilters = firewallLiteData.'**'.findAll {it.name() == "v6-firewall-packet-filters"}
790                                  def v6FirewallPacketFiltersSize = v6FirewallPacketFilters.size()
791                                  //println " v6FirewallPacketFiltersSize = " + v6FirewallPacketFilters.size()
792                                  for (i in 0..v6FirewallPacketFiltersSize-1) {
793                                         def v6FirewallPacketFilter = v6FirewallPacketFilters[i]
794                                         def v6FirewallPacketFilterXml = XmlUtil.serialize(v6FirewallPacketFilter)
795                                         rebuildingFirewallLite += "<tns2:v6-firewall-packet-filters>"
796                                         def v6FirewallPacketFiltersList = ["v6-firewall-prefix", "v6-firewall-prefix-length", "allow-icmp-ping"]
797                                         rebuildingFirewallLite += buildElements(v6FirewallPacketFilterXml, v6FirewallPacketFiltersList, "")
798                                         try { // optional
799                                                 def udpPortsList = ["port-number"]
800                                                 rebuildingFirewallLite += buildElementsUnbounded(v6FirewallPacketFilterXml, udpPortsList, "udp-ports")
801                                         } catch (Exception e) {
802                                       log("ERROR", " Optional - Exception FIREWALL-LITE v6 'udp-ports' ")
803                                         }
804                                         try { // optional
805                                                 def tcpPortsList =  ["port-number"]
806                                                 rebuildingFirewallLite += buildElementsUnbounded(v6FirewallPacketFilterXml, tcpPortsList, "tcp-ports")
807                                         } catch (Exception e) {
808                                         log("ERROR", " Optional - Exception FIREWALL-LITE v6 'tcp-ports' ")
809                                         }
810                                rebuildingFirewallLite += "</tns2:v6-firewall-packet-filters>"
811                                  }
812                          } catch (Exception e) {
813                                  log("ERROR", " Optional - Exception FIREWALL-LITE 'v6-firewall-packet-filters' ")
814                          }
815                          rebuildingFirewallLite+= "</tns2:firewall-lite>"
816                 }
817                 log("DEBUG", " rebuildingFirewallLite - " + rebuildingFirewallLite)
818                 return rebuildingFirewallLite
819      }
820         
821         def buildStaticRoutes(xmlInput) {
822                 def rebuildingStaticRoutes = ''
823                 if (xmlInput != null) {
824                         rebuildingStaticRoutes = "<tns2:static-routes>"
825                         def v4StaticRouteslist = ["v4-static-route-prefix","v4-static-route-prefix-length", "v4-next-hop-address"]
826                         rebuildingStaticRoutes += buildElementsUnbounded(xmlInput, v4StaticRouteslist, "v4-static-routes")
827                         def v6StaticRouteslist = ["v6-static-route-prefix","v6-static-route-prefix-length", "v6-next-hop-address"]
828                         rebuildingStaticRoutes += buildElementsUnbounded(xmlInput, v6StaticRouteslist, "v6-static-routes")
829                         rebuildingStaticRoutes += "</tns2:static-routes>"
830                 }
831                 log("DEBUG", " rebuildingStaticRoutes - " + rebuildingStaticRoutes)
832                 return rebuildingStaticRoutes
833         }
834         
835         public String generateCurrentTimeInUtc(){
836                 final  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
837                 sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
838                 final String utcTime = sdf.format(new Date());
839                 return utcTime;
840         }
841         
842         public String generateCurrentTimeInGMT(){
843                 final  SimpleDateFormat sdf = new SimpleDateFormat("E, d MMM yyyy h:m:s z");
844                 sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
845                 final String utcTime = sdf.format(new Date());
846                 return utcTime;
847         }
848         
849
850         /**
851          * @param encryptedAuth: encrypted credentials from urn properties
852          * @param msoKey: key to use to decrypt from urn properties
853          * @return base 64 encoded basic auth credentials
854          */
855         def getBasicAuth(encryptedAuth, msoKey){
856                 if ((encryptedAuth == null || encryptedAuth.isEmpty()) || (msoKey == null || msoKey.isEmpty()))
857                         return null
858                 try {
859                         def auth = decrypt(encryptedAuth, msoKey)
860                         byte[] encoded = Base64.encodeBase64(auth.getBytes())
861                         String encodedString = new String(encoded)
862                         encodedString = "Basic " + encodedString
863                         return encodedString
864                 } catch (Exception ex) {
865                         log("ERROR", "Unable to encode basic auth")
866                         throw ex
867                 }
868         }
869         
870         def encrypt(toEncrypt, msokey){
871                 try {
872                         String result = CryptoUtils.encrypt(toEncrypt, msokey);
873                         return result
874                 }
875                 catch (Exception e) {
876                         log("ERROR", "Failed to encrypt credentials")
877                 }
878         }
879         
880         def decrypt(toDecrypt, msokey){
881                 try {
882                         String result = CryptoUtils.decrypt(toDecrypt, msokey);
883                         return result
884                 }
885                 catch (Exception e) {
886                         log("ERROR", "Failed to decrypt credentials")
887                         throw e
888                 }
889         }
890         
891         /**
892          * Return URL with qualified host name (if any) or urn mapping
893          * @param  String url from urn mapping
894          * @return String url with qualified host name
895          */
896         public String getQualifiedHostNameForCallback(String urnCallbackUrl) {
897                 def callbackUrlToUse = urnCallbackUrl
898                 try{
899                         //swap host name with qualified host name from the jboss properties
900                         def qualifiedHostName = System.getProperty("jboss.qualified.host.name")
901                         if(qualifiedHostName!=null){
902                                 log("DEBUG", "qualifiedHostName:\n" + qualifiedHostName)
903                                 callbackUrlToUse = callbackUrlToUse.replaceAll("(http://)(.*)(:28080*)", {orig, first, torepl, last -> "${first}${qualifiedHostName}${last}"})
904                         }
905                 }catch(Exception e){
906                                 log("DEBUG", "unable to grab qualified host name, using what's in urn properties for callbackurl. Exception was: " + e.printStackTrace())
907                 }
908                 return callbackUrlToUse
909                 
910         }
911         
912         /**
913          * Retrieves text context of the element if the element exists, returns empty string otherwise
914          * @param com.sun.org.apache.xerces.internal.dom.DeferredElementNSImpl element to parse
915          * param String tagName tagName
916          * @return String text content of the element
917          */
918          public String getElementText(Element element, String tagName) {
919                 String text = ""
920                 org.w3c.dom.NodeList nodeList = element.getElementsByTagNameNS("*", tagName)
921                 if (nodeList != null && nodeList.length > 0) {
922                         text = nodeList.item(0).getTextContent()
923                 }
924                 return text
925          }
926          
927          /**
928           *
929           * Find the lowest unused module-index value in a given xml
930           */
931          public String getLowestUnusedIndex(String xml) {
932                  if (xml == null || xml.isEmpty()) {
933                          return "0"
934                  }               
935                  def moduleIndexList = getMultNodes(xml, "module-index") 
936                  if (moduleIndexList == null || moduleIndexList.size() == 0) {                  
937                          return "0"
938                  }
939                  
940                  def sortedModuleIndexList = moduleIndexList.sort{ a, b -> a as Integer <=> b as Integer}
941                 
942                  for (i in 0..sortedModuleIndexList.size()-1) {
943                          if (Integer.parseInt(sortedModuleIndexList[i]) != i) {
944                                  return i.toString()
945                          }
946                  }
947                  return sortedModuleIndexList.size().toString()
948          }
949         /**
950          * This utility checks if there is transaction id already present in MDC.
951          * If found, it returns same else creates new, sets in MDC for future use before returning
952          * @return String RequestId in UUID format.
953          */
954         public String getRequestID()
955         {
956                 String requestId = MDC.get("RequestId")
957                 if(requestId == null || requestId.isEmpty())
958                 {
959                         requestId = java.util.UUID.randomUUID()
960                         MDC.put("RequestId",requestId)
961                         log("DEBUG","MsoUtils - Created new RequestId: " + requestId)
962                 }
963                 else
964                 {
965                         log("DEBUG","MsoUtils - Using existing RequestId: " + requestId)
966                 }
967
968                 return requestId
969         }
970
971         /**
972          * Remove all the empty nodes and attributes from the within the given node
973          * @param node
974          * @return true if all empty nodes and attributes were removed.
975          */
976         public boolean cleanNode( Node node ) {
977                 node.attributes().with { a ->
978                         a.findAll { !it.value }.each { a.remove( it.key ) }
979                 }
980                 node.children().with { kids ->
981                         kids.findAll { it instanceof Node ? !cleanNode( it ) : false }
982                                         .each { kids.remove( it ) }
983                 }
984                 node.attributes() || node.children() || node.text()
985         }
986
987         /**
988          *
989          * @param xml
990          * @return String representation of xml after removing the empty nodes and attributes
991          */
992         public String cleanNode(String xmlString) {
993                 def xml = new XmlParser(false, false).parseText(xmlString)
994                 cleanNode(xml)
995                 return XmlUtil.serialize(xml)
996         }
997 }