BUG 1379 - rpcs behind yang-ext:mount aren't always executed 18/9218/1
authorJozef Gloncak <jgloncak@cisco.com>
Tue, 22 Jul 2014 07:06:11 +0000 (09:06 +0200)
committerJozef Gloncak <jgloncak@cisco.com>
Tue, 22 Jul 2014 07:13:02 +0000 (09:13 +0200)
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 <jgloncak@cisco.com>
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java
opendaylight/md-sal/sal-rest-connector/src/test/resources/invoke-rpc/invoke-rpc-module.yang

index bb7547d..4e807b4 100644 (file)
@@ -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);
index 313b766..2adf9b5 100644 (file)
@@ -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<CompositeNode> rpcResult = RpcResultBuilder.<CompositeNode>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<RestconfError> 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.

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.