ed9f73cb9b553edbe6160f6bab45119da649bef2
[netconf.git] / restconf / sal-rest-connector / src / test / java / org / opendaylight / controller / sal / restconf / impl / nn / to / xml / test / NnToXmlTest.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.sal.restconf.impl.nn.to.xml.test;
9
10 import static org.junit.Assert.assertTrue;
11
12 import com.google.common.base.VerifyException;
13 import com.google.common.collect.Iterables;
14 import java.io.ByteArrayOutputStream;
15 import java.io.OutputStream;
16 import java.util.List;
17 import javax.ws.rs.core.MediaType;
18 import org.junit.BeforeClass;
19 import org.junit.Rule;
20 import org.junit.Test;
21 import org.junit.rules.ExpectedException;
22 import org.mockito.Mockito;
23 import org.opendaylight.controller.sal.rest.impl.test.providers.AbstractBodyReaderTest;
24 import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeXmlBodyWriter;
25 import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
26 import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
27 import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
28 import org.opendaylight.yangtools.yang.common.QName;
29 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
30 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
31 import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
32 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
33 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
34 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
35 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
36 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
37 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
38 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
39 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
40 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
41 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
42 import org.opendaylight.yangtools.yang.model.util.type.BaseTypes;
43 import org.opendaylight.yangtools.yang.model.util.type.BitsTypeBuilder;
44 import org.opendaylight.yangtools.yang.model.util.type.EnumerationTypeBuilder;
45 import org.opendaylight.yangtools.yang.model.util.type.UnionTypeBuilder;
46
47 public class NnToXmlTest extends AbstractBodyReaderTest {
48
49     @Rule
50     public ExpectedException thrown = ExpectedException.none();
51
52     private final NormalizedNodeXmlBodyWriter xmlBodyWriter;
53     private static SchemaContext schemaContext;
54
55     public NnToXmlTest() throws NoSuchFieldException, SecurityException {
56         super();
57         this.xmlBodyWriter = new NormalizedNodeXmlBodyWriter();
58     }
59
60     @BeforeClass
61     public static void initialization() {
62         schemaContext = schemaContextLoader("/nn-to-xml/yang", schemaContext);
63         CONTROLLER_CONTEXT.setSchemas(schemaContext);
64     }
65
66     @Test
67     public void nnAsYangIdentityrefToXMLTest() throws Exception {
68         final NormalizedNodeContext normalizedNodeContext = prepareIdrefData(null, true);
69         nnToXml(normalizedNodeContext, "<lf11 xmlns:x=\"referenced:module\">x:iden</lf11>");
70     }
71
72     @Test
73     public void nnAsYangIdentityrefWithQNamePrefixToXMLTest() throws Exception {
74         final NormalizedNodeContext normalizedNodeContext = prepareIdrefData("prefix", true);
75         nnToXml(normalizedNodeContext, "<lf11 xmlns", "=\"referenced:module\">", ":iden</lf11>");
76     }
77
78     @Test
79     public void nnAsYangIdentityrefWithPrefixToXMLTest() throws Exception {
80         final NormalizedNodeContext normalizedNodeContext = prepareIdrefData("prefix", false);
81         nnToXml(normalizedNodeContext, "<lf11>no qname value</lf11>");
82     }
83
84     @Test
85     public void nnAsYangLeafrefWithPrefixToXMLTest() throws Exception {
86         final NormalizedNodeContext normalizedNodeContext = prepareLeafrefData();
87         nnToXml(normalizedNodeContext, "<lfBoolean>true</lfBoolean>", "<lfLfref>true</lfLfref>");
88     }
89
90     /**
91      * Negative test when leaf of type leafref references to not-existing leaf.
92      * {@code VerifyException} is expected.
93      */
94     @Test
95     public void nnAsYangLeafrefWithPrefixToXMLNegativeTest() throws Exception {
96         final NormalizedNodeContext normalizedNodeContext = prepareLeafrefNegativeData();
97
98         thrown.expect(VerifyException.class);
99         nnToXml(normalizedNodeContext, "<not-existing>value</not-existing>",
100                 "<lfLfrefNegative>value</lfLfrefnegative>");
101     }
102
103     @Test
104     public void nnAsYangStringToXmlTest() throws Exception {
105         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
106                 TypeDefinitionAwareCodec.from(BaseTypes.stringType()).deserialize("lfStr value"), "lfStr");
107         nnToXml(normalizedNodeContext, "<lfStr>lfStr value</lfStr>");
108     }
109
110     @Test
111     public void nnAsYangInt8ToXmlTest() throws Exception {
112         final String elName = "lfInt8";
113
114         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
115                 TypeDefinitionAwareCodec.from(BaseTypes.int8Type()).deserialize("14"), elName);
116         nnToXml(normalizedNodeContext, "<" + elName + ">14</" + elName + ">");
117     }
118
119     @Test
120     public void nnAsYangInt16ToXmlTest() throws Exception {
121         final String elName = "lfInt16";
122
123         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
124                 TypeDefinitionAwareCodec.from(BaseTypes.int16Type()).deserialize("3000"), elName);
125         nnToXml(normalizedNodeContext, "<" + elName + ">3000</" + elName + ">");
126     }
127
128     @Test
129     public void nnAsYangInt32ToXmlTest() throws Exception {
130         final String elName = "lfInt32";
131
132         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
133                 TypeDefinitionAwareCodec.from(BaseTypes.int32Type()).deserialize("201234"), elName);
134         nnToXml(normalizedNodeContext, "<" + elName + ">201234</" + elName + ">");
135     }
136
137     @Test
138     public void nnAsYangInt64ToXmlTest() throws Exception {
139         final String elName = "lfInt64";
140
141         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
142                 TypeDefinitionAwareCodec.from(BaseTypes.int64Type()).deserialize("5123456789"), elName);
143         nnToXml(normalizedNodeContext, "<" + elName + ">5123456789</" + elName + ">");
144     }
145
146     @Test
147     public void nnAsYangUint8ToXmlTest() throws Exception {
148         final String elName = "lfUint8";
149
150         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
151                 TypeDefinitionAwareCodec.from(BaseTypes.uint8Type()).deserialize("200"), elName);
152         nnToXml(normalizedNodeContext, "<" + elName + ">200</" + elName + ">");
153     }
154
155     @Test
156     public void snAsYangUint16ToXmlTest() throws Exception {
157         final String elName = "lfUint16";
158
159         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
160                 TypeDefinitionAwareCodec.from(BaseTypes.uint16Type()).deserialize("4000"), elName);
161         nnToXml(normalizedNodeContext, "<" + elName + ">4000</" + elName + ">");
162     }
163
164     @Test
165     public void nnAsYangUint32ToXmlTest() throws Exception {
166         final String elName = "lfUint32";
167
168         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
169                 TypeDefinitionAwareCodec.from(BaseTypes.uint32Type()).deserialize("4123456789"), elName);
170         nnToXml(normalizedNodeContext, "<" + elName + ">4123456789</" + elName + ">");
171     }
172
173     @Test
174     public void snAsYangUint64ToXmlTest() throws Exception {
175         final String elName = "lfUint64";
176         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
177                 TypeDefinitionAwareCodec.from(BaseTypes.uint64Type()).deserialize("5123456789"), elName);
178         nnToXml(normalizedNodeContext, "<" + elName + ">5123456789</" + elName + ">");
179     }
180
181     @Test
182     public void nnAsYangBinaryToXmlTest() throws Exception {
183         final String elName = "lfBinary";
184         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
185                 TypeDefinitionAwareCodec.from(BaseTypes.binaryType())
186                         .deserialize("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567"),
187                 elName);
188         nnToXml(normalizedNodeContext,
189                 "<" + elName + ">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567</" + elName + ">");
190     }
191
192     @Test
193     public void nnAsYangBitsToXmlTest() throws Exception {
194         final BitsTypeDefinition.Bit mockBit1 = Mockito.mock(BitsTypeDefinition.Bit.class);
195         Mockito.when(mockBit1.getName()).thenReturn("one");
196         Mockito.when(mockBit1.getPosition()).thenReturn(1L);
197         final BitsTypeDefinition.Bit mockBit2 = Mockito.mock(BitsTypeDefinition.Bit.class);
198         Mockito.when(mockBit2.getName()).thenReturn("two");
199         Mockito.when(mockBit2.getPosition()).thenReturn(2L);
200         final BitsTypeBuilder bitsTypeBuilder = BaseTypes.bitsTypeBuilder(Mockito.mock(SchemaPath.class));
201         bitsTypeBuilder.addBit(mockBit1);
202         bitsTypeBuilder.addBit(mockBit2);
203
204         final String elName = "lfBits";
205         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
206                 TypeDefinitionAwareCodec.from(bitsTypeBuilder.build()).deserialize("one two"), elName);
207         nnToXml(normalizedNodeContext, "<" + elName + ">one two</" + elName + ">");
208     }
209
210     @Test
211     public void nnAsYangEnumerationToXmlTest() throws Exception {
212         final EnumTypeDefinition.EnumPair mockEnum = Mockito.mock(EnumTypeDefinition.EnumPair.class);
213         Mockito.when(mockEnum.getName()).thenReturn("enum2");
214
215         final EnumerationTypeBuilder enumerationTypeBuilder = BaseTypes
216                 .enumerationTypeBuilder(Mockito.mock(SchemaPath.class));
217         enumerationTypeBuilder.addEnum(mockEnum);
218
219         final String elName = "lfEnumeration";
220         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
221                 TypeDefinitionAwareCodec.from(enumerationTypeBuilder.build()).deserialize("enum2"), elName);
222         nnToXml(normalizedNodeContext, "<" + elName + ">enum2</" + elName + ">");
223     }
224
225     @Test
226     public void nnAsYangEmptyToXmlTest() throws Exception {
227         final String elName = "lfEmpty";
228         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
229                 TypeDefinitionAwareCodec.from(BaseTypes.emptyType()).deserialize(null), elName);
230         nnToXml(normalizedNodeContext, "<" + elName + "></" + elName + ">");
231     }
232
233     @Test
234     public void nnAsYangBooleanToXmlTest() throws Exception {
235         final String elName = "lfBoolean";
236         NormalizedNodeContext normalizedNodeContext = prepareNNC(
237                 TypeDefinitionAwareCodec.from(BaseTypes.booleanType()).deserialize("false"), elName);
238         nnToXml(normalizedNodeContext, "<" + elName + ">false</" + elName + ">");
239
240         normalizedNodeContext = prepareNNC(TypeDefinitionAwareCodec.from(BaseTypes.booleanType()).deserialize("true"),
241                 elName);
242         nnToXml(normalizedNodeContext, "<" + elName + ">true</" + elName + ">");
243     }
244
245     @Test
246     public void nnAsYangUnionToXmlTest() throws Exception {
247         final BitsTypeDefinition.Bit mockBit1 = Mockito.mock(BitsTypeDefinition.Bit.class);
248         Mockito.when(mockBit1.getName()).thenReturn("first");
249         Mockito.when(mockBit1.getPosition()).thenReturn(1L);
250         final BitsTypeDefinition.Bit mockBit2 = Mockito.mock(BitsTypeDefinition.Bit.class);
251         Mockito.when(mockBit2.getName()).thenReturn("second");
252         Mockito.when(mockBit2.getPosition()).thenReturn(2L);
253
254         final BitsTypeBuilder bitsTypeBuilder = BaseTypes.bitsTypeBuilder(Mockito.mock(SchemaPath.class));
255         bitsTypeBuilder.addBit(mockBit1);
256         bitsTypeBuilder.addBit(mockBit2);
257
258         final UnionTypeBuilder unionTypeBuilder = BaseTypes.unionTypeBuilder(Mockito.mock(SchemaPath.class));
259         unionTypeBuilder.addType(BaseTypes.int8Type());
260         unionTypeBuilder.addType(bitsTypeBuilder.build());
261         unionTypeBuilder.addType(BaseTypes.booleanType());
262         unionTypeBuilder.addType(BaseTypes.stringType());
263
264         final String elName = "lfUnion";
265
266         // test int8
267         final String int8 = "15";
268         NormalizedNodeContext normalizedNodeContext = prepareNNC(
269                 TypeDefinitionAwareCodec.from(unionTypeBuilder.build()).deserialize(int8), elName);
270         nnToXml(normalizedNodeContext, "<" + elName + ">15</" + elName + ">");
271
272         // test bits
273         final String bits = "first second";
274         normalizedNodeContext = prepareNNC(TypeDefinitionAwareCodec.from(unionTypeBuilder.build()).deserialize(bits),
275                 elName);
276         nnToXml(normalizedNodeContext, "<" + elName + ">[first, second]</" + elName + ">");
277
278         // test boolean
279         final String bool = "true";
280         normalizedNodeContext = prepareNNC(TypeDefinitionAwareCodec.from(unionTypeBuilder.build()).deserialize(bool),
281                 elName);
282         nnToXml(normalizedNodeContext, "<" + elName + ">true</" + elName + ">");
283
284         // test string
285         final String s = "Hi!";
286         normalizedNodeContext = prepareNNC(TypeDefinitionAwareCodec.from(unionTypeBuilder.build()).deserialize(s),
287                 elName);
288         nnToXml(normalizedNodeContext, "<" + elName + ">Hi!</" + elName + ">");
289     }
290
291     private static NormalizedNodeContext prepareNNC(final Object object, final String name) {
292         final QName cont = QName.create("basic:module", "2013-12-2", "cont");
293         final QName lf = QName.create("basic:module", "2013-12-2", name);
294
295         final DataSchemaNode contSchema = schemaContext.getDataChildByName(cont);
296
297         final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> contData = Builders
298                 .containerBuilder((ContainerSchemaNode) contSchema);
299
300         final List<DataSchemaNode> instanceLf = ControllerContext
301                 .findInstanceDataChildrenByName((DataNodeContainer) contSchema, lf.getLocalName());
302         final DataSchemaNode schemaLf = Iterables.getFirst(instanceLf, null);
303
304         contData.withChild(Builders.leafBuilder((LeafSchemaNode) schemaLf).withValue(object).build());
305
306         final NormalizedNodeContext testNormalizedNodeContext = new NormalizedNodeContext(
307                 new InstanceIdentifierContext<>(null, contSchema, null, schemaContext), contData.build());
308
309         return testNormalizedNodeContext;
310     }
311
312     private void nnToXml(final NormalizedNodeContext normalizedNodeContext, final String... xmlRepresentation)
313             throws Exception {
314         final OutputStream output = new ByteArrayOutputStream();
315         this.xmlBodyWriter.writeTo(normalizedNodeContext, null, null, null, this.mediaType, null, output);
316
317         for (String element : xmlRepresentation) {
318             assertTrue(output.toString().contains(element));
319         }
320     }
321
322     private static NormalizedNodeContext prepareLeafrefData() {
323         final QName cont = QName.create("basic:module", "2013-12-2", "cont");
324         final QName lfBoolean = QName.create("basic:module", "2013-12-2", "lfBoolean");
325         final QName lfLfref = QName.create("basic:module", "2013-12-2", "lfLfref");
326
327         final DataSchemaNode contSchema = schemaContext.getDataChildByName(cont);
328
329         final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> contData = Builders
330                 .containerBuilder((ContainerSchemaNode) contSchema);
331
332         List<DataSchemaNode> instanceLf = ControllerContext
333                 .findInstanceDataChildrenByName((DataNodeContainer) contSchema, lfBoolean.getLocalName());
334         DataSchemaNode schemaLf = Iterables.getFirst(instanceLf, null);
335
336         contData.withChild(Builders.leafBuilder((LeafSchemaNode) schemaLf).withValue(Boolean.TRUE).build());
337
338         instanceLf = ControllerContext.findInstanceDataChildrenByName((DataNodeContainer) contSchema,
339                 lfLfref.getLocalName());
340         schemaLf = Iterables.getFirst(instanceLf, null);
341
342         contData.withChild(Builders.leafBuilder((LeafSchemaNode) schemaLf).withValue("true").build());
343
344         final NormalizedNodeContext testNormalizedNodeContext = new NormalizedNodeContext(
345                 new InstanceIdentifierContext<>(null, contSchema, null, schemaContext), contData.build());
346
347         return testNormalizedNodeContext;
348     }
349
350     private static NormalizedNodeContext prepareLeafrefNegativeData() {
351         final QName cont = QName.create("basic:module", "2013-12-2", "cont");
352         final QName lfLfref = QName.create("basic:module", "2013-12-2", "lfLfrefNegative");
353
354         final DataSchemaNode contSchema = schemaContext.getDataChildByName(cont);
355         final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> contData = Builders
356                 .containerBuilder((ContainerSchemaNode) contSchema);
357
358         final List<DataSchemaNode> instanceLf = ControllerContext.findInstanceDataChildrenByName((DataNodeContainer)
359                 contSchema, lfLfref.getLocalName());
360         final DataSchemaNode schemaLf = Iterables.getFirst(instanceLf, null);
361
362         contData.withChild(Builders.leafBuilder((LeafSchemaNode) schemaLf).withValue("value").build());
363
364         return new NormalizedNodeContext(
365                 new InstanceIdentifierContext<>(null, contSchema, null, schemaContext), contData.build());
366     }
367
368     private static NormalizedNodeContext prepareIdrefData(final String prefix, final boolean valueAsQName) {
369         final QName cont = QName.create("basic:module", "2013-12-2", "cont");
370         final QName cont1 = QName.create("basic:module", "2013-12-2", "cont1");
371         final QName lf11 = QName.create("basic:module", "2013-12-2", "lf11");
372
373         final DataSchemaNode contSchema = schemaContext.getDataChildByName(cont);
374
375         final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> contData = Builders
376                 .containerBuilder((ContainerSchemaNode) contSchema);
377
378         final DataSchemaNode cont1Schema = ((ContainerSchemaNode) contSchema).getDataChildByName(cont1);
379
380         final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> cont1Data = Builders
381                 .containerBuilder((ContainerSchemaNode) cont1Schema);
382
383         Object value = null;
384         if (valueAsQName) {
385             value = QName.create("referenced:module", "2013-12-2", "iden");
386         } else {
387             value = "no qname value";
388         }
389
390         final List<DataSchemaNode> instanceLf = ControllerContext
391                 .findInstanceDataChildrenByName((DataNodeContainer) cont1Schema, lf11.getLocalName());
392         final DataSchemaNode schemaLf = Iterables.getFirst(instanceLf, null);
393
394         cont1Data.withChild(Builders.leafBuilder((LeafSchemaNode) schemaLf).withValue(value).build());
395
396         contData.withChild(cont1Data.build());
397
398         final NormalizedNodeContext testNormalizedNodeContext = new NormalizedNodeContext(
399                 new InstanceIdentifierContext<>(null, contSchema, null, schemaContext), contData.build());
400         return testNormalizedNodeContext;
401     }
402
403     @Override
404     protected MediaType getMediaType() {
405         return null;
406     }
407 }