From: Maros Marsalek Date: Thu, 25 Jun 2015 12:45:23 +0000 (+0200) Subject: BUG-3861 Detect RPC errors when committing netconf transaction X-Git-Tag: release/beryllium~438 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=eab5d830cad56a1bb3c796e0aae8f1bb1974499a BUG-3861 Detect RPC errors when committing netconf transaction 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 (cherry picked from commit e9b7db6d1bbbf4489bf35071d9ec2b0f96499938) --- diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteCandidateTx.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteCandidateTx.java index bba3453aa9..0f2b00280a 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteCandidateTx.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/WriteCandidateTx.java @@ -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 commitFutureAsVoid = Futures.transform(commit(), new Function, Void>() { @Override public Void apply(final RpcResult input) { + Preconditions.checkArgument(input.isSuccessful() && input.getErrors().isEmpty(), "Submit failed with errors: %s", input.getErrors()); return null; } }); diff --git a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceWriteOnlyTxTest.java b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceWriteOnlyTxTest.java index 3a378ed427..d16e364ff8 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceWriteOnlyTxTest.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/sal/tx/NetconfDeviceWriteOnlyTxTest.java @@ -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 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 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))))