743d0072566281e270315f1fbce0edeb74c8b6d6
[netconf.git] / restconf / restconf-nb / src / test / java / org / opendaylight / restconf / nb / rfc8040 / databind / XmlResourceBodyTest.java
1 /*
2  * Copyright (c) 2023 PANTHEON.tech, s.r.o. 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.restconf.nb.rfc8040.databind;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertThrows;
12
13 import java.util.Map;
14 import org.junit.Test;
15 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
16 import org.opendaylight.yangtools.yang.common.ErrorTag;
17 import org.opendaylight.yangtools.yang.common.ErrorType;
18 import org.opendaylight.yangtools.yang.common.QName;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
23 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
24 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
25
26 public class XmlResourceBodyTest extends AbstractResourceBodyTest {
27     private static final QName TOP_LEVEL_LIST = QName.create("foo", "2017-08-09", "top-level-list");
28
29     public XmlResourceBodyTest() {
30         super(XmlResourceBody::new);
31     }
32
33     /**
34      * Test PUT operation when message root element is not the same as the last element in request URI.
35      * PUT operation message should always start with schema node from URI otherwise exception should be
36      * thrown.
37      */
38     @Test
39     public void wrongRootElementTest() {
40         assertThrowsException("",
41             "Incorrect message root element (instance:identifier:module)cont1, should be "
42                 + "(urn:ietf:params:xml:ns:yang:ietf-restconf)data");
43         assertThrowsException("instance-identifier-module:cont/yang-ext:mount",
44             "Incorrect message root element (instance:identifier:module)cont1, should be "
45                 + "(urn:ietf:params:xml:ns:yang:ietf-restconf)data");
46         assertThrowsException("instance-identifier-module:cont",
47             "Incorrect message root element (instance:identifier:module)cont1, should be "
48                 + "(instance:identifier:module)cont");
49         assertThrowsException("instance-identifier-module:cont/yang-ext:mount/instance-identifier-module:cont",
50             "Incorrect message root element (instance:identifier:module)cont1, should be "
51                 + "(instance:identifier:module)cont");
52     }
53
54     private void assertThrowsException(final String uriPath, final String expectedErrorMessage) {
55         final var ex = assertThrows(RestconfDocumentedException.class,
56             () -> parseResource(uriPath, "/instanceidentifier/xml/bug7933.xml"));
57         final var restconfError = ex.getErrors().get(0);
58         assertEquals(ErrorType.PROTOCOL, restconfError.getErrorType());
59         assertEquals(ErrorTag.MALFORMED_MESSAGE, restconfError.getErrorTag());
60         assertEquals(expectedErrorMessage, restconfError.getErrorMessage());
61     }
62
63     @Test
64     public void testRangeViolation() throws Exception {
65         assertRangeViolation(() -> parse("netconf786:foo", """
66             <foo xmlns="netconf786"><bar>100</bar></foo>"""));
67     }
68
69     @Test
70     public void putXmlTest() throws Exception {
71         final var keyName = QName.create(TOP_LEVEL_LIST, "key-leaf");
72         assertEquals(Builders.mapEntryBuilder()
73             .withNodeIdentifier(NodeIdentifierWithPredicates.of(TOP_LEVEL_LIST, keyName, "key-value"))
74             .withChild(ImmutableNodes.leafNode(keyName, "key-value"))
75             .withChild(ImmutableNodes.leafNode(QName.create(keyName, "ordinary-leaf"), "leaf-value"))
76             .build(), parseResource("foo:top-level-list=key-value", "/foo-xml-test/foo.xml"));
77     }
78
79     @Test
80     public void moduleDataTest() throws Exception {
81         testModuleData("instance-identifier-module:cont");
82     }
83
84     @Test
85     public void moduleDataMountPointTest() throws Exception {
86         testModuleData("instance-identifier-module:cont/yang-ext:mount/instance-identifier-module:cont");
87     }
88
89     private void testModuleData(final String uriPath) throws Exception {
90         final var entryId = NodeIdentifierWithPredicates.of(LST11,
91             Map.of(KEYVALUE111, "value1", KEYVALUE112, "value2"));
92
93         assertEquals(Builders.containerBuilder()
94             .withNodeIdentifier(CONT_NID)
95             .withChild(Builders.containerBuilder()
96                 .withNodeIdentifier(CONT1_NID)
97                 .withChild(Builders.mapBuilder()
98                     .withNodeIdentifier(new NodeIdentifier(LST11))
99                     .withChild(Builders.mapEntryBuilder()
100                         .withNodeIdentifier(entryId)
101                         .withChild(ImmutableNodes.leafNode(KEYVALUE111, "value1"))
102                         .withChild(ImmutableNodes.leafNode(KEYVALUE112, "value2"))
103                         .withChild(ImmutableNodes.leafNode(LF111, YangInstanceIdentifier.of(CONT_NID, CONT1_NID,
104                             new NodeIdentifier(LST11), entryId, LF112_NID)))
105                         .withChild(ImmutableNodes.leafNode(LF112_NID, "lf112 value"))
106                         .build())
107                     .build())
108                 .build())
109             .build(), parseResource(uriPath, "/instanceidentifier/xml/xmldata.xml"));
110     }
111
112     @Test
113     public void moduleSubContainerDataPutTest() throws Exception {
114         testModuleSubContainerDataPut("instance-identifier-module:cont/cont1");
115     }
116
117     @Test
118     public void moduleSubContainerDataPutMountPointTest() throws Exception {
119         testModuleSubContainerDataPut(
120             "instance-identifier-module:cont/yang-ext:mount/instance-identifier-module:cont/cont1");
121     }
122
123     private void testModuleSubContainerDataPut(final String uriPath) throws Exception {
124         assertEquals(Builders.containerBuilder()
125             .withNodeIdentifier(CONT1_NID)
126             .withChild(Builders.leafSetBuilder()
127                 .withNodeIdentifier(new NodeIdentifier(LFLST11))
128                 .withChild(Builders.leafSetEntryBuilder()
129                     .withNodeIdentifier(new NodeWithValue<>(LFLST11, "lflst11_3"))
130                     .withValue("lflst11_3")
131                     .build())
132                 .withChild(Builders.leafSetEntryBuilder()
133                     .withNodeIdentifier(new NodeWithValue<>(LFLST11, "lflst11_1"))
134                     .withValue("lflst11_1")
135                     .build())
136                 .withChild(Builders.leafSetEntryBuilder()
137                     .withNodeIdentifier(new NodeWithValue<>(LFLST11, "lflst11_2"))
138                     .withValue("lflst11_2")
139                     .build())
140                 .build())
141             .withChild(ImmutableNodes.leafNode(LF11, YangInstanceIdentifier.of(CONT_NID, CONT1_NID,
142                 new NodeIdentifier(LFLST11), new NodeWithValue<>(LFLST11, "lflst11_1"))))
143             .build(), parseResource(uriPath, "/instanceidentifier/xml/xml_sub_container.xml"));
144     }
145 }