2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.controller.sal.restconf.impl.nn.to.xml.test;
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;
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;
50 public class NnToXmlTest extends AbstractBodyReaderTest {
51 private static EffectiveModelContext schemaContext;
53 private final NormalizedNodeXmlBodyWriter xmlBodyWriter;
55 public NnToXmlTest() {
56 super(schemaContext, null);
57 xmlBodyWriter = new NormalizedNodeXmlBodyWriter();
61 public static void initialization() {
62 schemaContext = schemaContextLoader("/nn-to-xml/yang", schemaContext);
66 public void nnAsYangIdentityrefToXMLTest() throws Exception {
67 final NormalizedNodeContext normalizedNodeContext = prepareIdrefData(null, true);
68 nnToXml(normalizedNodeContext, "<lf11 xmlns:x=\"referenced:module\">x:iden</lf11>");
72 public void nnAsYangIdentityrefWithQNamePrefixToXMLTest() throws Exception {
73 final NormalizedNodeContext normalizedNodeContext = prepareIdrefData("prefix", true);
74 nnToXml(normalizedNodeContext, "<lf11 xmlns", "=\"referenced:module\">", ":iden</lf11>");
78 public void nnAsYangIdentityrefWithPrefixToXMLTest() throws Exception {
79 final NormalizedNodeContext normalizedNodeContext = prepareIdrefData("prefix", false);
80 nnToXml(normalizedNodeContext, "<lf11>no qname value</lf11>");
84 public void nnAsYangLeafrefWithPrefixToXMLTest() throws Exception {
85 nnToXml(prepareLeafrefData(), "<lfBoolean>true</lfBoolean>", "<lfLfref>true</lfLfref>");
89 * Negative test when leaf of type leafref references to not-existing leaf.
90 * {@code VerifyException} is expected.
93 public void nnAsYangLeafrefWithPrefixToXMLNegativeTest() throws Exception {
94 final NormalizedNodeContext normalizedNodeContext = prepareLeafrefNegativeData();
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());
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>");
112 public void nnAsYangInt8ToXmlTest() throws Exception {
113 final String elName = "lfInt8";
115 final NormalizedNodeContext normalizedNodeContext = prepareNNC(
116 TypeDefinitionAwareCodec.from(BaseTypes.int8Type()).deserialize("14"), elName);
117 nnToXml(normalizedNodeContext, "<" + elName + ">14</" + elName + ">");
121 public void nnAsYangInt16ToXmlTest() throws Exception {
122 final String elName = "lfInt16";
124 final NormalizedNodeContext normalizedNodeContext = prepareNNC(
125 TypeDefinitionAwareCodec.from(BaseTypes.int16Type()).deserialize("3000"), elName);
126 nnToXml(normalizedNodeContext, "<" + elName + ">3000</" + elName + ">");
130 public void nnAsYangInt32ToXmlTest() throws Exception {
131 final String elName = "lfInt32";
133 final NormalizedNodeContext normalizedNodeContext = prepareNNC(
134 TypeDefinitionAwareCodec.from(BaseTypes.int32Type()).deserialize("201234"), elName);
135 nnToXml(normalizedNodeContext, "<" + elName + ">201234</" + elName + ">");
139 public void nnAsYangInt64ToXmlTest() throws Exception {
140 final String elName = "lfInt64";
142 final NormalizedNodeContext normalizedNodeContext = prepareNNC(
143 TypeDefinitionAwareCodec.from(BaseTypes.int64Type()).deserialize("5123456789"), elName);
144 nnToXml(normalizedNodeContext, "<" + elName + ">5123456789</" + elName + ">");
148 public void nnAsYangUint8ToXmlTest() throws Exception {
149 final String elName = "lfUint8";
151 final NormalizedNodeContext normalizedNodeContext = prepareNNC(
152 TypeDefinitionAwareCodec.from(BaseTypes.uint8Type()).deserialize("200"), elName);
153 nnToXml(normalizedNodeContext, "<" + elName + ">200</" + elName + ">");
157 public void snAsYangUint16ToXmlTest() throws Exception {
158 final String elName = "lfUint16";
160 final NormalizedNodeContext normalizedNodeContext = prepareNNC(
161 TypeDefinitionAwareCodec.from(BaseTypes.uint16Type()).deserialize("4000"), elName);
162 nnToXml(normalizedNodeContext, "<" + elName + ">4000</" + elName + ">");
166 public void nnAsYangUint32ToXmlTest() throws Exception {
167 final String elName = "lfUint32";
169 final NormalizedNodeContext normalizedNodeContext = prepareNNC(
170 TypeDefinitionAwareCodec.from(BaseTypes.uint32Type()).deserialize("4123456789"), elName);
171 nnToXml(normalizedNodeContext, "<" + elName + ">4123456789</" + elName + ">");
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 + ">");
183 public void nnAsYangBinaryToXmlTest() throws Exception {
184 final String elName = "lfBinary";
185 final NormalizedNodeContext normalizedNodeContext = prepareNNC(
186 TypeDefinitionAwareCodec.from(BaseTypes.binaryType())
187 .deserialize("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567"),
189 nnToXml(normalizedNodeContext,
190 "<" + elName + ">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567</" + elName + ">");
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);
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 + ">");
212 public void nnAsYangEnumerationToXmlTest() throws Exception {
213 final EnumTypeDefinition.EnumPair mockEnum = Mockito.mock(EnumTypeDefinition.EnumPair.class);
214 Mockito.when(mockEnum.getName()).thenReturn("enum2");
216 final EnumerationTypeBuilder enumerationTypeBuilder = BaseTypes
217 .enumerationTypeBuilder(QName.create("foo", "foo"));
218 enumerationTypeBuilder.addEnum(mockEnum);
220 final String elName = "lfEnumeration";
221 final NormalizedNodeContext normalizedNodeContext = prepareNNC(
222 TypeDefinitionAwareCodec.from(enumerationTypeBuilder.build()).deserialize("enum2"), elName);
223 nnToXml(normalizedNodeContext, "<" + elName + ">enum2</" + elName + ">");
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 + "/>");
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 + ">");
241 normalizedNodeContext = prepareNNC(TypeDefinitionAwareCodec.from(BaseTypes.booleanType()).deserialize("true"),
243 nnToXml(normalizedNodeContext, "<" + elName + ">true</" + elName + ">");
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);
255 final BitsTypeBuilder bitsTypeBuilder = BaseTypes.bitsTypeBuilder(QName.create("foo", "foo"));
256 bitsTypeBuilder.addBit(mockBit1);
257 bitsTypeBuilder.addBit(mockBit2);
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());
265 final String elName = "lfUnion";
268 final String int8 = "15";
269 NormalizedNodeContext normalizedNodeContext = prepareNNC(
270 TypeDefinitionAwareCodec.from(unionTypeBuilder.build()).deserialize(int8), elName);
271 nnToXml(normalizedNodeContext, "<" + elName + ">15</" + elName + ">");
274 final String bits = "first second";
275 normalizedNodeContext = prepareNNC(TypeDefinitionAwareCodec.from(unionTypeBuilder.build()).deserialize(bits),
277 nnToXml(normalizedNodeContext, "<" + elName + ">[first, second]</" + elName + ">");
280 final String bool = "true";
281 normalizedNodeContext = prepareNNC(TypeDefinitionAwareCodec.from(unionTypeBuilder.build()).deserialize(bool),
283 nnToXml(normalizedNodeContext, "<" + elName + ">true</" + elName + ">");
286 final String s = "Hi!";
287 normalizedNodeContext = prepareNNC(TypeDefinitionAwareCodec.from(unionTypeBuilder.build()).deserialize(s),
289 nnToXml(normalizedNodeContext, "<" + elName + ">Hi!</" + elName + ">");
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);
296 final DataSchemaNode contSchema = schemaContext.getDataChildByName(cont);
298 final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> contData = SchemaAwareBuilders
299 .containerBuilder((ContainerSchemaNode) contSchema);
301 final List<DataSchemaNode> instanceLf = ControllerContext
302 .findInstanceDataChildrenByName((DataNodeContainer) contSchema, lf.getLocalName());
303 final DataSchemaNode schemaLf = Iterables.getFirst(instanceLf, null);
305 contData.withChild(SchemaAwareBuilders.leafBuilder((LeafSchemaNode) schemaLf).withValue(object).build());
307 final NormalizedNodeContext testNormalizedNodeContext = new NormalizedNodeContext(
308 new InstanceIdentifierContext<>(null, contSchema, null, schemaContext), contData.build());
310 return testNormalizedNodeContext;
313 private void nnToXml(final NormalizedNodeContext normalizedNodeContext, final String... xmlRepresentation)
315 final OutputStream output = new ByteArrayOutputStream();
316 xmlBodyWriter.writeTo(normalizedNodeContext, null, null, null, mediaType, null, output);
318 for (String element : xmlRepresentation) {
319 assertTrue(output.toString().contains(element));
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");
328 final DataSchemaNode contSchema = schemaContext.getDataChildByName(cont);
330 final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> contData = SchemaAwareBuilders
331 .containerBuilder((ContainerSchemaNode) contSchema);
333 List<DataSchemaNode> instanceLf = ControllerContext
334 .findInstanceDataChildrenByName((DataNodeContainer) contSchema, lfBoolean.getLocalName());
335 DataSchemaNode schemaLf = Iterables.getFirst(instanceLf, null);
337 contData.withChild(SchemaAwareBuilders.leafBuilder((LeafSchemaNode) schemaLf).withValue(Boolean.TRUE).build());
339 instanceLf = ControllerContext.findInstanceDataChildrenByName((DataNodeContainer) contSchema,
340 lfLfref.getLocalName());
341 schemaLf = Iterables.getFirst(instanceLf, null);
343 contData.withChild(SchemaAwareBuilders.leafBuilder((LeafSchemaNode) schemaLf).withValue("true").build());
345 final NormalizedNodeContext testNormalizedNodeContext = new NormalizedNodeContext(
346 new InstanceIdentifierContext<>(null, contSchema, null, schemaContext), contData.build());
348 return testNormalizedNodeContext;
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");
355 final DataSchemaNode contSchema = schemaContext.getDataChildByName(cont);
356 final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> contData = SchemaAwareBuilders
357 .containerBuilder((ContainerSchemaNode) contSchema);
359 final List<DataSchemaNode> instanceLf = ControllerContext.findInstanceDataChildrenByName((DataNodeContainer)
360 contSchema, lfLfref.getLocalName());
361 final DataSchemaNode schemaLf = Iterables.getFirst(instanceLf, null);
363 contData.withChild(SchemaAwareBuilders.leafBuilder((LeafSchemaNode) schemaLf).withValue("value").build());
365 return new NormalizedNodeContext(
366 new InstanceIdentifierContext<>(null, contSchema, null, schemaContext), contData.build());
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");
374 final DataSchemaNode contSchema = schemaContext.getDataChildByName(cont);
376 final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> contData = SchemaAwareBuilders
377 .containerBuilder((ContainerSchemaNode) contSchema);
379 final DataSchemaNode cont1Schema = ((ContainerSchemaNode) contSchema).getDataChildByName(cont1);
381 final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> cont1Data = SchemaAwareBuilders
382 .containerBuilder((ContainerSchemaNode) cont1Schema);
386 value = QName.create("referenced:module", "2013-12-02", "iden");
388 value = "no qname value";
391 final List<DataSchemaNode> instanceLf = ControllerContext
392 .findInstanceDataChildrenByName((DataNodeContainer) cont1Schema, lf11.getLocalName());
393 final DataSchemaNode schemaLf = Iterables.getFirst(instanceLf, null);
395 cont1Data.withChild(SchemaAwareBuilders.leafBuilder((LeafSchemaNode) schemaLf).withValue(value).build());
397 contData.withChild(cont1Data.build());
399 final NormalizedNodeContext testNormalizedNodeContext = new NormalizedNodeContext(
400 new InstanceIdentifierContext<>(null, contSchema, null, schemaContext), contData.build());
401 return testNormalizedNodeContext;
405 protected MediaType getMediaType() {