Skip to content
This repository has been archived by the owner on Nov 14, 2024. It is now read-only.

Cherrypick/qos exception mapping #2715

Merged
merged 12 commits into from
Nov 20, 2017
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,15 @@
import com.palantir.atlasdb.logging.LoggingArgs;
import com.palantir.atlasdb.qos.FakeQosClient;
import com.palantir.atlasdb.qos.QosClient;
import com.palantir.atlasdb.qos.ratelimit.QosAwareThrowables;
import com.palantir.atlasdb.qos.ratelimit.RateLimitExceededException;
import com.palantir.atlasdb.util.AnnotatedCallable;
import com.palantir.atlasdb.util.AnnotationType;
import com.palantir.atlasdb.util.AtlasDbMetrics;
import com.palantir.common.annotation.Idempotent;
import com.palantir.common.base.ClosableIterator;
import com.palantir.common.base.ClosableIterators;
import com.palantir.common.base.FunctionCheckedException;
import com.palantir.common.base.Throwables;
import com.palantir.common.exception.PalantirRuntimeException;
import com.palantir.logsafe.SafeArg;
import com.palantir.logsafe.UnsafeArg;
Expand Down Expand Up @@ -497,7 +498,7 @@ public String toString() {
}
return ImmutableMap.copyOf(result);
} catch (Exception e) {
throw Throwables.unwrapAndThrowAtlasDbDependencyException(e);
throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
}
}

Expand Down Expand Up @@ -567,7 +568,7 @@ public Map<Cell, Value> get(TableReference tableRef, Map<Cell, Long> timestampBy
}
return builder.build();
} catch (Exception e) {
throw Throwables.unwrapAndThrowAtlasDbDependencyException(e);
throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
}
}

Expand Down Expand Up @@ -795,7 +796,7 @@ private Map<byte[], RowColumnRangeIterator> getRowsColumnRangeIteratorForSingleH
}
return ret;
} catch (Exception e) {
throw Throwables.unwrapAndThrowAtlasDbDependencyException(e);
throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
}
}

Expand Down Expand Up @@ -835,7 +836,7 @@ public String toString() {
}
});
} catch (Exception e) {
throw Throwables.unwrapAndThrowAtlasDbDependencyException(e);
throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
}
}

Expand Down Expand Up @@ -975,7 +976,7 @@ public void put(final TableReference tableRef, final Map<Cell, byte[]> values, f
try {
putInternal("put", tableRef, KeyValueServices.toConstantTimestampValues(values.entrySet(), timestamp));
} catch (Exception e) {
throw Throwables.unwrapAndThrowAtlasDbDependencyException(e);
throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
}
}

Expand All @@ -995,7 +996,7 @@ public void putWithTimestamps(TableReference tableRef, Multimap<Cell, Value> val
try {
putInternal("putWithTimestamps", tableRef, values.entries());
} catch (Exception e) {
throw Throwables.unwrapAndThrowAtlasDbDependencyException(e);
throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
}
}

Expand Down Expand Up @@ -1284,7 +1285,7 @@ public void truncateTables(final Set<TableReference> tablesToTruncate) {
throw new InsufficientConsistencyException("Truncating tables requires all Cassandra nodes"
+ " to be up and available.");
} catch (TException e) {
throw Throwables.unwrapAndThrowAtlasDbDependencyException(e);
throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
}
}
}
Expand Down Expand Up @@ -1416,7 +1417,7 @@ public String toString() {
throw new InsufficientConsistencyException("Deleting requires all Cassandra nodes to be up and available.",
e);
} catch (Exception e) {
throw Throwables.unwrapAndThrowAtlasDbDependencyException(e);
throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
}
}

Expand Down Expand Up @@ -1635,7 +1636,7 @@ private void dropTablesInternal(final Set<TableReference> tablesToDrop) {
throw new InsufficientConsistencyException(
"Dropping tables requires all Cassandra nodes to be up and available.", e);
} catch (Exception e) {
throw Throwables.unwrapAndThrowAtlasDbDependencyException(e);
throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
}
}

Expand Down Expand Up @@ -1761,7 +1762,7 @@ private Map<TableReference, byte[]> filterOutExistingTables(
}
}
} catch (Exception e) {
throw Throwables.unwrapAndThrowAtlasDbDependencyException(e);
throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
}

return filteredTables;
Expand All @@ -1782,7 +1783,8 @@ private void createTablesInternal(final Map<TableReference, byte[]> tableNamesTo
} catch (TException thriftException) {
if (thriftException.getMessage() != null
&& !thriftException.getMessage().contains("already existing table")) {
throw Throwables.unwrapAndThrowAtlasDbDependencyException(thriftException);
throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(
thriftException);
}
}
}
Expand Down Expand Up @@ -2024,7 +2026,7 @@ private void putMetadataAndMaybeAlterTables(
return null;
});
} catch (Exception e) {
throw Throwables.unwrapAndThrowAtlasDbDependencyException(e);
throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
}
}

