BUG-5280: unwrap RuntimeRequestExceptions 20/55720/2
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 19 Apr 2017 13:59:22 +0000 (15:59 +0200)
committerTom Pantelis <tompantelis@gmail.com>
Fri, 21 Apr 2017 13:28:02 +0000 (13:28 +0000)
This patch adds the primitive to unwrap RuntimeRequestExceptions,
so the underlying cause is propagated.

Change-Id: I77771867a48eb5f63d35a6402aca6ad0bc5b12e3
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/concepts/RequestException.java
opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/concepts/RuntimeRequestException.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/AbstractProxyTransaction.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/AbstractShardBackendResolver.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/actors/dds/ClientTransactionCommitCohortTest.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/actors/dds/ModuleShardBackendResolverTest.java

index 5f525b0a9beb8e60174367f4798121d89a8200a6..4f2a0585da76c9afe04b0a5c744faf4c22138eba 100644 (file)
@@ -29,4 +29,14 @@ public abstract class RequestException extends Exception {
     }
 
     public abstract boolean isRetriable();
+
+    /**
+     * Unwraps the underlying failure. This method is overridden only in {@link RuntimeRequestException}.
+     *
+     * @return Underlying cause of the failure if exception is a {@link RuntimeRequestException}, or the exception
+     *         itself.
+     */
+    public Throwable unwrap() {
+        return this;
+    }
 }
index 2cf1828da4049180e701c864ad8d233929645384..a52396fd5d5f6a00ab78085bd457f8aca3a3246d 100644 (file)
@@ -21,13 +21,17 @@ public final class RuntimeRequestException extends RequestException {
     private static final long serialVersionUID = 1L;
 
     public RuntimeRequestException(final String message, final Throwable cause) {
-        super(message, cause);
+        super(message, Preconditions.checkNotNull(cause));
         Preconditions.checkArgument(!Strings.isNullOrEmpty(message), "Exception message is mandatory");
-        Preconditions.checkNotNull(cause);
     }
 
     @Override
     public boolean isRetriable() {
         return false;
     }
+
+    @Override
+    public Throwable unwrap() {
+        return getCause();
+    }
 }
index 27f9b47cd9211386c9d43bb080aaea4b78cc3c0d..86d7f237411f0068fc4649371d85245c993c8ddf 100644 (file)
@@ -316,7 +316,7 @@ abstract class AbstractProxyTransaction implements Identifiable<TransactionIdent
             if (t instanceof TransactionAbortSuccess) {
                 ret.voteYes();
             } else if (t instanceof RequestFailure) {
-                ret.voteNo(((RequestFailure<?, ?>) t).getCause());
+                ret.voteNo(((RequestFailure<?, ?>) t).getCause().unwrap());
             } else {
                 ret.voteNo(new IllegalStateException("Unhandled response " + t.getClass()));
             }
@@ -349,7 +349,7 @@ abstract class AbstractProxyTransaction implements Identifiable<TransactionIdent
                     if (t instanceof TransactionCommitSuccess) {
                         ret.set(Boolean.TRUE);
                     } else if (t instanceof RequestFailure) {
-                        ret.setException(((RequestFailure<?, ?>) t).getCause());
+                        ret.setException(((RequestFailure<?, ?>) t).getCause().unwrap());
                     } else {
                         ret.setException(new IllegalStateException("Unhandled response " + t.getClass()));
                     }
@@ -380,7 +380,7 @@ abstract class AbstractProxyTransaction implements Identifiable<TransactionIdent
                     if (t instanceof TransactionCanCommitSuccess) {
                         ret.voteYes();
                     } else if (t instanceof RequestFailure) {
-                        ret.voteNo(((RequestFailure<?, ?>) t).getCause());
+                        ret.voteNo(((RequestFailure<?, ?>) t).getCause().unwrap());
                     } else {
                         ret.voteNo(new IllegalStateException("Unhandled response " + t.getClass()));
                     }
