Report ServerException from ApiPathNormalizer
[netconf.git] / restconf / restconf-nb / src / test / java / org / opendaylight / restconf / nb / rfc8040 / databind / AbstractResourceBodyTest.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.jupiter.api.Assertions.assertEquals;
11 import static org.junit.jupiter.api.Assertions.assertNotNull;
12 import static org.junit.jupiter.api.Assertions.assertThrows;
13
14 import com.google.common.collect.ImmutableMap;
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.text.ParseException;
18 import java.util.function.Function;
19 import org.eclipse.jdt.annotation.NonNull;
20 import org.junit.jupiter.api.BeforeAll;
21 import org.junit.jupiter.api.extension.ExtendWith;
22 import org.junit.jupiter.api.function.Executable;
23 import org.mockito.Mock;
24 import org.mockito.junit.jupiter.MockitoExtension;
25 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
26 import org.opendaylight.mdsal.dom.api.DOMMountPoint;
27 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
28 import org.opendaylight.restconf.api.ApiPath;
29 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
30 import org.opendaylight.restconf.common.errors.RestconfError;
31 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.MdsalRestconfStrategy;
32 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy.StrategyAndPath;
33 import org.opendaylight.restconf.server.api.DatabindContext;
34 import org.opendaylight.restconf.server.api.ResourceBody;
35 import org.opendaylight.restconf.server.api.ServerException;
36 import org.opendaylight.yangtools.yang.common.ErrorTag;
37 import org.opendaylight.yangtools.yang.common.ErrorType;
38 import org.opendaylight.yangtools.yang.common.QName;
39 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
40 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
41 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
42
43 @ExtendWith(MockitoExtension.class)
44 abstract class AbstractResourceBodyTest extends AbstractBodyTest {
45     static final NodeIdentifier CONT_NID = new NodeIdentifier(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont"));
46     static final NodeIdentifier CONT1_NID = new NodeIdentifier(QName.create(INSTANCE_IDENTIFIER_MODULE_QNAME, "cont1"));
47
48     static final QName LST11 = QName.create("augment:module", "2014-01-17", "lst11");
49     static final QName KEYVALUE111 = QName.create(LST11, "keyvalue111");
50     static final QName KEYVALUE112 = QName.create(LST11, "keyvalue112");
51
52     static final QName LF111 = QName.create("augment:augment:module", "2014-01-17", "lf111");
53     static final NodeIdentifier LF112_NID = new NodeIdentifier(QName.create(LF111, "lf112"));
54
55     static final QName LF11 = QName.create("augment:module:leaf:list", "2014-01-27", "lf11");
56     static final QName LFLST11 = QName.create(LF11, "lflst11");
57
58     private static DatabindContext DATABIND;
59
60     @Mock
61     DOMDataBroker dataBroker;
62     @Mock
63     DOMMountPointService mountPointService;
64     @Mock
65     DOMMountPoint mountPoint;
66
67     private final Function<InputStream, ResourceBody> bodyConstructor;
68
69     AbstractResourceBodyTest(final Function<InputStream, ResourceBody> bodyConstructor) {
70         assertNotNull(bodyConstructor);
71         this.bodyConstructor = bodyConstructor;
72     }
73
74     @BeforeAll
75     static final void initModelContext() throws Exception {
76         final var testFiles = loadFiles("/instanceidentifier/yang");
77         testFiles.addAll(loadFiles("/modules"));
78         testFiles.addAll(loadFiles("/foo-xml-test/yang"));
79         DATABIND = DatabindContext.ofModel(YangParserTestUtils.parseYangFiles(testFiles));
80     }
81
82     final @NonNull NormalizedNode parse(final String uriPath, final String patchBody) throws IOException {
83         final ApiPath apiPath;
84         try {
85             apiPath = ApiPath.parse(uriPath);
86         } catch (ParseException e) {
87             throw new AssertionError(e);
88         }
89
90         final var strategy = new MdsalRestconfStrategy(DATABIND, dataBroker, ImmutableMap.of(), null, null, null,
91             mountPointService);
92         final StrategyAndPath stratAndPath;
93         try {
94             stratAndPath = strategy.resolveStrategyPath(apiPath);
95         } catch (ServerException e) {
96             throw new AssertionError(e);
97         }
98
99         try (var body = bodyConstructor.apply(stringInputStream(patchBody))) {
100             return body.toNormalizedNode(stratAndPath.path());
101         }
102     }
103
104     static final RestconfError assertError(final Executable executable) {
105         final var ex = assertThrows(RestconfDocumentedException.class, executable);
106         final var errors = ex.getErrors();
107         assertEquals(1, errors.size());
108         return errors.get(0);
109     }
110
111     static final void assertRangeViolation(final Executable executable) {
112         final var error = assertError(executable);
113         assertEquals(ErrorType.APPLICATION, error.getErrorType());
114         assertEquals(ErrorTag.INVALID_VALUE, error.getErrorTag());
115         assertEquals("bar error app tag", error.getErrorAppTag());
116         assertEquals("bar error message", error.getErrorMessage());
117     }
118 }