Expand Down Expand Up @@ -2089,7 +2091,7 @@ public void addGarbageCollectionSentinelValues(TableReference tableRef, Iterable
putInternal("addGarbageCollectionSentinelValues",
tableRef, Iterables.transform(cells, cell -> Maps.immutableEntry(cell, value)));
} catch (Exception e) {
throw Throwables.unwrapAndThrowAtlasDbDependencyException(e);
throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
}
}

Expand Down Expand Up @@ -2146,7 +2148,7 @@ public void putUnlessExists(final TableReference tableRef, final Map<Cell, byte[
return null;
});
} catch (Exception e) {
throw Throwables.unwrapAndThrowAtlasDbDependencyException(e);
throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
}
}

Expand Down Expand Up @@ -2182,7 +2184,7 @@ public void checkAndSet(final CheckAndSetRequest request) throws CheckAndSetExce
} catch (CheckAndSetException e) {
throw e;
} catch (Exception e) {
throw Throwables.unwrapAndThrowAtlasDbDependencyException(e);
throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
}
}

Expand Down Expand Up @@ -2470,8 +2472,11 @@ private <V> List<V> runAllTasksCancelOnFailure(List<Callable<V>> tasks) {
try {
//Callable<Void> returns null, so can't use immutable list
return Collections.singletonList(tasks.get(0).call());
} catch (RateLimitExceededException e) {
// Prioritise over
throw e;
} catch (Exception e) {
throw Throwables.unwrapAndThrowAtlasDbDependencyException(e);
throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
}
}

