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