X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=restconf%2Frestconf-nb-bierman02%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Frestconf%2Fimpl%2Ftest%2FInvokeRpcMethodTest.java;h=f4909eb24c9e7ceb4c3c90f418f9c56902934d17;hb=18ae8c40de8ebd41ab1253d369c0930b9f48229f;hp=be5170a03e8ab89421c4765f45df37d9594489c7;hpb=f402dcd49a468e018192c96151bef3a0cdf70d62;p=netconf.git diff --git a/restconf/restconf-nb-bierman02/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java b/restconf/restconf-nb-bierman02/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java index be5170a03e..f4909eb24c 100644 --- a/restconf/restconf-nb-bierman02/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java +++ b/restconf/restconf-nb-bierman02/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java @@ -9,59 +9,58 @@ package org.opendaylight.controller.sal.restconf.impl.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFailedFluentFuture; import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFluentFuture; -import com.google.common.base.Optional; import java.io.FileNotFoundException; -import java.net.URI; -import java.net.URISyntaxException; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.List; +import java.util.Optional; +import java.util.Set; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MultivaluedHashMap; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; -import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; -import org.mockito.Mockito; import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils; import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException; import org.opendaylight.mdsal.dom.api.DOMRpcResult; import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult; +import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext; import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade; import org.opendaylight.netconf.sal.restconf.impl.ControllerContext; import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl; +import org.opendaylight.restconf.common.ErrorTags; import org.opendaylight.restconf.common.context.InstanceIdentifierContext; -import org.opendaylight.restconf.common.context.NormalizedNodeContext; import org.opendaylight.restconf.common.errors.RestconfDocumentedException; import org.opendaylight.restconf.common.errors.RestconfError; -import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag; -import org.opendaylight.restconf.common.errors.RestconfError.ErrorType; +import org.opendaylight.yangtools.yang.common.ErrorTag; +import org.opendaylight.yangtools.yang.common.ErrorType; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.opendaylight.yangtools.yang.common.XMLNamespace; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.data.impl.schema.Builders; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder; +import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder; +import org.opendaylight.yangtools.yang.data.api.schema.builder.NormalizedNodeBuilder; +import org.opendaylight.yangtools.yang.data.impl.schema.SchemaAwareBuilders; +import org.opendaylight.yangtools.yang.model.api.ContainerLike; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; @@ -69,8 +68,6 @@ import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.RpcDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.api.SchemaPath; -import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils; import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; public class InvokeRpcMethodTest { @@ -97,8 +94,8 @@ public class InvokeRpcMethodTest { uriInfo = mock(UriInfo.class); final MultivaluedMap map = new MultivaluedHashMap<>(); - map.put("prettyPrint", Collections.singletonList("true")); - when(uriInfo.getQueryParameters(any(Boolean.class))).thenReturn(map); + map.put("prettyPrint", List.of("true")); + doReturn(map).when(uriInfo).getQueryParameters(any(Boolean.class)); } /** @@ -109,18 +106,14 @@ public class InvokeRpcMethodTest { @Test @Ignore public void invokeRpcMethodTest() { - try { - controllerContext.findModuleNameByNamespace(new URI("invoke:rpc:module")); - } catch (final URISyntaxException e) { - assertTrue("Uri wasn't created sucessfuly", false); - } + controllerContext.findModuleNameByNamespace(XMLNamespace.of("invoke:rpc:module")); final NormalizedNodeContext payload = prepareDomPayload(); final NormalizedNodeContext rpcResponse = restconfImpl.invokeRpc("invoke-rpc-module:rpc-test", payload, uriInfo); - assertTrue(rpcResponse != null); - assertTrue(rpcResponse.getData() == null); + assertNotNull(rpcResponse); + assertNull(rpcResponse.getData()); } @@ -129,63 +122,57 @@ public class InvokeRpcMethodTest { final Module rpcModule = schema.findModules("invoke-rpc-module").iterator().next(); assertNotNull(rpcModule); final QName rpcQName = QName.create(rpcModule.getQNameModule(), "rpc-test"); - final QName rpcInputQName = QName.create(rpcModule.getQNameModule(),"input"); - ContainerSchemaNode rpcInputSchemaNode = null; + ContainerLike rpcInputSchemaNode = null; for (final RpcDefinition rpc : rpcModule.getRpcs()) { if (rpcQName.isEqualWithoutRevision(rpc.getQName())) { - rpcInputSchemaNode = SchemaNodeUtils.getRpcDataSchema(rpc, rpcInputQName); + rpcInputSchemaNode = rpc.getInput(); break; } } assertNotNull(rpcInputSchemaNode); final DataContainerNodeBuilder container = - Builders.containerBuilder(rpcInputSchemaNode); + SchemaAwareBuilders.containerBuilder(rpcInputSchemaNode); final QName contQName = QName.create(rpcModule.getQNameModule(), "cont"); final DataSchemaNode contSchemaNode = rpcInputSchemaNode.getDataChildByName(contQName); assertTrue(contSchemaNode instanceof ContainerSchemaNode); final DataContainerNodeBuilder contNode = - Builders.containerBuilder((ContainerSchemaNode) contSchemaNode); + SchemaAwareBuilders.containerBuilder((ContainerSchemaNode) contSchemaNode); final QName lfQName = QName.create(rpcModule.getQNameModule(), "lf"); final DataSchemaNode lfSchemaNode = ((ContainerSchemaNode) contSchemaNode).getDataChildByName(lfQName); assertTrue(lfSchemaNode instanceof LeafSchemaNode); final LeafNode lfNode = - Builders.leafBuilder((LeafSchemaNode) lfSchemaNode).withValue("any value").build(); + SchemaAwareBuilders.leafBuilder((LeafSchemaNode) lfSchemaNode).withValue("any value").build(); contNode.withChild(lfNode); container.withChild(contNode.build()); return new NormalizedNodeContext( - new InstanceIdentifierContext<>(null, rpcInputSchemaNode, null, schema), container.build()); + new InstanceIdentifierContext(null, rpcInputSchemaNode, null, schema), container.build()); } @Test public void testInvokeRpcWithNoPayloadRpc_FailNoErrors() { final QName qname = QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)cancel-toast"); - final SchemaPath type = SchemaPath.create(true, qname); doReturn(immediateFailedFluentFuture(new DOMRpcImplementationNotAvailableException("testExeption"))) - .when(brokerFacade).invokeRpc(eq(type), isNull()); - - try { - this.restconfImpl.invokeRpc("toaster:cancel-toast", null, uriInfo); - fail("Expected an exception to be thrown."); - } catch (final RestconfDocumentedException e) { - verifyRestconfDocumentedException(e, 0, ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED, - Optional.absent(), Optional.absent()); - } + .when(brokerFacade).invokeRpc(eq(qname), any()); + + final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class, + () -> restconfImpl.invokeRpc("toaster:cancel-toast", null, uriInfo)); + verifyRestconfDocumentedException(ex, 0, ErrorType.APPLICATION, ErrorTag.OPERATION_NOT_SUPPORTED, + Optional.empty(), Optional.empty()); } void verifyRestconfDocumentedException(final RestconfDocumentedException restDocumentedException, final int index, final ErrorType expErrorType, final ErrorTag expErrorTag, final Optional expErrorMsg, final Optional expAppTag) { - RestconfError actual = null; - try { - actual = restDocumentedException.getErrors().get(index); - } catch (final ArrayIndexOutOfBoundsException ex) { - fail("RestconfError not found at index " + index); - } + + final List errors = restDocumentedException.getErrors(); + assertTrue("RestconfError not found at index " + index, errors.size() > index); + + RestconfError actual = errors.get(index); assertEquals("getErrorType", expErrorType, actual.getErrorType()); assertEquals("getErrorTag", expErrorTag, actual.getErrorTag()); @@ -208,32 +195,32 @@ public class InvokeRpcMethodTest { "app-tag", null, null)); final DOMRpcResult result = new DefaultDOMRpcResult(rpcErrors); - final SchemaPath path = SchemaPath.create(true, - QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)cancel-toast")); - doReturn(immediateFluentFuture(result)).when(brokerFacade).invokeRpc(eq(path), isNull()); - - try { - this.restconfImpl.invokeRpc("toaster:cancel-toast", null, uriInfo); - fail("Expected an exception to be thrown."); - } catch (final RestconfDocumentedException e) { - verifyRestconfDocumentedException(e, 0, ErrorType.TRANSPORT, ErrorTag.OPERATION_FAILED, Optional.of("foo"), - Optional.absent()); - verifyRestconfDocumentedException(e, 1, ErrorType.RPC, ErrorTag.IN_USE, Optional.of("bar"), - Optional.of("app-tag")); - } + final QName path = QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)cancel-toast"); + doReturn(immediateFluentFuture(result)).when(brokerFacade).invokeRpc(eq(path), any()); + + final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class, + () -> restconfImpl.invokeRpc("toaster:cancel-toast", null, uriInfo)); + + // We are performing pass-through here of error-tag, hence the tag remains as specified, but we want to make + // sure the HTTP status remains the same as + final ErrorTag bogus = new ErrorTag("bogusTag"); + verifyRestconfDocumentedException(ex, 0, ErrorType.TRANSPORT, bogus, Optional.of("foo"), Optional.empty()); + assertEquals(ErrorTags.statusOf(ErrorTag.OPERATION_FAILED), ErrorTags.statusOf(bogus)); + + verifyRestconfDocumentedException(ex, 1, ErrorType.RPC, ErrorTag.IN_USE, Optional.of("bar"), + Optional.of("app-tag")); } @Test public void testInvokeRpcWithNoPayload_Success() { - final NormalizedNode resultObj = null; + final NormalizedNode resultObj = null; final DOMRpcResult expResult = new DefaultDOMRpcResult(resultObj); final QName qname = QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)cancel-toast"); - final SchemaPath path = SchemaPath.create(true, qname); - doReturn(immediateFluentFuture(expResult)).when(brokerFacade).invokeRpc(eq(path), isNull()); + doReturn(immediateFluentFuture(expResult)).when(brokerFacade).invokeRpc(eq(qname), any()); - final NormalizedNodeContext output = this.restconfImpl.invokeRpc("toaster:cancel-toast", null, uriInfo); + final NormalizedNodeContext output = restconfImpl.invokeRpc("toaster:cancel-toast", null, uriInfo); assertNotNull(output); assertEquals(null, output.getData()); // additional validation in the fact that the restconfImpl does not @@ -242,70 +229,54 @@ public class InvokeRpcMethodTest { @Test public void testInvokeRpcWithEmptyOutput() { - final ContainerNode resultObj = Mockito.mock(ContainerNode.class); - Mockito.when(resultObj.getValue()).thenReturn(Collections.emptySet()); + final ContainerNode resultObj = mock(ContainerNode.class); + doReturn(Set.of()).when(resultObj).body(); + doCallRealMethod().when(resultObj).isEmpty(); final DOMRpcResult expResult = new DefaultDOMRpcResult(resultObj); final QName qname = QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)cancel-toast"); - final SchemaPath path = SchemaPath.create(true, qname); - doReturn(immediateFluentFuture(expResult)).when(brokerFacade).invokeRpc(eq(path), isNull()); + doReturn(immediateFluentFuture(expResult)).when(brokerFacade).invokeRpc(eq(qname), any()); - WebApplicationException exceptionToBeThrown = null; - try { - this.restconfImpl.invokeRpc("toaster:cancel-toast", null, uriInfo); - } catch (final WebApplicationException exception) { - exceptionToBeThrown = exception; - - } - Assert.assertNotNull("WebApplicationException with status code 204 is expected.", exceptionToBeThrown); - Assert.assertEquals(Response.Status.NO_CONTENT.getStatusCode(), exceptionToBeThrown.getResponse().getStatus()); + WebApplicationException exceptionToBeThrown = assertThrows(WebApplicationException.class, + () -> restconfImpl.invokeRpc("toaster:cancel-toast", null, uriInfo)); + assertEquals(Response.Status.NO_CONTENT.getStatusCode(), exceptionToBeThrown.getResponse().getStatus()); } @Test public void testInvokeRpcMethodWithBadMethodName() { - try { - this.restconfImpl.invokeRpc("toaster:bad-method", null, uriInfo); - fail("Expected an exception"); - } catch (final RestconfDocumentedException e) { - verifyRestconfDocumentedException(e, 0, ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT, - Optional.absent(), Optional.absent()); - } + final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class, + () -> restconfImpl.invokeRpc("toaster:bad-method", null, uriInfo)); + verifyRestconfDocumentedException(ex, 0, ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT, + Optional.empty(), Optional.empty()); } @Test @Ignore public void testInvokeRpcMethodWithInput() { final DOMRpcResult expResult = mock(DOMRpcResult.class); - final SchemaPath path = SchemaPath.create(true, - QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)make-toast")); + final QName path = QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)make-toast"); final Module rpcModule = schemaContext.findModules("toaster").iterator().next(); assertNotNull(rpcModule); final QName rpcQName = QName.create(rpcModule.getQNameModule(), "make-toast"); - final QName rpcInputQName = QName.create(rpcModule.getQNameModule(),"input"); RpcDefinition rpcDef = null; - ContainerSchemaNode rpcInputSchemaNode = null; for (final RpcDefinition rpc : rpcModule.getRpcs()) { if (rpcQName.isEqualWithoutRevision(rpc.getQName())) { - rpcInputSchemaNode = SchemaNodeUtils.getRpcDataSchema(rpc, rpcInputQName); rpcDef = rpc; break; } } assertNotNull(rpcDef); - assertNotNull(rpcInputSchemaNode); - final DataContainerNodeBuilder containerBuilder = - Builders.containerBuilder(rpcInputSchemaNode); - final NormalizedNodeContext payload = - new NormalizedNodeContext(new InstanceIdentifierContext<>(null, rpcInputSchemaNode, - null, schemaContext), containerBuilder.build()); + final NormalizedNodeContext payload = new NormalizedNodeContext( + InstanceIdentifierContext.ofLocalRpcInput(schemaContext, rpcDef), + SchemaAwareBuilders.containerBuilder(rpcDef.getInput()).build()); doReturn(immediateFluentFuture(expResult)).when(brokerFacade).invokeRpc(eq(path), any(NormalizedNode.class)); - final NormalizedNodeContext output = this.restconfImpl.invokeRpc("toaster:make-toast", payload, uriInfo); + final NormalizedNodeContext output = restconfImpl.invokeRpc("toaster:make-toast", payload, uriInfo); assertNotNull(output); assertEquals(null, output.getData()); // additional validation in the fact that the restconfImpl does not @@ -314,13 +285,10 @@ public class InvokeRpcMethodTest { @Test public void testThrowExceptionWhenSlashInModuleName() { - try { - this.restconfImpl.invokeRpc("toaster/slash", null, uriInfo); - fail("Expected an exception."); - } catch (final RestconfDocumentedException e) { - verifyRestconfDocumentedException(e, 0, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, - Optional.absent(), Optional.absent()); - } + final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class, + () -> restconfImpl.invokeRpc("toaster/slash", null, uriInfo)); + verifyRestconfDocumentedException(ex, 0, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, + Optional.empty(), Optional.empty()); } @Test @@ -332,10 +300,10 @@ public class InvokeRpcMethodTest { final QName rpcOutputQName = QName.create(rpcModule.getQNameModule(),"output"); RpcDefinition rpcDef = null; - ContainerSchemaNode rpcOutputSchemaNode = null; + ContainerLike rpcOutputSchemaNode = null; for (final RpcDefinition rpc : rpcModule.getRpcs()) { if (rpcQName.isEqualWithoutRevision(rpc.getQName())) { - rpcOutputSchemaNode = SchemaNodeUtils.getRpcDataSchema(rpc, rpcOutputQName); + rpcOutputSchemaNode = rpc.getOutput(); rpcDef = rpc; break; } @@ -343,21 +311,21 @@ public class InvokeRpcMethodTest { assertNotNull(rpcDef); assertNotNull(rpcOutputSchemaNode); final DataContainerNodeBuilder containerBuilder = - Builders.containerBuilder(rpcOutputSchemaNode); + SchemaAwareBuilders.containerBuilder(rpcOutputSchemaNode); final DataSchemaNode leafSchema = rpcOutputSchemaNode .getDataChildByName(QName.create(rpcModule.getQNameModule(), "textOut")); assertTrue(leafSchema instanceof LeafSchemaNode); final NormalizedNodeBuilder> leafBuilder = - Builders.leafBuilder((LeafSchemaNode) leafSchema); + SchemaAwareBuilders.leafBuilder((LeafSchemaNode) leafSchema); leafBuilder.withValue("brm"); containerBuilder.withChild(leafBuilder.build()); final ContainerNode container = containerBuilder.build(); final DOMRpcResult result = new DefaultDOMRpcResult(container); - doReturn(immediateFluentFuture(result)).when(brokerFacade).invokeRpc(eq(rpcDef.getPath()), isNull()); + doReturn(immediateFluentFuture(result)).when(brokerFacade).invokeRpc(eq(rpcDef.getQName()), any()); - final NormalizedNodeContext output = this.restconfImpl.invokeRpc("toaster:testOutput", null, uriInfo); + final NormalizedNodeContext output = restconfImpl.invokeRpc("toaster:testOutput", null, uriInfo); assertNotNull(output); assertNotNull(output.getData()); assertSame(container, output.getData()); @@ -372,7 +340,7 @@ public class InvokeRpcMethodTest { * invoked. */ @Test - @Ignore // FIXME find how to use mockito for it public void testMountedRpcCallNoPayload_Success() throws Exception { + // FIXME find how to use mockito for it } }