groovy node-tree integration
[controller.git] / opendaylight / sal / yang-prototype / yang / yang-data-impl / src / test / java / org / opendaylight / controller / yang / data / impl / NodeHelper.java
1 /*\r
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
3  *\r
4  * This program and the accompanying materials are made available under the\r
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
6  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
7  */\r
8 package org.opendaylight.controller.yang.data.impl;\r
9 \r
10 import groovy.lang.Binding;\r
11 import groovy.lang.GroovyShell;\r
12 import groovy.lang.Script;\r
13 \r
14 import java.io.ByteArrayInputStream;\r
15 import java.io.ByteArrayOutputStream;\r
16 import java.io.IOException;\r
17 import java.io.InputStream;\r
18 import java.io.InputStreamReader;\r
19 import java.io.PrintStream;\r
20 import java.io.Reader;\r
21 import java.io.StringWriter;\r
22 import java.lang.reflect.Method;\r
23 import java.text.MessageFormat;\r
24 import java.util.ArrayList;\r
25 import java.util.List;\r
26 import java.util.Set;\r
27 \r
28 import javax.xml.transform.OutputKeys;\r
29 import javax.xml.transform.Transformer;\r
30 import javax.xml.transform.TransformerFactory;\r
31 import javax.xml.transform.dom.DOMSource;\r
32 import javax.xml.transform.stream.StreamResult;\r
33 \r
34 import org.custommonkey.xmlunit.Diff;\r
35 import org.junit.Assert;\r
36 import org.opendaylight.controller.yang.common.QName;\r
37 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
38 import org.opendaylight.controller.yang.data.api.Node;\r
39 import org.opendaylight.controller.yang.model.api.Module;\r
40 import org.opendaylight.controller.yang.model.api.SchemaContext;\r
41 import org.opendaylight.controller.yang.model.parser.api.YangModelParser;\r
42 import org.opendaylight.controller.yang.parser.impl.YangParserImpl;\r
43 import org.slf4j.Logger;\r
44 import org.slf4j.LoggerFactory;\r
45 import org.w3c.dom.Document;\r
46 import org.xml.sax.SAXException;\r
47 \r
48 /**\r
49  * @author michal.rehak\r
50  *\r
51  */\r
52 public abstract class NodeHelper {\r
53     \r
54     private static final Logger LOG = LoggerFactory.getLogger(NodeHelper.class);\r
55     \r
56     /** xml source of example network configuration */\r
57     public static final String NETWORK_XML = \r
58       "<network xmlns=\"urn:opendaylight:controller:network\">\n" +\r
59       //"<network>\n" +\r
60       "    <topologies>\n" +\r
61       "        <topology>\n" +\r
62       "            <topology-id>topId_01</topology-id>\n" +\r
63       "            <nodes>\n" +\r
64       "                <node>\n" +\r
65       "                    <node-id>nodeId_02</node-id>\n" +\r
66       "                    <supporting-ne>networkId_02</supporting-ne>\n" +\r
67       "                    <termination-points>\n" +\r
68       "                        <termination-point>\n" +\r
69       "                            <tp-id>tpId_03</tp-id>\n" +\r
70       "                        </termination-point>\n" +\r
71       "                    </termination-points>\n" +\r
72       "                </node>\n" +\r
73       "                <node>\n" +\r
74       "                    <node-id>nodeId_16</node-id>\n" +\r
75       "                    <supporting-ne>networkId_17</supporting-ne>\n" +\r
76       "                    <termination-points>\n" +\r
77       "                        <termination-point>\n" +\r
78       "                            <tp-id>tpId_18</tp-id>\n" +\r
79       "                        </termination-point>\n" +\r
80       "                    </termination-points>\n" +\r
81       "                </node>\n" +\r
82       "                <node>\n" +\r
83       "                    <node-id>nodeId_19</node-id>\n" +\r
84       "                    <supporting-ne>networkId_20</supporting-ne>\n" +\r
85       "                    <termination-points>\n" +\r
86       "                        <termination-point>\n" +\r
87       "                            <tp-id>tpId_18</tp-id>\n" +\r
88       "                        </termination-point>\n" +\r
89       "                        <termination-point>\n" +\r
90       "                            <tp-id>tpId_19</tp-id>\n" +\r
91       "                        </termination-point>\n" +\r
92       "                    </termination-points>\n" +\r
93       "                </node>\n" +\r
94       "            </nodes>\n" +\r
95       "            <links>\n" +\r
96       "                <link>\n" +\r
97       "                    <link-id>linkId_04</link-id>\n" +\r
98       "                    <source>\n" +\r
99       "                        <source-node>nodeId_05</source-node>\n" +\r
100       "                        <source-tp>tpId_06</source-tp>\n" +\r
101       "                    </source>\n" +\r
102       "                    <destination>\n" +\r
103       "                        <dest-node>nodeId_07</dest-node>\n" +\r
104       "                        <dest-tp>tpId_08</dest-tp>\n" +\r
105       "                    </destination>\n" +\r
106       "                </link>\n" +\r
107       "                <link>\n" +\r
108       "                    <link-id>linkId_11</link-id>\n" +\r
109       "                    <source>\n" +\r
110       "                        <source-node>nodeId_12</source-node>\n" +\r
111       "                        <source-tp>tpId_13</source-tp>\n" +\r
112       "                    </source>\n" +\r
113       "                    <destination>\n" +\r
114       "                        <dest-node>nodeId_14</dest-node>\n" +\r
115       "                        <dest-tp>tpId_15</dest-tp>\n" +\r
116       "                    </destination>\n" +\r
117       "                </link>\n" +\r
118       "            </links>\n" +\r
119       "        </topology>\n" +\r
120       "    </topologies>\n" +\r
121       "    <network-elements>\n" +\r
122       "        <network-element>\n" +\r
123       "            <element-id>ntElementId_09</element-id>\n" +\r
124       "        </network-element>\n" +\r
125       "        <network-element>\n" +\r
126       "            <element-id>ntElementId_10</element-id>\n" +\r
127       "        </network-element>\n" +\r
128       "    </network-elements>\n" +\r
129       "</network>";\r
130 \r
131     /**\r
132      * @param domTree\r
133      * @param out\r
134      * @throws Exception \r
135      */\r
136     public static void dumpDoc(Document domTree, PrintStream out) throws Exception {\r
137       TransformerFactory transformerFact = TransformerFactory.newInstance();\r
138       transformerFact.setAttribute("indent-number", 4);\r
139       Transformer transformer = transformerFact.newTransformer();\r
140       transformer.setOutputProperty(OutputKeys.INDENT, "yes");\r
141       //initialize StreamResult with File object to save to file\r
142       StreamResult result = new StreamResult(new StringWriter());\r
143       DOMSource source = new DOMSource(domTree);\r
144       transformer.transform(source, result);\r
145       String xmlString = result.getWriter().toString();\r
146       out.println(xmlString);\r
147     }\r
148     \r
149     /**\r
150      * @param qName\r
151      * @return example tree, see {@link #NETWORK_XML}\r
152      */\r
153     public static CompositeNode buildTestConfigTree(QName qName) {\r
154         List<Node<?>> value = new ArrayList<Node<?>>(); \r
155         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "element-id"), null, "ntElementId_09"));\r
156         CompositeNode ntElementNode1 = NodeFactory.createImmutableCompositeNode(new QName(qName, "network-element"), null, value);\r
157         assignParentToChildren(ntElementNode1);\r
158         \r
159         value = new ArrayList<Node<?>>(); \r
160         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "element-id"), null, "ntElementId_10"));\r
161         CompositeNode ntElementNode2 = NodeFactory.createImmutableCompositeNode(new QName(qName, "network-element"), null, value);\r
162         assignParentToChildren(ntElementNode2);\r
163         \r
164         value = new ArrayList<Node<?>>();\r
165         value.add(ntElementNode1);\r
166         value.add(ntElementNode2);\r
167         CompositeNode ntElementsNode = NodeFactory.createImmutableCompositeNode(\r
168                 new QName(qName, "network-elements"), null, value);\r
169         assignParentToChildren(ntElementsNode);\r
170         \r
171         value = new ArrayList<Node<?>>(); \r
172         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "dest-node"), null, "nodeId_07"));\r
173         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "dest-tp"), null, "tpId_08"));\r
174         CompositeNode destination = NodeFactory.createImmutableCompositeNode(\r
175                 new QName(qName, "destination"), null, value);\r
176         assignParentToChildren(destination);\r
177         \r
178         value = new ArrayList<Node<?>>(); \r
179         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "source-node"), null, "nodeId_05"));\r
180         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "source-tp"), null, "tpId_06"));\r
181         CompositeNode source = NodeFactory.createImmutableCompositeNode(\r
182                 new QName(qName, "source"), null, value);\r
183         assignParentToChildren(source);\r
184         \r
185         value = new ArrayList<Node<?>>(); \r
186         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "link-id"), null, "linkId_04"));\r
187         value.add(source);\r
188         value.add(destination);\r
189         CompositeNode link1 = NodeFactory.createImmutableCompositeNode(\r
190                 new QName(qName, "link"), null, value);\r
191         assignParentToChildren(link1);\r
192         \r
193         value = new ArrayList<Node<?>>(); \r
194         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "dest-node"), null, "nodeId_14"));\r
195         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "dest-tp"), null, "tpId_15"));\r
196         destination = NodeFactory.createImmutableCompositeNode(\r
197                 new QName(qName, "destination"), null, value);\r
198         assignParentToChildren(destination);\r
199         \r
200         value = new ArrayList<Node<?>>(); \r
201         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "source-node"), null, "nodeId_12"));\r
202         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "source-tp"), null, "tpId_13"));\r
203         source = NodeFactory.createImmutableCompositeNode(\r
204                 new QName(qName, "source"), null, value);\r
205         assignParentToChildren(source);\r
206         \r
207         value = new ArrayList<Node<?>>(); \r
208         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "link-id"), null, "linkId_11"));\r
209         value.add(source);\r
210         value.add(destination);\r
211         CompositeNode link2 = NodeFactory.createImmutableCompositeNode(\r
212                 new QName(qName, "link"), null, value);\r
213         assignParentToChildren(link2);\r
214         \r
215         value = new ArrayList<Node<?>>(); \r
216         value.add(link1);\r
217         value.add(link2);\r
218         CompositeNode links = NodeFactory.createImmutableCompositeNode(\r
219                 new QName(qName, "links"), null, value);\r
220         assignParentToChildren(links);\r
221         \r
222         \r
223         value = new ArrayList<Node<?>>(); \r
224         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "tp-id"), null, "tpId_03"));\r
225         CompositeNode terminationPointNode1 = NodeFactory.createImmutableCompositeNode(\r
226                 new QName(qName, "termination-point"), null, value);\r
227         assignParentToChildren(terminationPointNode1);\r
228         \r
229         value = new ArrayList<Node<?>>(); \r
230         value.add(terminationPointNode1);\r
231         CompositeNode terminationPointsNode = NodeFactory.createImmutableCompositeNode(\r
232                 new QName(qName, "termination-points"), null, value);\r
233         assignParentToChildren(terminationPointsNode);\r
234         \r
235         value = new ArrayList<Node<?>>(); \r
236         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "node-id"), null, "nodeId_02"));\r
237         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_02"));\r
238         value.add(terminationPointsNode);\r
239         CompositeNode node1Node = NodeFactory.createImmutableCompositeNode(\r
240                 new QName(qName, "node"), null, value);\r
241         assignParentToChildren(node1Node);\r
242         \r
243         value = new ArrayList<Node<?>>(); \r
244         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "tp-id"), null, "tpId_18"));\r
245         terminationPointNode1 = NodeFactory.createImmutableCompositeNode(\r
246                 new QName(qName, "termination-point"), null, value);\r
247         assignParentToChildren(terminationPointNode1);\r
248         \r
249         value = new ArrayList<Node<?>>(); \r
250         value.add(terminationPointNode1);\r
251         terminationPointsNode = NodeFactory.createImmutableCompositeNode(\r
252                 new QName(qName, "termination-points"), null, value);\r
253         assignParentToChildren(terminationPointsNode);\r
254         \r
255         value = new ArrayList<Node<?>>(); \r
256         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "node-id"), null, "nodeId_16"));\r
257         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_17"));\r
258         value.add(terminationPointsNode);\r
259         CompositeNode node2Node = NodeFactory.createImmutableCompositeNode(\r
260                 new QName(qName, "node"), null, value);\r
261         assignParentToChildren(node2Node);\r
262         \r
263         value = new ArrayList<Node<?>>(); \r
264         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "tp-id"), null, "tpId_18"));\r
265         terminationPointNode1 = NodeFactory.createImmutableCompositeNode(\r
266                 new QName(qName, "termination-point"), null, value);\r
267         assignParentToChildren(terminationPointNode1);\r
268         \r
269         value = new ArrayList<Node<?>>(); \r
270         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "tp-id"), null, "tpId_19"));\r
271         CompositeNode terminationPointNode2 = NodeFactory.createImmutableCompositeNode(\r
272                 new QName(qName, "termination-point"), null, value);\r
273         assignParentToChildren(terminationPointNode2);\r
274         \r
275         value = new ArrayList<Node<?>>(); \r
276         value.add(terminationPointNode1);\r
277         value.add(terminationPointNode2);\r
278         terminationPointsNode = NodeFactory.createImmutableCompositeNode(\r
279                 new QName(qName, "termination-points"), null, value);\r
280         assignParentToChildren(terminationPointsNode);\r
281         \r
282         value = new ArrayList<Node<?>>(); \r
283         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "node-id"), null, "nodeId_19"));\r
284         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_20"));\r
285         value.add(terminationPointsNode);\r
286         CompositeNode node3Node = NodeFactory.createImmutableCompositeNode(\r
287                 new QName(qName, "node"), null, value);\r
288         assignParentToChildren(node3Node);\r
289         \r
290         value = new ArrayList<Node<?>>(); \r
291         value.add(node1Node);\r
292         value.add(node2Node);\r
293         value.add(node3Node);\r
294         CompositeNode nodesNode = NodeFactory.createImmutableCompositeNode(\r
295                 new QName(qName, "nodes"), null, value);\r
296         assignParentToChildren(nodesNode);\r
297         \r
298         value = new ArrayList<Node<?>>();\r
299         value.add(links);\r
300         value.add(nodesNode);\r
301         value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "topology-id"), null, "topId_01"));\r
302         CompositeNode topology = NodeFactory.createImmutableCompositeNode(\r
303                 new QName(qName, "topology"), null, value);\r
304         assignParentToChildren(topology);\r
305         \r
306         value = new ArrayList<Node<?>>();\r
307         value.add(topology);\r
308         CompositeNode topologies = NodeFactory.createImmutableCompositeNode(\r
309                 new QName(qName, "topologies"), null, value);\r
310         assignParentToChildren(topologies);\r
311         \r
312         value = new ArrayList<Node<?>>();\r
313         value.add(topologies);\r
314         value.add(ntElementsNode);\r
315         CompositeNode network = NodeFactory.createImmutableCompositeNode(\r
316                 new QName(qName, "network"), null, value);\r
317         assignParentToChildren(network);\r
318         \r
319         return network;\r
320     }\r
321 \r
322     /**\r
323      * @param parentNode\r
324      */\r
325     public static void assignParentToChildren(CompositeNode parentNode) {\r
326         for (Node<?> child : parentNode.getChildren()) {\r
327             ((AbstractNodeTO<?>) child).setParent(parentNode);\r
328         }\r
329     }\r
330 \r
331     /**\r
332      * @return schema context of controller-network.yang\r
333      */\r
334     public static SchemaContext loadSchemaContext() {\r
335         YangModelParser yParser = new YangParserImpl();\r
336         List<InputStream> yangInputStreams = new ArrayList<>();\r
337         yangInputStreams.add(NodeHelper.class.getResourceAsStream(\r
338                 "/controller-network.yang"));\r
339         yangInputStreams.add(NodeHelper.class.getResourceAsStream(\r
340                 "/ietf-inet-types@2010-09-24.yang"));\r
341         Set<Module> modules = yParser\r
342                 .parseYangModelsFromStreams(yangInputStreams);\r
343         return yParser.resolveSchemaContext(modules);\r
344     }\r
345     \r
346     /**\r
347      * @param scriptName \r
348      * @return tree root\r
349      * @throws Exception\r
350      */\r
351     public static CompositeNode loadConfigByGroovy(String scriptName) throws Exception {\r
352         InputStream configStream = NodeHelper.class.getResourceAsStream(scriptName);\r
353         Binding binding = new Binding();\r
354         GroovyShell gShell = new GroovyShell(binding);\r
355         LOG.debug("groovy: starting script parse..  " + scriptName);\r
356                 Script configScript = gShell.parse(new InputStreamReader(configStream));\r
357                 LOG.debug("groovy: starting script..  " + scriptName);\r
358                 configScript.run();\r
359                 LOG.debug("groovy: digging result");\r
360         Object xmlGen = binding.getVariable("xmlGen");\r
361         LOG.debug("xmlGen = " + xmlGen);\r
362         Method getter = xmlGen.getClass().getDeclaredMethod("getBuilder", new Class[0]);\r
363         MyNodeBuilder builder = (MyNodeBuilder) getter.invoke(xmlGen, new Object[0]);\r
364         \r
365         return builder.getRootNode();\r
366     }\r
367     \r
368     /**\r
369      * @param pattern , e.g.: <pre>"//{0}:network/{1}:xx[text() = 'sss']"</pre>\r
370      * @param nsArg , e.g.: <pre>{"uri:ns1", "uri:ns2"}</pre>\r
371      * @return pattern with namespaces: <pre>//uri:ns1:network/uri:ns2:xx[text() = ''sss'']"</pre>\r
372      */\r
373     public static String AddNamespaceToPattern(String pattern, Object... nsArg) {\r
374         Object[] ns = nsArg;\r
375         String patternNs = pattern.replaceAll("'", "''");\r
376         if (ns == null) {\r
377             ns = new Object[]{""};\r
378         } else {\r
379             // add ':' into pattern after placeholders\r
380             patternNs = patternNs.replaceAll("(\\{[0-9]+\\})", "$1:");\r
381         }\r
382         \r
383         return MessageFormat.format(patternNs, ns);\r
384     }\r
385 \r
386     /**\r
387      * @param tree\r
388      * @param xmlFile \r
389      * @param clazz \r
390      * @throws Exception\r
391      * @throws SAXException\r
392      * @throws IOException\r
393      */\r
394     public static void compareXmlTree(Document tree, String xmlFile, Class<?> clazz) throws Exception,\r
395             SAXException, IOException {\r
396         ByteArrayOutputStream actualRaw = new ByteArrayOutputStream();\r
397         dumpDoc(tree, new PrintStream(actualRaw));\r
398         Reader actualReader = new InputStreamReader(new ByteArrayInputStream(actualRaw.toByteArray()));\r
399         \r
400         Reader expectedReader = new InputStreamReader(clazz.getResourceAsStream(xmlFile));\r
401         Diff myDiff = new Diff(expectedReader, actualReader);\r
402         myDiff.overrideDifferenceListener(new IgnoreWhiteCharsDiffListener());\r
403         \r
404         boolean similar = myDiff.similar();\r
405         if (! similar) {\r
406             System.out.println(new String(actualRaw.toByteArray()));\r
407         }\r
408         Assert.assertEquals(myDiff.toString(), true, similar);\r
409     }\r
410 \r
411 }\r