From: Jozef Gloncak Date: Tue, 22 Jul 2014 07:06:11 +0000 (+0200) Subject: BUG 1379 - rpcs behind yang-ext:mount aren't always executed X-Git-Tag: release/helium~460 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=987da6535d262937135d14dbcad3d08e10767480 BUG 1379 - rpcs behind yang-ext:mount aren't always executed new corrected behavior: If rpc is from device behing yang-ext:mount and it doesn't exist in controller then it is ALSO executed. Change-Id: Ieebf2522b39cd42a8da57b05cf49e528c924f7ba Signed-off-by: Jozef Gloncak --- diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java index bb7547d330..4e807b4e23 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java @@ -490,7 +490,13 @@ public class RestconfImpl implements RestconfService { } final String identifierDecoded = controllerContext.urlPathArgDecode(identifierEncoded); - RpcDefinition rpc = controllerContext.getRpcDefinition(identifierDecoded); + + RpcDefinition rpc = null; + if (mountPoint == null) { + rpc = controllerContext.getRpcDefinition(identifierDecoded); + } else { + rpc = findRpc(mountPoint.getSchemaContext(), identifierDecoded); + } if (rpc == null) { throw new RestconfDocumentedException("RPC does not exist.", ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT); @@ -504,6 +510,25 @@ public class RestconfImpl implements RestconfService { } + private RpcDefinition findRpc(final SchemaContext schemaContext, final String identifierDecoded) { + final String[] splittedIdentifier = identifierDecoded.split(":"); + if (splittedIdentifier.length != 2) { + throw new RestconfDocumentedException(identifierDecoded + + " couldn't be splitted to 2 parts (module:rpc name)", ErrorType.APPLICATION, + ErrorTag.INVALID_VALUE); + } + for (Module module : schemaContext.getModules()) { + if (module.getName().equals(splittedIdentifier[0])) { + for (RpcDefinition rpcDefinition : module.getRpcs()) { + if (rpcDefinition.getQName().getLocalName().equals(splittedIdentifier[1])) { + return rpcDefinition; + } + } + } + } + return null; + } + private StructuredData callRpc(final RpcExecutor rpcExecutor, final CompositeNode payload, boolean prettyPrint) { if (rpcExecutor == null) { throw new RestconfDocumentedException("RPC does not exist.", ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java index 313b766ed3..2adf9b5530 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java @@ -36,7 +36,6 @@ import javax.ws.rs.core.UriInfo; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; - import org.opendaylight.controller.sal.core.api.mount.MountInstance; import org.opendaylight.controller.sal.restconf.impl.BrokerFacade; import org.opendaylight.controller.sal.restconf.impl.ControllerContext; @@ -298,6 +297,14 @@ public class InvokeRpcMethodTest { assertNotNull(output.getSchema()); } + /** + * + * Tests calling of RestConfImpl method invokeRpc. In the method there is searched rpc in remote schema context. + * This rpc is then executed. + * + * I wasn't able to simulate calling of rpc on remote device therefore this testing method raise method when rpc is + * invoked. + */ @Test public void testMountedRpcCallNoPayload_Success() throws Exception { RpcResult rpcResult = RpcResultBuilder.success().build(); @@ -313,21 +320,32 @@ public class InvokeRpcMethodTest { MountInstance mockMountPoint = mock(MountInstance.class); when(mockMountPoint.rpc(eq(cancelToastQName), any(CompositeNode.class))).thenReturn(mockListener); + when(mockMountPoint.getSchemaContext()).thenReturn(TestUtils.loadSchemaContext("/invoke-rpc")); + InstanceIdWithSchemaNode mockedInstanceId = mock(InstanceIdWithSchemaNode.class); when(mockedInstanceId.getMountPoint()).thenReturn(mockMountPoint); ControllerContext mockedContext = mock(ControllerContext.class); - String cancelToastStr = "toaster:cancel-toast"; - when(mockedContext.urlPathArgDecode(cancelToastStr)).thenReturn(cancelToastStr); - when(mockedContext.getRpcDefinition(cancelToastStr)).thenReturn(mockRpc); + String rpcNoop = "invoke-rpc-module:rpc-noop"; + when(mockedContext.urlPathArgDecode(rpcNoop)).thenReturn(rpcNoop); + when(mockedContext.getRpcDefinition(rpcNoop)).thenReturn(mockRpc); when( - mockedContext.toMountPointIdentifier("opendaylight-inventory:nodes/node/" - + "REMOTE_HOST/yang-ext:mount/toaster:cancel-toast")).thenReturn(mockedInstanceId); + mockedContext.toMountPointIdentifier(eq("opendaylight-inventory:nodes/node/" + + "REMOTE_HOST/yang-ext:mount/invoke-rpc-module:rpc-noop"))).thenReturn(mockedInstanceId); restconfImpl.setControllerContext(mockedContext); - StructuredData output = restconfImpl.invokeRpc( - "opendaylight-inventory:nodes/node/REMOTE_HOST/yang-ext:mount/toaster:cancel-toast", "", uriInfo); - assertEquals(null, output); + try { + restconfImpl.invokeRpc( + "opendaylight-inventory:nodes/node/REMOTE_HOST/yang-ext:mount/invoke-rpc-module:rpc-noop", "", + uriInfo); + fail("RestconfDocumentedException wasn't raised"); + } catch (RestconfDocumentedException e) { + List errors = e.getErrors(); + assertNotNull(errors); + assertEquals(1, errors.size()); + assertEquals(ErrorType.APPLICATION, errors.iterator().next().getErrorType()); + assertEquals(ErrorTag.OPERATION_FAILED, errors.iterator().next().getErrorTag()); + } // additional validation in the fact that the restconfImpl does not // throw an exception. diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/invoke-rpc/invoke-rpc-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/invoke-rpc/invoke-rpc-module.yang index ba06645354..208c2164d5 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/resources/invoke-rpc/invoke-rpc-module.yang +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/invoke-rpc/invoke-rpc-module.yang @@ -16,5 +16,8 @@ module invoke-rpc-module { } } } - + + rpc rpc-noop { + } + } \ No newline at end of file