diff --git a/google-cloud-bigtable/clirr-ignored-differences.xml b/google-cloud-bigtable/clirr-ignored-differences.xml
index 1f0ff9f4a1..60b9dca093 100644
--- a/google-cloud-bigtable/clirr-ignored-differences.xml
+++ b/google-cloud-bigtable/clirr-ignored-differences.xml
@@ -156,4 +156,22 @@
com/google/cloud/bigtable/gaxx/retrying/ApiResultRetryAlgorithm
*
+
+
+ 7004
+ com/google/cloud/bigtable/data/v2/stub/mutaterows/MutateRowsRetryingCallable
+ *
+
+
+
+ 7004
+ com/google/cloud/bigtable/data/v2/models/MutateRowsException
+ *
+
+
+
+ 7009
+ com/google/cloud/bigtable/data/v2/models/MutateRowsException
+ *
+
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/MutateRowsException.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/MutateRowsException.java
index d1c0eda844..4ae0606ab9 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/MutateRowsException.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/MutateRowsException.java
@@ -17,6 +17,7 @@
import com.google.api.core.InternalApi;
import com.google.api.gax.rpc.ApiException;
+import com.google.api.gax.rpc.ErrorDetails;
import com.google.api.gax.rpc.StatusCode;
import com.google.auto.value.AutoValue;
import com.google.bigtable.v2.MutateRowsRequest;
@@ -53,16 +54,36 @@ public Object getTransportCode() {
* applications.
*/
@InternalApi
- public MutateRowsException(
+ public static MutateRowsException create(
@Nullable Throwable rpcError,
@Nonnull List failedMutations,
boolean retryable) {
- super("Some mutations failed to apply", rpcError, LOCAL_STATUS, retryable);
+ ErrorDetails errorDetails = null;
+ if (rpcError instanceof ApiException) {
+ errorDetails = ((ApiException) rpcError).getErrorDetails();
+ }
+
+ return new MutateRowsException(rpcError, failedMutations, retryable, errorDetails);
+ }
+
+ private MutateRowsException(
+ @Nullable Throwable rpcError,
+ @Nonnull List failedMutations,
+ boolean retryable,
+ @Nullable ErrorDetails errorDetails) {
+ super(rpcError, LOCAL_STATUS, retryable, errorDetails);
Preconditions.checkNotNull(failedMutations);
Preconditions.checkArgument(!failedMutations.isEmpty(), "failedMutations can't be empty");
this.failedMutations = failedMutations;
}
+ // TODO: remove this after we add a ctor in gax to pass in a Throwable, a message and error
+ // details.
+ @Override
+ public String getMessage() {
+ return "Some mutations failed to apply";
+ }
+
/**
* Retrieve all of the failed mutations. This list will contain failures for all of the mutations
* that have failed across all of the retry attempts so far.
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStub.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStub.java
index a575aa8607..9245682dc1 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStub.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStub.java
@@ -784,7 +784,8 @@ public Map extract(MutateRowsRequest mutateRowsRequest) {
clientContext.getDefaultCallContext(),
withBigtableTracer,
retryingExecutor,
- settings.bulkMutateRowsSettings().getRetryableCodes());
+ settings.bulkMutateRowsSettings().getRetryableCodes(),
+ retryAlgorithm);
}
/**
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/mutaterows/MutateRowsAttemptCallable.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/mutaterows/MutateRowsAttemptCallable.java
index 269ce79031..155ea43211 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/mutaterows/MutateRowsAttemptCallable.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/mutaterows/MutateRowsAttemptCallable.java
@@ -19,7 +19,9 @@
import com.google.api.core.ApiFuture;
import com.google.api.core.ApiFutures;
import com.google.api.gax.grpc.GrpcStatusCode;
+import com.google.api.gax.retrying.RetryAlgorithm;
import com.google.api.gax.retrying.RetryingFuture;
+import com.google.api.gax.retrying.TimedAttemptSettings;
import com.google.api.gax.rpc.ApiCallContext;
import com.google.api.gax.rpc.ApiException;
import com.google.api.gax.rpc.ApiExceptionFactory;
@@ -31,7 +33,6 @@
import com.google.bigtable.v2.MutateRowsResponse.Entry;
import com.google.cloud.bigtable.data.v2.models.MutateRowsException;
import com.google.cloud.bigtable.data.v2.models.MutateRowsException.FailedMutation;
-import com.google.cloud.bigtable.gaxx.retrying.ApiExceptions;
import com.google.cloud.bigtable.gaxx.retrying.NonCancellableFuture;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
@@ -111,6 +112,8 @@ public Object getTransportCode() {
@Nullable private List originalIndexes;
@Nonnull private final Set retryableCodes;
@Nullable private final List permanentFailures;
+ @Nonnull private final RetryAlgorithm retryAlgorithm;
+ @Nonnull private TimedAttemptSettings attemptSettings;
// Parent controller
private RetryingFuture externalFuture;
@@ -138,11 +141,14 @@ public List apply(Throwable throwable) {
@Nonnull UnaryCallable> innerCallable,
@Nonnull MutateRowsRequest originalRequest,
@Nonnull ApiCallContext callContext,
- @Nonnull Set retryableCodes) {
+ @Nonnull Set retryableCodes,
+ @Nonnull RetryAlgorithm retryAlgorithm) {
this.innerCallable = Preconditions.checkNotNull(innerCallable, "innerCallable");
this.currentRequest = Preconditions.checkNotNull(originalRequest, "currentRequest");
this.callContext = Preconditions.checkNotNull(callContext, "callContext");
this.retryableCodes = Preconditions.checkNotNull(retryableCodes, "retryableCodes");
+ this.retryAlgorithm = retryAlgorithm;
+ this.attemptSettings = retryAlgorithm.createFirstAttempt();
permanentFailures = Lists.newArrayList();
}
@@ -230,14 +236,15 @@ private void handleAttemptError(Throwable rpcError) {
Builder builder = lastRequest.toBuilder().clearEntries();
List newOriginalIndexes = Lists.newArrayList();
+ attemptSettings = retryAlgorithm.createNextAttempt(null, entryError, null, attemptSettings);
+
for (int i = 0; i < currentRequest.getEntriesCount(); i++) {
int origIndex = getOriginalIndex(i);
FailedMutation failedMutation = FailedMutation.create(origIndex, entryError);
allFailures.add(failedMutation);
- if (!ApiExceptions.isRetryable2(failedMutation.getError())
- && !failedMutation.getError().isRetryable()) {
+ if (!retryAlgorithm.shouldRetry(null, failedMutation.getError(), null, attemptSettings)) {
permanentFailures.add(failedMutation);
} else {
// Schedule the mutation entry for the next RPC by adding it to the request builder and
@@ -250,7 +257,7 @@ private void handleAttemptError(Throwable rpcError) {
currentRequest = builder.build();
originalIndexes = newOriginalIndexes;
- throw new MutateRowsException(rpcError, allFailures.build(), entryError.isRetryable());
+ throw MutateRowsException.create(rpcError, allFailures.build(), builder.getEntriesCount() > 0);
}
/**
@@ -258,7 +265,7 @@ private void handleAttemptError(Throwable rpcError) {
* transient failures are found, their corresponding mutations are scheduled for the next RPC. The
* caller is notified of both new found errors and pre-existing permanent errors in the thrown
* {@link MutateRowsException}. If no errors exist, then the attempt future is successfully
- * completed.
+ * completed. We don't currently handle RetryInfo on entry level failures.
*/
private void handleAttemptSuccess(List responses) {
List allFailures = Lists.newArrayList(permanentFailures);
@@ -319,7 +326,7 @@ private void handleAttemptSuccess(List responses) {
if (!allFailures.isEmpty()) {
boolean isRetryable = builder.getEntriesCount() > 0;
- throw new MutateRowsException(null, allFailures, isRetryable);
+ throw MutateRowsException.create(null, allFailures, isRetryable);
}
}
@@ -354,10 +361,10 @@ private static ApiException createSyntheticErrorForRpcFailure(Throwable overallR
ApiException requestApiException = (ApiException) overallRequestError;
return ApiExceptionFactory.createException(
- "Didn't receive a result for this mutation entry",
overallRequestError,
requestApiException.getStatusCode(),
- requestApiException.isRetryable());
+ requestApiException.isRetryable(),
+ requestApiException.getErrorDetails());
}
return ApiExceptionFactory.createException(
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/mutaterows/MutateRowsRetryingCallable.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/mutaterows/MutateRowsRetryingCallable.java
index ff0daf78bb..8ad1db258d 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/mutaterows/MutateRowsRetryingCallable.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/mutaterows/MutateRowsRetryingCallable.java
@@ -16,6 +16,7 @@
package com.google.cloud.bigtable.data.v2.stub.mutaterows;
import com.google.api.core.InternalApi;
+import com.google.api.gax.retrying.RetryAlgorithm;
import com.google.api.gax.retrying.RetryingExecutorWithContext;
import com.google.api.gax.retrying.RetryingFuture;
import com.google.api.gax.rpc.ApiCallContext;
@@ -44,23 +45,26 @@ public class MutateRowsRetryingCallable extends UnaryCallable callable;
private final RetryingExecutorWithContext executor;
private final ImmutableSet retryCodes;
+ private final RetryAlgorithm retryAlgorithm;
public MutateRowsRetryingCallable(
@Nonnull ApiCallContext callContextPrototype,
@Nonnull ServerStreamingCallable callable,
@Nonnull RetryingExecutorWithContext executor,
- @Nonnull Set retryCodes) {
+ @Nonnull Set retryCodes,
+ @Nonnull RetryAlgorithm retryAlgorithm) {
this.callContextPrototype = Preconditions.checkNotNull(callContextPrototype);
this.callable = Preconditions.checkNotNull(callable);
this.executor = Preconditions.checkNotNull(executor);
this.retryCodes = ImmutableSet.copyOf(retryCodes);
+ this.retryAlgorithm = retryAlgorithm;
}
@Override
public RetryingFuture futureCall(MutateRowsRequest request, ApiCallContext inputContext) {
ApiCallContext context = callContextPrototype.nullToSelf(inputContext);
MutateRowsAttemptCallable retryCallable =
- new MutateRowsAttemptCallable(callable.all(), request, context, retryCodes);
+ new MutateRowsAttemptCallable(callable.all(), request, context, retryCodes, retryAlgorithm);
RetryingFuture retryingFuture = executor.createFuture(retryCallable, context);
retryCallable.setExternalFuture(retryingFuture);
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/retrying/ApiExceptions.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/retrying/ApiExceptions.java
deleted file mode 100644
index 4e794fa41a..0000000000
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/retrying/ApiExceptions.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2023 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.google.cloud.bigtable.gaxx.retrying;
-
-import com.google.api.core.InternalApi;
-
-// TODO: move this to gax later
-@InternalApi
-public class ApiExceptions {
-
- private ApiExceptions() {}
-
- // TODO: this should replace the existing ApiException#isRetryable() method,
- // but that cant be done in bigtable, so this lives here for now.
- public static boolean isRetryable2(Throwable e) {
- if (RetryInfoRetryAlgorithm.extractRetryDelay(e) != null) {
- return true;
- }
- return false;
- }
-}
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/retrying/RetryInfoRetryAlgorithm.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/retrying/RetryInfoRetryAlgorithm.java
index 71457f7e9a..085b48bbb5 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/retrying/RetryInfoRetryAlgorithm.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/retrying/RetryInfoRetryAlgorithm.java
@@ -20,12 +20,8 @@
import com.google.api.gax.retrying.RetryingContext;
import com.google.api.gax.retrying.TimedAttemptSettings;
import com.google.api.gax.rpc.ApiException;
-import com.google.common.annotations.VisibleForTesting;
import com.google.protobuf.util.Durations;
import com.google.rpc.RetryInfo;
-import io.grpc.Metadata;
-import io.grpc.Status;
-import io.grpc.protobuf.ProtoUtils;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.threeten.bp.Duration;
@@ -37,10 +33,6 @@
@InternalApi
public class RetryInfoRetryAlgorithm extends BasicResultRetryAlgorithm {
- @VisibleForTesting
- public static final Metadata.Key RETRY_INFO_KEY =
- ProtoUtils.keyForProto(RetryInfo.getDefaultInstance());
-
@Override
public TimedAttemptSettings createNextAttempt(
Throwable prevThrowable, ResponseT prevResponse, TimedAttemptSettings prevSettings) {
@@ -50,6 +42,7 @@ public TimedAttemptSettings createNextAttempt(
.toBuilder()
.setRandomizedRetryDelay(retryDelay)
.setAttemptCount(prevSettings.getAttemptCount() + 1)
+ .setOverallAttemptCount(prevSettings.getAttemptCount() + 1)
.build();
}
return null;
@@ -93,17 +86,17 @@ static Duration extractRetryDelay(@Nullable Throwable throwable) {
if (throwable == null) {
return null;
}
- Metadata trailers = Status.trailersFromThrowable(throwable);
- if (trailers == null) {
+ if (!(throwable instanceof ApiException)) {
return null;
}
- RetryInfo retryInfo = trailers.get(RETRY_INFO_KEY);
- if (retryInfo == null) {
+ ApiException exception = (ApiException) throwable;
+ if (exception.getErrorDetails() == null) {
return null;
}
- if (!retryInfo.hasRetryDelay()) {
+ if (exception.getErrorDetails().getRetryInfo() == null) {
return null;
}
+ RetryInfo retryInfo = exception.getErrorDetails().getRetryInfo();
return Duration.ofMillis(Durations.toMillis(retryInfo.getRetryDelay()));
}
}
diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/RetryInfoTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/RetryInfoTest.java
index b38e53480c..fef901ac2b 100644
--- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/RetryInfoTest.java
+++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/RetryInfoTest.java
@@ -15,13 +15,13 @@
*/
package com.google.cloud.bigtable.data.v2.stub;
-import static com.google.cloud.bigtable.gaxx.retrying.RetryInfoRetryAlgorithm.RETRY_INFO_KEY;
import static com.google.common.truth.Truth.assertThat;
import com.google.api.gax.core.NoCredentialsProvider;
import com.google.api.gax.grpc.GrpcStatusCode;
import com.google.api.gax.grpc.GrpcTransportChannel;
import com.google.api.gax.rpc.ApiException;
+import com.google.api.gax.rpc.ErrorDetails;
import com.google.api.gax.rpc.FixedTransportChannelProvider;
import com.google.api.gax.rpc.InternalException;
import com.google.api.gax.rpc.UnavailableException;
@@ -55,7 +55,9 @@
import com.google.cloud.bigtable.data.v2.models.RowMutation;
import com.google.cloud.bigtable.data.v2.models.RowMutationEntry;
import com.google.common.base.Stopwatch;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Queues;
+import com.google.protobuf.Any;
import com.google.rpc.RetryInfo;
import io.grpc.Metadata;
import io.grpc.Status;
@@ -77,13 +79,16 @@ public class RetryInfoTest {
@Rule public GrpcServerRule serverRule = new GrpcServerRule();
+ private static final Metadata.Key ERROR_DETAILS_KEY =
+ Metadata.Key.of("grpc-status-details-bin", Metadata.BINARY_BYTE_MARSHALLER);
+
private FakeBigtableService service;
private BigtableDataClient client;
private BigtableDataSettings.Builder settings;
private AtomicInteger attemptCounter = new AtomicInteger();
private com.google.protobuf.Duration delay =
- com.google.protobuf.Duration.newBuilder().setSeconds(1).setNanos(0).build();
+ com.google.protobuf.Duration.newBuilder().setSeconds(2).setNanos(0).build();
@Before
public void setUp() throws IOException {
@@ -366,13 +371,18 @@ private void verifyRetryInfoCanBeDisabled(Runnable runnable) {
private void enqueueRetryableExceptionWithDelay(com.google.protobuf.Duration delay) {
Metadata trailers = new Metadata();
RetryInfo retryInfo = RetryInfo.newBuilder().setRetryDelay(delay).build();
- trailers.put(RETRY_INFO_KEY, retryInfo);
+ ErrorDetails errorDetails =
+ ErrorDetails.builder().setRawErrorMessages(ImmutableList.of(Any.pack(retryInfo))).build();
+ byte[] status =
+ com.google.rpc.Status.newBuilder().addDetails(Any.pack(retryInfo)).build().toByteArray();
+ trailers.put(ERROR_DETAILS_KEY, status);
ApiException exception =
new UnavailableException(
new StatusRuntimeException(Status.UNAVAILABLE, trailers),
GrpcStatusCode.of(Status.Code.UNAVAILABLE),
- true);
+ true,
+ errorDetails);
service.expectations.add(exception);
}
@@ -380,13 +390,18 @@ private void enqueueRetryableExceptionWithDelay(com.google.protobuf.Duration del
private ApiException enqueueNonRetryableExceptionWithDelay(com.google.protobuf.Duration delay) {
Metadata trailers = new Metadata();
RetryInfo retryInfo = RetryInfo.newBuilder().setRetryDelay(delay).build();
- trailers.put(RETRY_INFO_KEY, retryInfo);
+ ErrorDetails errorDetails =
+ ErrorDetails.builder().setRawErrorMessages(ImmutableList.of(Any.pack(retryInfo))).build();
+ byte[] status =
+ com.google.rpc.Status.newBuilder().addDetails(Any.pack(retryInfo)).build().toByteArray();
+ trailers.put(ERROR_DETAILS_KEY, status);
ApiException exception =
new InternalException(
new StatusRuntimeException(Status.INTERNAL, trailers),
GrpcStatusCode.of(Status.Code.INTERNAL),
- false);
+ false,
+ errorDetails);
service.expectations.add(exception);
diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/mutaterows/MutateRowsAttemptCallableTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/mutaterows/MutateRowsAttemptCallableTest.java
index 358ff01cde..e5d12ccaeb 100644
--- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/mutaterows/MutateRowsAttemptCallableTest.java
+++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/mutaterows/MutateRowsAttemptCallableTest.java
@@ -16,16 +16,19 @@
package com.google.cloud.bigtable.data.v2.stub.mutaterows;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.any;
import com.google.api.core.AbstractApiFuture;
import com.google.api.core.ApiFuture;
import com.google.api.core.ApiFutures;
import com.google.api.gax.grpc.GrpcCallContext;
import com.google.api.gax.grpc.GrpcStatusCode;
+import com.google.api.gax.retrying.RetryAlgorithm;
import com.google.api.gax.retrying.RetrySettings;
import com.google.api.gax.retrying.RetryingFuture;
import com.google.api.gax.retrying.TimedAttemptSettings;
import com.google.api.gax.rpc.ApiCallContext;
+import com.google.api.gax.rpc.ApiException;
import com.google.api.gax.rpc.StatusCode.Code;
import com.google.api.gax.rpc.UnaryCallable;
import com.google.api.gax.rpc.UnavailableException;
@@ -47,6 +50,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import org.mockito.Mockito;
import org.threeten.bp.Duration;
@RunWith(JUnit4.class)
@@ -64,6 +68,8 @@ public class MutateRowsAttemptCallableTest {
private Set retryCodes;
private ApiCallContext callContext;
private MockRetryingFuture parentFuture;
+ private final RetryAlgorithm mockRetryAlgorithm =
+ Mockito.mock(RetryAlgorithm.class);
@Before
public void setUp() {
@@ -71,6 +77,12 @@ public void setUp() {
retryCodes = ImmutableSet.of(Code.DEADLINE_EXCEEDED, Code.UNAVAILABLE);
callContext = GrpcCallContext.createDefault();
parentFuture = new MockRetryingFuture();
+ Mockito.when(mockRetryAlgorithm.shouldRetry(any(), any(), any(), any()))
+ .thenAnswer(
+ input -> {
+ Throwable throwable = input.getArgument(1);
+ return ((ApiException) throwable).isRetryable();
+ });
}
@Test
@@ -84,7 +96,8 @@ public void singleEntrySuccessTest() throws Exception {
.build());
MutateRowsAttemptCallable attemptCallable =
- new MutateRowsAttemptCallable(innerCallable, request, callContext, retryCodes);
+ new MutateRowsAttemptCallable(
+ innerCallable, request, callContext, retryCodes, mockRetryAlgorithm);
attemptCallable.setExternalFuture(parentFuture);
attemptCallable.call();
@@ -107,7 +120,8 @@ public void missingEntry() {
.build());
MutateRowsAttemptCallable attemptCallable =
- new MutateRowsAttemptCallable(innerCallable, request, callContext, retryCodes);
+ new MutateRowsAttemptCallable(
+ innerCallable, request, callContext, retryCodes, mockRetryAlgorithm);
attemptCallable.setExternalFuture(parentFuture);
attemptCallable.call();
@@ -140,7 +154,8 @@ public void testNoRpcTimeout() {
.build());
MutateRowsAttemptCallable attemptCallable =
- new MutateRowsAttemptCallable(innerCallable, request, callContext, retryCodes);
+ new MutateRowsAttemptCallable(
+ innerCallable, request, callContext, retryCodes, mockRetryAlgorithm);
attemptCallable.setExternalFuture(parentFuture);
attemptCallable.call();
@@ -172,7 +187,8 @@ public void mixedTest() {
.build());
MutateRowsAttemptCallable attemptCallable =
- new MutateRowsAttemptCallable(innerCallable, request, callContext, retryCodes);
+ new MutateRowsAttemptCallable(
+ innerCallable, request, callContext, retryCodes, mockRetryAlgorithm);
attemptCallable.setExternalFuture(parentFuture);
// Make the only call
@@ -230,7 +246,8 @@ public void nextAttemptTest() {
.build());
MutateRowsAttemptCallable attemptCallable =
- new MutateRowsAttemptCallable(innerCallable, request, callContext, retryCodes);
+ new MutateRowsAttemptCallable(
+ innerCallable, request, callContext, retryCodes, mockRetryAlgorithm);
attemptCallable.setExternalFuture(parentFuture);
// Make the first call
@@ -295,7 +312,8 @@ public ApiFuture> futureCall(
// Make the call
MutateRowsAttemptCallable attemptCallable =
- new MutateRowsAttemptCallable(innerCallable, request, callContext, retryCodes);
+ new MutateRowsAttemptCallable(
+ innerCallable, request, callContext, retryCodes, mockRetryAlgorithm);
attemptCallable.setExternalFuture(parentFuture);
attemptCallable.call();
@@ -347,7 +365,8 @@ public ApiFuture> futureCall(
// Make the call
MutateRowsAttemptCallable attemptCallable =
- new MutateRowsAttemptCallable(innerCallable, request, callContext, retryCodes);
+ new MutateRowsAttemptCallable(
+ innerCallable, request, callContext, retryCodes, mockRetryAlgorithm);
attemptCallable.setExternalFuture(parentFuture);
attemptCallable.call();
diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/mutaterows/MutateRowsBatchingDescriptorTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/mutaterows/MutateRowsBatchingDescriptorTest.java
index 81d5c67396..237444ba84 100644
--- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/mutaterows/MutateRowsBatchingDescriptorTest.java
+++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/mutaterows/MutateRowsBatchingDescriptorTest.java
@@ -138,7 +138,7 @@ public void splitExceptionWithFailedMutationsTest() {
// Threw an exception at 1st and 3rd entry
MutateRowsException serverError =
- new MutateRowsException(
+ MutateRowsException.create(
null,
ImmutableList.of(
MutateRowsException.FailedMutation.create(