Move ErrorTags
[netconf.git] / restconf / restconf-nb / src / test / java / org / opendaylight / restconf / nb / jaxrs / RestconfSchemaServiceMountTest.java
1 /*
2  * Copyright (c) 2016 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.restconf.nb.jaxrs;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.opendaylight.restconf.nb.jaxrs.AbstractRestconfTest.assertEntity;
12 import static org.opendaylight.restconf.nb.jaxrs.AbstractRestconfTest.assertError;
13
14 import com.google.common.io.CharStreams;
15 import java.io.Reader;
16 import org.junit.Before;
17 import org.junit.Test;
18 import org.junit.runner.RunWith;
19 import org.mockito.Mock;
20 import org.mockito.junit.MockitoJUnitRunner;
21 import org.opendaylight.mdsal.dom.api.DOMActionService;
22 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
23 import org.opendaylight.mdsal.dom.api.DOMRpcService;
24 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
25 import org.opendaylight.mdsal.dom.broker.DOMMountPointServiceImpl;
26 import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
27 import org.opendaylight.restconf.api.ApiPath;
28 import org.opendaylight.restconf.api.query.PrettyPrintParam;
29 import org.opendaylight.restconf.nb.rfc8040.ErrorTagMapping;
30 import org.opendaylight.restconf.nb.rfc8040.ErrorTags;
31 import org.opendaylight.restconf.server.mdsal.MdsalDatabindProvider;
32 import org.opendaylight.restconf.server.mdsal.MdsalRestconfServer;
33 import org.opendaylight.yangtools.yang.common.ErrorTag;
34 import org.opendaylight.yangtools.yang.common.ErrorType;
35 import org.opendaylight.yangtools.yang.common.QName;
36 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
37 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
38 import org.opendaylight.yangtools.yang.model.api.source.YangTextSource;
39 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
40
41 /**
42  * Unit tests for {@code RestconfSchemaService}.
43  */
44 @RunWith(MockitoJUnitRunner.StrictStubs.class)
45 public class RestconfSchemaServiceMountTest {
46     private static final ApiPath MOUNT_POINT = AbstractRestconfTest.apiPath("mount-point-1:cont/yang-ext:mount");
47     private static final ApiPath NULL_MOUNT_POINT = AbstractRestconfTest.apiPath("mount-point-2:cont/yang-ext:mount");
48     private static final ApiPath NOT_EXISTING_MOUNT_POINT =
49         AbstractRestconfTest.apiPath("mount-point-3:cont/yang-ext:mount");
50
51     // schema context with modules behind mount point
52     private static final EffectiveModelContext SCHEMA_CONTEXT_BEHIND_MOUNT_POINT =
53         YangParserTestUtils.parseYangResourceDirectory("/modules/modules-behind-mount-point");
54     // schema context with mount points
55     private static final EffectiveModelContext SCHEMA_CONTEXT_WITH_MOUNT_POINTS =
56         YangParserTestUtils.parseYangResourceDirectory("/modules/mount-points");
57
58     // handlers
59     @Mock
60     private DOMDataBroker dataBroker;
61     @Mock
62     private DOMActionService actionService;
63     @Mock
64     private DOMRpcService rpcService;
65     @Mock
66     private YangTextSource yangSource;
67     @Mock
68     private Reader yangReader;
69
70     // service under test
71     private JaxRsRestconf restconf;
72
73     @Before
74     public void setup() throws Exception {
75         final var mountPointService = new DOMMountPointServiceImpl();
76         // create and register mount points
77         mountPointService
78                 .createMountPoint(YangInstanceIdentifier.of(QName.create("mount:point:1", "2016-01-01", "cont")))
79                 .addService(DOMSchemaService.class, new FixedDOMSchemaService(SCHEMA_CONTEXT_BEHIND_MOUNT_POINT))
80                 .addService(DOMDataBroker.class, dataBroker)
81                 .register();
82         mountPointService
83                 .createMountPoint(YangInstanceIdentifier.of(QName.create("mount:point:2", "2016-01-01", "cont")))
84                 .register();
85
86         restconf = new JaxRsRestconf(
87             new MdsalRestconfServer(new MdsalDatabindProvider(
88                 new FixedDOMSchemaService(SCHEMA_CONTEXT_WITH_MOUNT_POINTS)), dataBroker, rpcService, actionService,
89                 mountPointService),
90             ErrorTagMapping.RFC8040, PrettyPrintParam.FALSE);
91     }
92
93     /**
94      * Get schema with identifier of existing module behind mount point and check if correct module was found.
95      */
96     @Test
97     public void getSchemaMountPointTest() throws Exception {
98         final var reader = assertEntity(Reader.class, 200,
99             ar -> restconf.modulesYangGET(MOUNT_POINT, "module1-behind-mount-point", "2014-02-03", ar));
100         assertEquals("""
101             module module1-behind-mount-point {
102               namespace module:1:behind:mount:point;
103               prefix mod1bemopo;
104               revision 2014-02-03;
105               rpc rpc-behind-module1;
106             }
107             """, CharStreams.toString(reader));
108     }
109
110     /**
111      * Get schema with identifier of not-existing module behind mount point. Trying to create
112      * <code>SchemaExportContext</code> with not-existing module behind mount point should result in error.
113      */
114     @Test
115     public void getSchemaForNotExistingModuleMountPointTest() {
116         final var error = assertError(ar -> restconf.modulesYangGET(MOUNT_POINT, "not-existing", "2016-01-01", ar));
117         assertEquals("Source not-existing@2016-01-01 not found", error.getErrorMessage());
118         assertEquals(ErrorTag.DATA_MISSING, error.getErrorTag());
119         assertEquals(ErrorType.APPLICATION, error.getErrorType());
120     }
121
122     /**
123      * Try to get schema with <code>null</code> <code>SchemaContext</code> behind mount point when using
124      * <code>NULL_MOUNT_POINT</code>. Test is expected to fail with <code>NullPointerException</code>.
125      */
126     @Test
127     public void getSchemaNullSchemaContextBehindMountPointTest() {
128         // make test - call service on mount point with null schema context
129         // NULL_MOUNT_POINT contains null schema context
130         final var error = assertError(
131             ar -> restconf.modulesYangGET(NULL_MOUNT_POINT, "module1-behind-mount-point", "2014-02-03", ar));
132         assertEquals("Mount point 'mount-point-2:cont' does not expose DOMSchemaService", error.getErrorMessage());
133         assertEquals(ErrorType.PROTOCOL, error.getErrorType());
134         assertEquals(ErrorTags.RESOURCE_DENIED_TRANSPORT, error.getErrorTag());
135     }
136
137     /**
138      * Try to get schema with empty (not valid) identifier behind mount point catching
139      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
140      * values.
141      */
142     @Test
143     public void getSchemaWithEmptyIdentifierMountPointTest() {
144         final var error = assertError(ar -> restconf.modulesYangGET(MOUNT_POINT, "", null, ar));
145         assertEquals("Identifier must start with character from set 'a-zA-Z_", error.getErrorMessage());
146         assertEquals(ErrorType.PROTOCOL, error.getErrorType());
147         assertEquals(ErrorTag.INVALID_VALUE, error.getErrorTag());
148     }
149
150     /**
151      * Try to get schema behind mount point with not-parsable identifier catching
152      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
153      * values.
154      */
155     @Test
156     public void getSchemaWithNotParsableIdentifierMountPointTest() {
157         final var error = assertError(ar -> restconf.modulesYangGET(MOUNT_POINT, "01_module", "2016-01-01", ar));
158         assertEquals("Identifier must start with character from set 'a-zA-Z_", error.getErrorMessage());
159         assertEquals(ErrorType.PROTOCOL, error.getErrorType());
160         assertEquals(ErrorTag.INVALID_VALUE, error.getErrorTag());
161     }
162
163     /**
164      * Try to get schema with wrong (not valid) identifier behind mount point catching
165      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
166      * values.
167      *
168      * <p>
169      * Not valid identifier contains only revision without module name.
170      */
171     @Test
172     public void getSchemaWrongIdentifierMountPointTest() {
173         final var error = assertError(ar -> restconf.modulesYangGET(MOUNT_POINT, "2014-01-01", null, ar));
174         assertEquals("Identifier must start with character from set 'a-zA-Z_", error.getErrorMessage());
175         assertEquals(ErrorType.PROTOCOL, error.getErrorType());
176         assertEquals(ErrorTag.INVALID_VALUE, error.getErrorTag());
177     }
178
179     /**
180      * Try to get schema behind mount point with identifier when does not contain revision catching
181      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
182      * values.
183      */
184     @Test
185     public void getSchemaWithoutRevisionMountPointTest() {
186         final var error = assertError(ar -> restconf.modulesYangGET(MOUNT_POINT, "module", null, ar));
187         assertEquals("Source module not found", error.getErrorMessage());
188         assertEquals(ErrorType.APPLICATION, error.getErrorType());
189         assertEquals(ErrorTag.DATA_MISSING, error.getErrorTag());
190     }
191
192     /**
193      * Negative test when mount point module is not found in current <code>SchemaContext</code> for mount points.
194      * <code>IllegalArgumentException</code> exception is expected.
195      */
196     @Test
197     public void getSchemaContextWithNotExistingMountPointTest() {
198         final var error = assertError(
199             ar -> restconf.modulesYangGET(NOT_EXISTING_MOUNT_POINT, "module1-behind-mount-point", "2014-02-03", ar));
200         assertEquals("Failed to lookup for module with name 'mount-point-3'.", error.getErrorMessage());
201         assertEquals(ErrorType.PROTOCOL, error.getErrorType());
202         assertEquals(ErrorTag.UNKNOWN_ELEMENT, error.getErrorTag());
203     }
204 }