@@ -411,7 +411,7 @@ abstract class AbstractProxyTransaction implements Identifiable<TransactionIdent
             if (t instanceof TransactionPreCommitSuccess) {
                 ret.voteYes();
             } else if (t instanceof RequestFailure) {
-                ret.voteNo(((RequestFailure<?, ?>) t).getCause());
+                ret.voteNo(((RequestFailure<?, ?>) t).getCause().unwrap());
             } else {
                 ret.voteNo(new IllegalStateException("Unhandled response " + t.getClass()));
             }
@@ -444,7 +444,7 @@ abstract class AbstractProxyTransaction implements Identifiable<TransactionIdent
             if (t instanceof TransactionCommitSuccess) {
                 ret.voteYes();
             } else if (t instanceof RequestFailure) {
-                ret.voteNo(((RequestFailure<?, ?>) t).getCause());
+                ret.voteNo(((RequestFailure<?, ?>) t).getCause().unwrap());
             } else {
                 ret.voteNo(new IllegalStateException("Unhandled response " + t.getClass()));
             }
index 51f96e18fde4e2f0ea66d2ca41d3f72d9ea58755..93cf7931e56139523146e5c36932a2eba626328e 100644 (file)
@@ -24,7 +24,6 @@ import org.opendaylight.controller.cluster.access.client.BackendInfoResolver;
 import org.opendaylight.controller.cluster.access.commands.ConnectClientRequest;
 import org.opendaylight.controller.cluster.access.commands.ConnectClientSuccess;
 import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier;
-import org.opendaylight.controller.cluster.access.concepts.RequestException;
 import org.opendaylight.controller.cluster.access.concepts.RequestFailure;
 import org.opendaylight.controller.cluster.common.actor.ExplicitAsk;
 import org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException;
@@ -137,7 +136,7 @@ abstract class AbstractShardBackendResolver extends BackendInfoResolver<ShardBac
                     return;
                 }
                 if (response instanceof RequestFailure) {
-                    final RequestException cause = ((RequestFailure<?, ?>) response).getCause();
+                    final Throwable cause = ((RequestFailure<?, ?>) response).getCause().unwrap();
                     LOG.debug("Connect attempt to {} failed to process", shardName, cause);
                     future.completeExceptionally(cause);
                     return;
index f9eb6ed6aff1b260e53341a5b454a6a53466c943..6fde068c6e47e9b027046bf6406f9319b8d84a85 100644 (file)
@@ -228,12 +228,13 @@ public class ClientTransactionCommitCohortTest {
         //reply fail to last transaction
         final TransactionTester<RemoteProxyTransaction> last = transactions.get(transactions.size() - 1);
         expectFunction.accept(last);
-        final RuntimeRequestException cause = new RuntimeRequestException("fail", new RuntimeException());
+        final RuntimeException e = new RuntimeException();
+        final RuntimeRequestException cause = new RuntimeRequestException("fail", e);
         last.replyFailure(cause);
         //check future fail
         final ExecutionException exception =
                 assertOperationThrowsException(() -> getWithTimeout(canCommit), ExecutionException.class);
-        Assert.assertEquals(cause, exception.getCause());
+        Assert.assertEquals(e, exception.getCause());
     }
 
 }
index d1c322f86aad61c9642945cd7a3d78987828b80f..f86f8063692ea34c49a27da17ceb40cf861ef5e8 100644 (file)
@@ -117,8 +117,7 @@ public class ModuleShardBackendResolverTest {
         final ExecutionException caught =
                 TestUtils.assertOperationThrowsException(() -> TestUtils.getWithTimeout(stage.toCompletableFuture()),
                         ExecutionException.class);
-        Assert.assertNotNull(caught.getCause());
-        Assert.assertEquals(cause, caught.getCause().getCause());
+        Assert.assertEquals(cause, caught.getCause());
     }
 
     @Test