@Override public WriteTimeoutException copy() { return new WriteTimeoutException( getAddress(), getMessage(), this, getConsistencyLevel(), getWriteType(), getReceivedAcknowledgements(), getRequiredAcknowledgements()); }
@Test(groups = "unit") public void should_create_proper_write_timeout_exception() { WriteTimeoutException e = new WriteTimeoutException(address1, LOCAL_QUORUM, WriteType.BATCH, 2, 3); assertThat(e.getMessage()) .isEqualTo( "Cassandra timeout during BATCH write query at consistency LOCAL_QUORUM (3 replica were required but only 2 acknowledged the write)"); assertThat(e.getConsistencyLevel()).isEqualTo(LOCAL_QUORUM); assertThat(e.getReceivedAcknowledgements()).isEqualTo(2); assertThat(e.getRequiredAcknowledgements()).isEqualTo(3); assertThat(e.getWriteType()).isEqualTo(WriteType.BATCH); assertThat(e.getAddress()).isEqualTo(address1); assertThat(e.getHost()).isEqualTo(address1.getAddress()); e = e.copy(address2); assertThat(e.getMessage()) .isEqualTo( "Cassandra timeout during BATCH write query at consistency LOCAL_QUORUM (3 replica were required but only 2 acknowledged the write)"); assertThat(e.getConsistencyLevel()).isEqualTo(LOCAL_QUORUM); assertThat(e.getReceivedAcknowledgements()).isEqualTo(2); assertThat(e.getRequiredAcknowledgements()).isEqualTo(3); assertThat(e.getWriteType()).isEqualTo(WriteType.BATCH); assertThat(e.getAddress()).isEqualTo(address2); assertThat(e.getHost()).isEqualTo(address2.getAddress()); } }
@Test(groups = "short") public void should_throw_proper_write_timeout_exception() { simulateError(1, write_request_timeout); try { query(); fail("expected a WriteTimeoutException"); } catch (WriteTimeoutException e) { assertThat(e.getMessage()) .isEqualTo( "Cassandra timeout during SIMPLE write query at consistency LOCAL_ONE (1 replica were required but only 0 acknowledged the write)"); assertThat(e.getConsistencyLevel()).isEqualTo(LOCAL_ONE); assertThat(e.getReceivedAcknowledgements()).isEqualTo(0); assertThat(e.getRequiredAcknowledgements()).isEqualTo(1); assertThat(e.getWriteType()).isEqualTo(WriteType.SIMPLE); assertThat(e.getAddress()).isEqualTo(host1.getSocketAddress()); assertThat(e.getHost()).isEqualTo(host1.getAddress()); } }
retryPolicy.onWriteTimeout( statement, wte.getConsistencyLevel(), wte.getWriteType(), wte.getRequiredAcknowledgements(), wte.getReceivedAcknowledgements(), retriesByPolicy); else {
WriteType writeType = e.getWriteType(); if (writeType == WriteType.BATCH_LOG) { throw new RetriableExecutionException("logging failed in the batch.", e);
return new TruncateException(host, message); case WRITE_TIMEOUT: return ((WriteTimeoutException) infos).copy(host); case READ_TIMEOUT: return ((ReadTimeoutException) infos).copy(host);
if (ignoreTimeout && e.getReceivedAcknowledgements() > 0) { return 1; if (ignoreTimeout && e.getReceivedAcknowledgements() > 0) { return currentValue + 1;
/** * Ensures that when handling a write timeout with {@link DowngradingConsistencyRetryPolicy} that * a retry is attempted on the same host with a reduced consistency level that matches * min(received acknowledgments, THREE) if the {@link WriteType} is {@link * WriteType#UNLOGGED_BATCH} and is only retries once. * * @param alive The number of received acknowledgements to use in write timeout. * @param expectedDowngradedCL The consistency level that is expected to be used on the retry. * @test_category retry_policy */ @Test(groups = "short", dataProvider = "consistencyLevels") public void should_retry_once_on_same_host_with_reduced_consistency_level_on_write_timeout( int alive, ConsistencyLevel expectedDowngradedCL) { simulateError( 1, write_request_timeout, new WriteTimeoutConfig(UNLOGGED_BATCH, alive, alive + 1)); try { query(); fail("expected a WriteTimeoutException"); } catch (WriteTimeoutException e) { assertThat(e.getConsistencyLevel()).isEqualTo(expectedDowngradedCL); } assertOnWriteTimeoutWasCalled(2); assertThat(errors.getRetries().getCount()).isEqualTo(1); assertThat(errors.getWriteTimeouts().getCount()).isEqualTo(2); assertThat(errors.getRetriesOnWriteTimeout().getCount()).isEqualTo(1); assertQueried(1, 2); assertQueried(2, 0); assertQueried(3, 0); }
if (statement.isIdempotentWithDefault(manager.cluster.getConfiguration().getQueryOptions())) retry = retryPolicy.onWriteTimeout(statement, wte.getConsistencyLevel(), wte.getWriteType(), wte.getRequiredAcknowledgements(), wte.getReceivedAcknowledgements(), retriesByPolicy); else {
@Test(groups = "short") public void should_throw_proper_write_timeout_exception() { simulateError(1, write_request_timeout); try { query(); fail("expected a WriteTimeoutException"); } catch (WriteTimeoutException e) { assertThat(e.getMessage()) .isEqualTo( "Cassandra timeout during SIMPLE write query at consistency LOCAL_ONE (1 replica were required but only 0 acknowledged the write)"); assertThat(e.getConsistencyLevel()).isEqualTo(LOCAL_ONE); assertThat(e.getReceivedAcknowledgements()).isEqualTo(0); assertThat(e.getRequiredAcknowledgements()).isEqualTo(1); assertThat(e.getWriteType()).isEqualTo(WriteType.SIMPLE); assertThat(e.getAddress()).isEqualTo(host1.getSocketAddress()); assertThat(e.getHost()).isEqualTo(host1.getAddress()); } }
if (e.getWriteType() == WriteType.CAS) { } else if (e.getWriteType() == WriteType.SIMPLE) { Mutation mutation = (Mutation) operation; if (mutation.getCondition().isPresent()) {
public DriverException asException(InetSocketAddress host) { switch (code) { case SERVER_ERROR: return new DriverInternalError(String.format("An unexpected error occurred server side on %s: %s", host, message)); case PROTOCOL_ERROR: return new DriverInternalError("An unexpected protocol error occurred. This is a bug in this library, please report: " + message); case BAD_CREDENTIALS: return new AuthenticationException(host, message); case UNAVAILABLE: return ((UnavailableException)infos).copy(); // We copy to have a nice stack trace case OVERLOADED: return new DriverInternalError(String.format("Queried host (%s) was overloaded; this shouldn't happen, another node should have been tried", host)); case IS_BOOTSTRAPPING: return new DriverInternalError(String.format("Queried host (%s) was bootstrapping; this shouldn't happen, another node should have been tried", host)); case TRUNCATE_ERROR: return new TruncateException(message); case WRITE_TIMEOUT: return ((WriteTimeoutException)infos).copy(); case READ_TIMEOUT: return ((ReadTimeoutException)infos).copy(); case SYNTAX_ERROR: return new SyntaxError(message); case UNAUTHORIZED: return new UnauthorizedException(message); case INVALID: return new InvalidQueryException(message); case CONFIG_ERROR: return new InvalidConfigurationInQueryException(message); case ALREADY_EXISTS: return ((AlreadyExistsException)infos).copy(); case UNPREPARED: return new DriverInternalError(String.format("A prepared query was submitted on %s but was not known of that node; this shouldn't happen, the query should have been re-prepared", host)); default: return new DriverInternalError(String.format("Unknown protocol error code %s returned by %s. The error message was: %s", code, host, message)); } }
/** * Ensures that when handling a write timeout with {@link DowngradingConsistencyRetryPolicy} that * a retry is attempted on the same host with a reduced consistency level that matches * min(received acknowledgments, THREE) if the {@link WriteType} is {@link * WriteType#UNLOGGED_BATCH} and is only retries once. * * @param alive The number of received acknowledgements to use in write timeout. * @param expectedDowngradedCL The consistency level that is expected to be used on the retry. * @test_category retry_policy */ @Test(groups = "short", dataProvider = "consistencyLevels") public void should_retry_once_on_same_host_with_reduced_consistency_level_on_write_timeout( int alive, ConsistencyLevel expectedDowngradedCL) { simulateError( 1, write_request_timeout, new WriteTimeoutConfig(UNLOGGED_BATCH, alive, alive + 1)); try { query(); fail("expected a WriteTimeoutException"); } catch (WriteTimeoutException e) { assertThat(e.getConsistencyLevel()).isEqualTo(expectedDowngradedCL); } assertOnWriteTimeoutWasCalled(2); assertThat(errors.getRetries().getCount()).isEqualTo(1); assertThat(errors.getWriteTimeouts().getCount()).isEqualTo(2); assertThat(errors.getRetriesOnWriteTimeout().getCount()).isEqualTo(1); assertQueried(1, 2); assertQueried(2, 0); assertQueried(3, 0); }
/** * Create a copy of this exception with a nicer stack trace, and including the coordinator address * that caused this exception to be raised. * * <p>This method is mainly intended for internal use by the driver and exists mainly because: * * <ol> * <li>the original exception was decoded from a response frame and at that time, the * coordinator address was not available; and * <li>the newly-created exception will refer to the current thread in its stack trace, which * generally yields a more user-friendly stack trace that the original one. * </ol> * * @param address The full address of the host that caused this exception to be thrown. * @return a copy/clone of this exception, but with the given host address instead of the original * one. */ public WriteTimeoutException copy(InetSocketAddress address) { return new WriteTimeoutException( address, getMessage(), this, getConsistencyLevel(), getWriteType(), getReceivedAcknowledgements(), getRequiredAcknowledgements()); } }
@Test(groups = "unit") public void should_create_proper_write_timeout_exception() { WriteTimeoutException e = new WriteTimeoutException(address1, LOCAL_QUORUM, WriteType.BATCH, 2, 3); assertThat(e.getMessage()) .isEqualTo( "Cassandra timeout during BATCH write query at consistency LOCAL_QUORUM (3 replica were required but only 2 acknowledged the write)"); assertThat(e.getConsistencyLevel()).isEqualTo(LOCAL_QUORUM); assertThat(e.getReceivedAcknowledgements()).isEqualTo(2); assertThat(e.getRequiredAcknowledgements()).isEqualTo(3); assertThat(e.getWriteType()).isEqualTo(WriteType.BATCH); assertThat(e.getAddress()).isEqualTo(address1); assertThat(e.getHost()).isEqualTo(address1.getAddress()); e = e.copy(address2); assertThat(e.getMessage()) .isEqualTo( "Cassandra timeout during BATCH write query at consistency LOCAL_QUORUM (3 replica were required but only 2 acknowledged the write)"); assertThat(e.getConsistencyLevel()).isEqualTo(LOCAL_QUORUM); assertThat(e.getReceivedAcknowledgements()).isEqualTo(2); assertThat(e.getRequiredAcknowledgements()).isEqualTo(3); assertThat(e.getWriteType()).isEqualTo(WriteType.BATCH); assertThat(e.getAddress()).isEqualTo(address2); assertThat(e.getHost()).isEqualTo(address2.getAddress()); } }
if (statement.isIdempotentWithDefault(manager.cluster.getConfiguration().getQueryOptions())) retry = retryPolicy.onWriteTimeout(statement, wte.getConsistencyLevel(), wte.getWriteType(), wte.getRequiredAcknowledgements(), wte.getReceivedAcknowledgements(), retriesByPolicy); else {
@Test public void handle_WTEThrownInSimpleWriteInBatchExecution_ShouldThrowRetriableExecutionException() { // Arrange configureBehavior(); mutations = prepareConditionalPuts(); WriteTimeoutException e = mock(WriteTimeoutException.class); when(e.getWriteType()).thenReturn(WriteType.SIMPLE); when(session.execute(any(Statement.class))).thenThrow(e); // Act Assert assertThatThrownBy( () -> { batch.handle(mutations); }) .isInstanceOf(RetriableExecutionException.class) .hasCause(e); }
return new TruncateException(host, message); case WRITE_TIMEOUT: return ((WriteTimeoutException) infos).copy(host); case READ_TIMEOUT: return ((ReadTimeoutException) infos).copy(host);
@Override public DriverException copy() { return new WriteTimeoutException(getMessage(), this, getConsistencyLevel(), getWriteType(), getReceivedAcknowledgements(), getRequiredAcknowledgements()); } }
if (statement.isIdempotentWithDefault(manager.cluster.getConfiguration().getQueryOptions())) retry = retryPolicy.onWriteTimeout(statement, wte.getConsistencyLevel(), wte.getWriteType(), wte.getRequiredAcknowledgements(), wte.getReceivedAcknowledgements(), retriesByPolicy); else {