Expand All @@ -2486,7 +2491,7 @@ private <V> List<V> runAllTasksCancelOnFailure(List<Callable<V>> tasks) {
}
return results;
} catch (Exception e) {
throw Throwables.unwrapAndThrowAtlasDbDependencyException(e);
throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
} finally {
for (Future<V> future : futures) {
future.cancel(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
import com.palantir.atlasdb.keyvalue.cassandra.CassandraClient;
import com.palantir.atlasdb.keyvalue.cassandra.CassandraClientPool;
import com.palantir.atlasdb.keyvalue.cassandra.TracingQueryRunner;
import com.palantir.atlasdb.qos.ratelimit.QosAwareThrowables;
import com.palantir.common.base.FunctionCheckedException;
import com.palantir.common.base.Throwables;

public class RowGetter {
private CassandraClientPool clientPool;
Expand Down Expand Up @@ -69,7 +69,7 @@ public List<KeySlice> apply(CassandraClient client) throws Exception {
throw new InsufficientConsistencyException("get_range_slices requires " + consistency
+ " Cassandra nodes to be up and available.", e);
} catch (Exception e) {
throw Throwables.unwrapAndThrowAtlasDbDependencyException(e);
throw QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(e);
}
}

Expand Down
1 change: 1 addition & 0 deletions atlasdb-cli-distribution/versions.lock
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@
"transitive": [
"com.palantir.atlasdb:atlasdb-api",
"com.palantir.atlasdb:atlasdb-client",
"com.palantir.atlasdb:atlasdb-impl-shared",
"com.palantir.atlasdb:qos-service-impl"
]
},
Expand Down
2 changes: 2 additions & 0 deletions atlasdb-cli/versions.lock
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@
"transitive": [
"com.palantir.atlasdb:atlasdb-api",
"com.palantir.atlasdb:atlasdb-client",
"com.palantir.atlasdb:atlasdb-impl-shared",
"com.palantir.atlasdb:qos-service-impl"
]
},
Expand Down Expand Up @@ -1473,6 +1474,7 @@
"transitive": [
"com.palantir.atlasdb:atlasdb-api",
"com.palantir.atlasdb:atlasdb-client",
"com.palantir.atlasdb:atlasdb-impl-shared",
"com.palantir.atlasdb:qos-service-impl"
]
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2017 Palantir Technologies, Inc. All rights reserved.
*
* Licensed under the BSD-3 License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.palantir.atlasdb.qos.ratelimit;

import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.ExecutionException;

import com.palantir.common.base.Throwables;

public final class QosAwareThrowables {
private QosAwareThrowables() {
// no
}

/**
* If the provided Throwable is
* a) an ExecutionException or InvocationTargetException, then apply this method on the cause;
* b) a RateLimitExceededException or an AtlasDbDependencyException, then rethrow it;
* c) none of the above, then wrap it in an AtlasDbDependencyException and throw that.
*/
public static RuntimeException unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(Throwable ex) {
if (ex instanceof ExecutionException || ex instanceof InvocationTargetException) {
// Needs to be this way in case you have ITE(RLE) or variants of that.
throw unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(ex.getCause());
} else if (ex instanceof RateLimitExceededException) {
throw (RateLimitExceededException) ex;
}
throw Throwables.unwrapAndThrowAtlasDbDependencyException(ex);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright 2017 Palantir Technologies, Inc. All rights reserved.
*
* Licensed under the BSD-3 License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.palantir.atlasdb.qos.ratelimit;

import static org.assertj.core.api.Assertions.assertThatThrownBy;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.ExecutionException;

import org.junit.Test;

import com.palantir.common.exception.AtlasDbDependencyException;

public class QosAwareThrowablesTest {
private static final Exception RATE_LIMIT_EXCEEDED_EXCEPTION =
new RateLimitExceededException("Stop!");
private static final Exception ATLASDB_DEPENDENCY_EXCEPTION =
new AtlasDbDependencyException("The TimeLock is dead, long live the TimeLock");

@Test
public void unwrapAndThrowRateLimitExceededOrAtlasDbDependencyExceptionCanThrowRateLimitExceededException() {
assertThatThrownBy(() -> QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(
RATE_LIMIT_EXCEEDED_EXCEPTION)).isEqualTo(RATE_LIMIT_EXCEEDED_EXCEPTION);
}

@Test
public void unwrapAndThrowRateLimitExceededOrAtlasDbDependencyExceptionCanThrowAtlasDbDependencyException() {
assertThatThrownBy(() -> QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(
ATLASDB_DEPENDENCY_EXCEPTION)).isEqualTo(ATLASDB_DEPENDENCY_EXCEPTION);
}

@Test
public void unwrapAndThrowRateLimitExceededOrAtlasDbDependencyExceptionThrowsWrappedRateLimitExceededExceptions() {
assertThatThrownBy(() -> QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(
new ExecutionException(RATE_LIMIT_EXCEEDED_EXCEPTION))).isEqualTo(RATE_LIMIT_EXCEEDED_EXCEPTION);
assertThatThrownBy(() -> QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(
new InvocationTargetException(RATE_LIMIT_EXCEEDED_EXCEPTION))).isEqualTo(RATE_LIMIT_EXCEEDED_EXCEPTION);
}

@Test
public void unwrapAndThrowRateLimitExceededOrAtlasDbDependencyExceptionThrowsWrappedAtlasDbDependencyExceptions() {
assertThatThrownBy(() -> QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(
new ExecutionException(ATLASDB_DEPENDENCY_EXCEPTION))).isEqualTo(ATLASDB_DEPENDENCY_EXCEPTION);
assertThatThrownBy(() -> QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(
new InvocationTargetException(ATLASDB_DEPENDENCY_EXCEPTION))).isEqualTo(ATLASDB_DEPENDENCY_EXCEPTION);
}

@Test
public void unwrapAndThrowRateLimitExceededOrAtlasDbDependencyExceptionWrapsRuntimeExceptions() {
assertThatThrownBy(() -> QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(
new RuntimeException("runtimeException"))).isInstanceOf(AtlasDbDependencyException.class);
}

@Test
public void unwrapAndThrowRateLimitExceededOrAtlasDbDependencyExceptionWrapsCheckedExceptions() {
assertThatThrownBy(() -> QosAwareThrowables.unwrapAndThrowRateLimitExceededOrAtlasDbDependencyException(
new IOException("ioException"))).isInstanceOf(AtlasDbDependencyException.class);
}
}
11 changes: 6 additions & 5 deletions atlasdb-commons/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ apply from: "../gradle/publish-jars.gradle"
apply from: "../gradle/shared.gradle"

dependencies {
compile group: 'com.google.code.findbugs', name: 'jsr305'
compile group: 'com.google.guava', name: 'guava'
compile group: 'org.slf4j', name: 'slf4j-api'
compile project(":commons-executors")
compile group: 'javax.ws.rs', name: 'javax.ws.rs-api'

compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations'
compile group: 'com.google.code.findbugs', name: 'jsr305'
compile group: 'com.google.guava', name: 'guava'
compile group: 'com.palantir.safe-logging', name: 'safe-logging'
compile group: 'io.dropwizard.metrics', name: 'metrics-core'
compile group: 'javax.ws.rs', name: 'javax.ws.rs-api'
compile group: 'net.jpountz.lz4', name: 'lz4'
compile group: 'com.palantir.safe-logging', name: 'safe-logging'
compile group: 'org.slf4j', name: 'slf4j-api'

testCompile group: 'junit', name: 'junit'
testCompile group: 'org.assertj', name: 'assertj-core'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,13 @@
import org.junit.Test;

public class ThrowablesTest extends Assert {

@Before
public void setUp() throws Exception {
NoUsefulConstructorException.noUsefulConstructorCalled = false;
}

@Test
public void testRewrap() {

try {
throwTwoArgConstructorException();
fail("Should not get here");
Expand Down Expand Up @@ -61,9 +59,9 @@ public void testRewrap() {
int sizeAfter = e.getStackTrace().length;
assertTrue(sizeAfter + " should be > " + sizeBefore, sizeAfter > sizeBefore);
}

}


// only has a (string, throwable) constructor
public void throwTwoArgConstructorException() throws TwoArgConstructorException {
throw new TwoArgConstructorException("Told you so", new IOException("Contained"));
Expand Down
Loading