Further warnings mitigation
[netconf.git] / restconf / restconf-nb / src / test / java / org / opendaylight / restconf / nb / jaxrs / RestconfOperationsPostTest.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.assertNull;
11 import static org.junit.jupiter.api.Assertions.assertEquals;
12 import static org.junit.jupiter.api.Assertions.assertSame;
13 import static org.mockito.ArgumentMatchers.any;
14 import static org.mockito.ArgumentMatchers.eq;
15 import static org.mockito.Mockito.doReturn;
16 import static org.mockito.Mockito.mock;
17
18 import com.google.common.util.concurrent.Futures;
19 import java.util.List;
20 import java.util.Optional;
21 import org.junit.jupiter.api.Test;
22 import org.junit.jupiter.api.extension.ExtendWith;
23 import org.mockito.Mock;
24 import org.mockito.junit.jupiter.MockitoExtension;
25 import org.opendaylight.mdsal.dom.api.DOMActionService;
26 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
27 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
28 import org.opendaylight.mdsal.dom.api.DOMNotificationService;
29 import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
30 import org.opendaylight.mdsal.dom.api.DOMRpcResult;
31 import org.opendaylight.mdsal.dom.api.DOMRpcService;
32 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
33 import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
34 import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
35 import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
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;
40 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
41 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
42 import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
43 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
44 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
45
46 @ExtendWith(MockitoExtension.class)
47 class RestconfOperationsPostTest extends AbstractRestconfTest {
48     private static final QName RPC = QName.create("invoke:rpc:module", "2013-12-03", "rpc-test");
49     private static final ContainerNode INPUT = ImmutableNodes.newContainerBuilder()
50         .withNodeIdentifier(new NodeIdentifier(QName.create(RPC, "input")))
51         .withChild(ImmutableNodes.newContainerBuilder()
52             .withNodeIdentifier(new NodeIdentifier(QName.create(RPC, "cont")))
53             .withChild(ImmutableNodes.leafNode(QName.create(RPC, "lf"), "test"))
54             .build())
55         .build();
56     private static final ContainerNode OUTPUT = ImmutableNodes.newContainerBuilder()
57         .withNodeIdentifier(new NodeIdentifier(QName.create(RPC, "output")))
58         .withChild(ImmutableNodes.leafNode(QName.create(RPC, "content"), "operation result"))
59         .build();
60     private static final EffectiveModelContext MODEL_CONTEXT =
61         YangParserTestUtils.parseYangResourceDirectory("/invoke-rpc");
62
63     @Mock
64     private DOMNotificationService notificationService;
65
66     @Override
67     EffectiveModelContext modelContext() {
68         return MODEL_CONTEXT;
69     }
70
71     @Test
72     void testInvokeRpcWithNonEmptyOutput() {
73         final var result = mock(ContainerNode.class);
74         doReturn(false).when(result).isEmpty();
75
76         prepNNC(result);
77         assertSame(result, assertNormalizedNode(200, ar -> restconf.operationsXmlPOST(
78             apiPath("invoke-rpc-module:rpc-test"), stringInputStream("""
79                 <input xmlns="invoke:rpc:module"/>"""), uriInfo, ar)));
80     }
81
82     @Test
83     void testInvokeRpcWithEmptyOutput() {
84         final var result = mock(ContainerNode.class);
85         doReturn(true).when(result).isEmpty();
86
87         prepNNC(result);
88         assertNull(assertEntity(204, ar -> restconf.operationsJsonPOST(apiPath("invoke-rpc-module:rpc-test"),
89             stringInputStream("""
90                 {
91                   "invoke-rpc-module:input" : {
92                   }
93                 }"""), uriInfo, ar)));
94     }
95
96     @Test
97     void invokeRpcTest() {
98         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult(OUTPUT, List.of()))).when(rpcService)
99             .invokeRpc(RPC, INPUT);
100
101         assertEquals(OUTPUT, assertNormalizedNode(200, ar -> restconf.operationsXmlPOST(
102             apiPath("invoke-rpc-module:rpc-test"), stringInputStream("""
103                 <input xmlns="invoke:rpc:module">
104                   <cont>
105                     <lf>test</lf>
106                   </cont>
107                 </input>"""), uriInfo, ar)));
108     }
109
110     @Test
111     void invokeRpcErrorsAndCheckTestTest() throws Exception {
112         final var exception = new DOMRpcImplementationNotAvailableException(
113                 "No implementation of RPC " + RPC + " available.");
114         doReturn(Futures.immediateFailedFuture(exception)).when(rpcService).invokeRpc(RPC, INPUT);
115
116         final var error = assertError(ar -> restconf.operationsJsonPOST(apiPath("invoke-rpc-module:rpc-test"),
117             stringInputStream("""
118                 {
119                   "invoke-rpc-module:input" : {
120                     "cont" : {
121                       "lf" : "test"
122                     }
123                   }
124                 }"""), uriInfo, ar));
125         assertEquals("No implementation of RPC (invoke:rpc:module?revision=2013-12-03)rpc-test available.",
126             error.getErrorMessage());
127         assertEquals(ErrorType.RPC, error.getErrorType());
128         assertEquals(ErrorTag.OPERATION_FAILED, error.getErrorTag());
129     }
130
131     @Test
132     void invokeRpcViaMountPointTest() throws Exception {
133         doReturn(Optional.of(new FixedDOMSchemaService(MODEL_CONTEXT))).when(mountPoint)
134             .getService(DOMSchemaService.class);
135         doReturn(Optional.of(rpcService)).when(mountPoint).getService(DOMRpcService.class);
136         doReturn(Optional.empty()).when(mountPoint).getService(DOMActionService.class);
137         doReturn(Optional.empty()).when(mountPoint).getService(DOMMountPointService.class);
138         doReturn(Optional.empty()).when(mountPoint).getService(NetconfDataTreeService.class);
139         doReturn(Optional.of(dataBroker)).when(mountPoint).getService(DOMDataBroker.class);
140         doReturn(Optional.of(mountPoint)).when(mountPointService).getMountPoint(YangInstanceIdentifier.of(
141             QName.create("urn:ietf:params:xml:ns:yang:ietf-yang-library", "2019-01-04", "modules-state")));
142         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult(OUTPUT, List.of()))).when(rpcService)
143             .invokeRpc(RPC, INPUT);
144
145         assertEquals(OUTPUT, assertNormalizedNode(200,
146             ar -> restconf.operationsJsonPOST(
147                 apiPath("ietf-yang-library:modules-state/yang-ext:mount/invoke-rpc-module:rpc-test"),
148                 stringInputStream("""
149                     {
150                       "invoke-rpc-module:input" : {
151                         "cont" : {
152                           "lf" : "test"
153                         }
154                       }
155                     }"""), uriInfo, ar)));
156     }
157
158     @Test
159     void invokeRpcMissingMountPointServiceTest() {
160         doReturn(Optional.of(new FixedDOMSchemaService(MODEL_CONTEXT))).when(mountPoint)
161             .getService(DOMSchemaService.class);
162         doReturn(Optional.empty()).when(mountPoint).getService(DOMRpcService.class);
163         doReturn(Optional.empty()).when(mountPoint).getService(DOMActionService.class);
164         doReturn(Optional.empty()).when(mountPoint).getService(DOMMountPointService.class);
165         doReturn(Optional.empty()).when(mountPoint).getService(NetconfDataTreeService.class);
166         doReturn(Optional.of(dataBroker)).when(mountPoint).getService(DOMDataBroker.class);
167         doReturn(Optional.of(mountPoint)).when(mountPointService).getMountPoint(YangInstanceIdentifier.of(
168             QName.create("urn:ietf:params:xml:ns:yang:ietf-yang-library", "2019-01-04", "modules-state")));
169
170         final var error = assertError(
171             ar -> restconf.operationsJsonPOST(
172                 apiPath("ietf-yang-library:modules-state/yang-ext:mount/invoke-rpc-module:rpc-test"),
173                 stringInputStream("""
174                     {
175                       "invoke-rpc-module:input" : {
176                       }
177                     }"""), uriInfo, ar));
178         assertEquals("RPC invocation is not available", error.getErrorMessage());
179         assertEquals(ErrorType.PROTOCOL, error.getErrorType());
180         assertEquals(ErrorTag.OPERATION_NOT_SUPPORTED, error.getErrorTag());
181     }
182
183     @Test
184     void checkResponseTest() throws Exception {
185         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult(OUTPUT, List.of())))
186             .when(rpcService).invokeRpc(RPC, INPUT);
187
188         assertEquals(OUTPUT, assertNormalizedNode(200, ar -> restconf.operationsJsonPOST(
189             apiPath("invoke-rpc-module:rpc-test"),
190             stringInputStream("""
191                 {
192                   "invoke-rpc-module:input" : {
193                     "cont" : {
194                       "lf" : "test"
195                     }
196                   }
197                 }"""), uriInfo, ar)));
198     }
199
200     private void prepNNC(final ContainerNode result) {
201         final var qname = QName.create("invoke:rpc:module", "2013-12-03", "rpc-test");
202         final var domRpcResult = mock(DOMRpcResult.class);
203         doReturn(Futures.immediateFuture(domRpcResult)).when(rpcService).invokeRpc(eq(qname), any(ContainerNode.class));
204         doReturn(result).when(domRpcResult).value();
205     }
206 }