BUG-3861 Detect RPC errors when committing netconf transaction 74/23674/1
authorMaros Marsalek <mmarsale@cisco.com>
Thu, 25 Jun 2015 12:45:23 +0000 (14:45 +0200)
committerTony Tkacik <ttkacik@cisco.com>
Thu, 2 Jul 2015 11:36:29 +0000 (11:36 +0000)
Transaction from netconf southbound would return a succeeded future in case
an rpc-error was returned as response to commit rpc.

Change-Id: I7ec538f09c5d1b9ac5e18d69ccc6d2c3939d01c3
Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
(cherry picked from commit e9b7db6d1bbbf4489bf35071d9ec2b0f96499938)

opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteCandidateTx.java
opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceWriteOnlyTxTest.java

index bba3453aa93eb80155b58672b3341cd875ebb374..0f2b00280a162b0cddf0435b04a7df4d9ec566ac 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.controller.sal.connect.netconf.sal.tx;
 
 import com.google.common.base.Function;
 import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -130,6 +131,7 @@ public class WriteCandidateTx extends AbstractWriteTx {
         final ListenableFuture<Void> commitFutureAsVoid = Futures.transform(commit(), new Function<RpcResult<TransactionStatus>, Void>() {
             @Override
             public Void apply(final RpcResult<TransactionStatus> input) {
+                Preconditions.checkArgument(input.isSuccessful() && input.getErrors().isEmpty(), "Submit failed with errors: %s", input.getErrors());
                 return null;
             }
         });
index 3a378ed427fb6def7846eebd84aefe5e529afd8e..d16e364ff8a7a614b6ffbf5d2fdd16a40b8a82ce 100644 (file)
@@ -30,6 +30,8 @@ import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
 import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
 import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@@ -91,6 +93,27 @@ public class NetconfDeviceWriteOnlyTxTest {
         fail("Submit should fail");
     }
 
+    @Test
+    public void testFailedCommit() throws Exception {
+        final CheckedFuture<DefaultDOMRpcResult, Exception> rpcErrorFuture =
+                Futures.immediateCheckedFuture(new DefaultDOMRpcResult(RpcResultBuilder.newError(RpcError.ErrorType.APPLICATION, "a", "m")));
+
+        doReturn(Futures.immediateCheckedFuture(new DefaultDOMRpcResult(((NormalizedNode<?, ?>) null))))
+        .doReturn(rpcErrorFuture).when(rpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
+
+        final WriteCandidateTx tx = new WriteCandidateTx(id, new NetconfBaseOps(rpc, mock(SchemaContext.class)),
+                false, 60000L);
+
+        final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = tx.submit();
+        try {
+            submitFuture.checkedGet();
+        } catch (final TransactionCommitFailedException e) {
+            return;
+        }
+
+        fail("Submit should fail");
+    }
+
     @Test
     public void testDiscardChangesNotSentWithoutCandidate() {
         doReturn(Futures.immediateCheckedFuture(new DefaultDOMRpcResult(((NormalizedNode<?, ?>) null))))