Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specify Retry Usage in Firebase App Options #1076

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/main/java/com/google/firebase/FirebaseOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ public GoogleCredentials get() {
private final JsonFactory jsonFactory;
private final ThreadManager threadManager;
private final FirestoreOptions firestoreOptions;
private final boolean retryEnabled;

private FirebaseOptions(@NonNull final FirebaseOptions.Builder builder) {
this.databaseUrl = builder.databaseUrl;
Expand Down Expand Up @@ -116,6 +117,7 @@ private FirebaseOptions(@NonNull final FirebaseOptions.Builder builder) {
checkArgument(builder.writeTimeout >= 0);
this.writeTimeout = builder.writeTimeout;
this.firestoreOptions = builder.firestoreOptions;
this.retryEnabled = builder.retryEnabled;
}

/**
Expand Down Expand Up @@ -227,6 +229,15 @@ FirestoreOptions getFirestoreOptions() {
return firestoreOptions;
}

/**
* Returns whether automatic retries are enabled for HTTP requests.
*
* @return true if retries are enabled, and false otherwise.
*/
public boolean isRetryEnabled() {
return retryEnabled;
}

/**
* Creates an empty builder.
*
Expand Down Expand Up @@ -272,6 +283,7 @@ public static final class Builder {
private int connectTimeout;
private int readTimeout;
private int writeTimeout;
private boolean retryEnabled = true;

/**
* Constructs an empty builder.
Expand Down Expand Up @@ -521,6 +533,17 @@ public Builder setWriteTimeout(int writeTimeout) {
return this;
}

/**
* Enables or disables automatic retries for HTTP requests. By default, retries are enabled.
*
* @param retryEnabled Whether to enable automatic retries (default: true).
* @return This {@code Builder} instance is returned so subsequent calls can be chained.
*/
public Builder setRetryEnabled(boolean retryEnabled) {
this.retryEnabled = retryEnabled;
return this;
}

/**
* Builds the {@link FirebaseOptions} instance from the previously set options.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,17 @@ public class ApiClientUtils {
private ApiClientUtils() { }

/**
* Creates a new {@code HttpRequestFactory} which provides authorization (OAuth2), timeouts and
* automatic retries.
* Creates a new {@code HttpRequestFactory} which provides authorization (OAuth2) and timeouts.
* Automatic retries are enabled or disabled based on the application's configuration.
*
* @param app {@link FirebaseApp} from which to obtain authorization credentials.
* @return A new {@code HttpRequestFactory} instance.
*/
public static HttpRequestFactory newAuthorizedRequestFactory(FirebaseApp app) {
return newAuthorizedRequestFactory(app, DEFAULT_RETRY_CONFIG);
if (app.getOptions().isRetryEnabled()) {
return newAuthorizedRequestFactory(app, DEFAULT_RETRY_CONFIG);
}
return newAuthorizedRequestFactory(app, /*retryConfig*/ null);
}

/**
Expand Down
5 changes: 5 additions & 0 deletions src/test/java/com/google/firebase/FirebaseOptionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;

import com.google.api.client.json.gson.GsonFactory;
import com.google.auth.oauth2.AccessToken;
Expand All @@ -38,6 +39,7 @@

import org.junit.Test;


/**
* Tests for {@link FirebaseOptions}.
*/
Expand Down Expand Up @@ -89,6 +91,7 @@ public void createOptionsWithAllValuesSet() throws IOException {
.setReadTimeout(60000)
.setWriteTimeout(90000)
.setFirestoreOptions(firestoreOptions)
.setRetryEnabled(false)
.build();
assertEquals(FIREBASE_DB_URL, firebaseOptions.getDatabaseUrl());
assertEquals(FIREBASE_STORAGE_BUCKET, firebaseOptions.getStorageBucket());
Expand All @@ -100,6 +103,7 @@ public void createOptionsWithAllValuesSet() throws IOException {
assertEquals(60000, firebaseOptions.getReadTimeout());
assertEquals(90000, firebaseOptions.getWriteTimeout());
assertSame(firestoreOptions, firebaseOptions.getFirestoreOptions());
assertFalse(firebaseOptions.isRetryEnabled());

GoogleCredentials credentials = firebaseOptions.getCredentials();
assertNotNull(credentials);
Expand Down Expand Up @@ -193,6 +197,7 @@ public void checkToBuilderCreatesNewEquivalentInstance() {
assertEquals(ALL_VALUES_OPTIONS.getReadTimeout(), allValuesOptionsCopy.getReadTimeout());
assertSame(ALL_VALUES_OPTIONS.getFirestoreOptions(),
allValuesOptionsCopy.getFirestoreOptions());
assertEquals(ALL_VALUES_OPTIONS.isRetryEnabled(), allValuesOptionsCopy.isRetryEnabled());
}

@Test(expected = IllegalArgumentException.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public void testAuthorizedHttpClient() throws IOException {
}

@Test
public void testAuthorizedHttpClientWithoutRetry() throws IOException {
public void testAuthorizedHttpClientNoRetryConfigured() throws IOException {
FirebaseApp app = FirebaseApp.initializeApp(TEST_OPTIONS);

HttpRequestFactory requestFactory = ApiClientUtils.newAuthorizedRequestFactory(app, null);
Expand All @@ -83,6 +83,24 @@ public void testAuthorizedHttpClientWithoutRetry() throws IOException {
assertFalse(retryHandler instanceof RetryHandlerDecorator);
}

@Test
public void testAuthorizedHttpClientWithRetryDisabled() throws IOException {
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(new MockGoogleCredentials("test-token"))
.setRetryEnabled(false)
.build();

FirebaseApp app = FirebaseApp.initializeApp(options);

HttpRequestFactory requestFactory = ApiClientUtils.newAuthorizedRequestFactory(app);

assertTrue(requestFactory.getInitializer() instanceof FirebaseRequestInitializer);
HttpRequest request = requestFactory.buildGetRequest(TEST_URL);
assertEquals("Bearer test-token", request.getHeaders().getAuthorization());
HttpUnsuccessfulResponseHandler retryHandler = request.getUnsuccessfulResponseHandler();
assertFalse(retryHandler instanceof RetryHandlerDecorator);
}

@Test
public void testUnauthorizedHttpClient() throws IOException {
FirebaseApp app = FirebaseApp.initializeApp(TEST_OPTIONS);
Expand Down