Skip to content

Commit ffd3906

Browse files
committed
Create new handlers for every new request in GoogleCloudStorageService (#27339)
This commit changes the DefaultHttpRequestInitializer in order to make it create new HttpIOExceptionHandler and HttpUnsuccessfulResponseHandler for every new HTTP request instead of reusing the same two handlers for all requests. Closes #27092
1 parent bcc438a commit ffd3906

File tree

2 files changed

+62
-11
lines changed

2 files changed

+62
-11
lines changed

plugins/repository-gcs/src/main/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageService.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
2424
import com.google.api.client.http.HttpBackOffIOExceptionHandler;
2525
import com.google.api.client.http.HttpBackOffUnsuccessfulResponseHandler;
26-
import com.google.api.client.http.HttpIOExceptionHandler;
2726
import com.google.api.client.http.HttpRequest;
2827
import com.google.api.client.http.HttpRequestInitializer;
2928
import com.google.api.client.http.HttpUnsuccessfulResponseHandler;
@@ -34,9 +33,7 @@
3433
import com.google.api.services.storage.StorageScopes;
3534
import org.elasticsearch.ElasticsearchException;
3635
import org.elasticsearch.common.component.AbstractComponent;
37-
import org.elasticsearch.common.inject.Inject;
3836
import org.elasticsearch.common.settings.SecureSetting;
39-
import org.elasticsearch.common.settings.SecureString;
4037
import org.elasticsearch.common.settings.Setting;
4138
import org.elasticsearch.common.settings.Settings;
4239
import org.elasticsearch.common.unit.TimeValue;
@@ -148,15 +145,11 @@ class DefaultHttpRequestInitializer implements HttpRequestInitializer {
148145
private final TimeValue connectTimeout;
149146
private final TimeValue readTimeout;
150147
private final GoogleCredential credential;
151-
private final HttpUnsuccessfulResponseHandler handler;
152-
private final HttpIOExceptionHandler ioHandler;
153148

154149
DefaultHttpRequestInitializer(GoogleCredential credential, TimeValue connectTimeout, TimeValue readTimeout) {
155150
this.credential = credential;
156151
this.connectTimeout = connectTimeout;
157152
this.readTimeout = readTimeout;
158-
this.handler = new HttpBackOffUnsuccessfulResponseHandler(newBackOff());
159-
this.ioHandler = new HttpBackOffIOExceptionHandler(newBackOff());
160153
}
161154

162155
@Override
@@ -168,13 +161,14 @@ public void initialize(HttpRequest request) throws IOException {
168161
request.setReadTimeout((int) readTimeout.millis());
169162
}
170163

171-
request.setIOExceptionHandler(ioHandler);
164+
request.setIOExceptionHandler(new HttpBackOffIOExceptionHandler(newBackOff()));
172165
request.setInterceptor(credential);
173166

167+
final HttpUnsuccessfulResponseHandler handler = new HttpBackOffUnsuccessfulResponseHandler(newBackOff());
174168
request.setUnsuccessfulResponseHandler((req, resp, supportsRetry) -> {
175-
// Let the credential handle the response. If it failed, we rely on our backoff handler
176-
return credential.handleResponse(req, resp, supportsRetry) || handler.handleResponse(req, resp, supportsRetry);
177-
}
169+
// Let the credential handle the response. If it failed, we rely on our backoff handler
170+
return credential.handleResponse(req, resp, supportsRetry) || handler.handleResponse(req, resp, supportsRetry);
171+
}
178172
);
179173
}
180174

plugins/repository-gcs/src/test/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageServiceTests.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,28 @@
2727
import java.util.Map;
2828

2929
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
30+
import com.google.api.client.http.GenericUrl;
31+
import com.google.api.client.http.HttpIOExceptionHandler;
32+
import com.google.api.client.http.HttpRequest;
33+
import com.google.api.client.http.HttpRequestFactory;
34+
import com.google.api.client.http.HttpRequestInitializer;
35+
import com.google.api.client.http.HttpResponse;
36+
import com.google.api.client.http.HttpUnsuccessfulResponseHandler;
37+
import com.google.api.client.testing.http.MockHttpTransport;
3038
import org.elasticsearch.common.settings.Settings;
39+
import org.elasticsearch.common.unit.TimeValue;
3140
import org.elasticsearch.env.Environment;
3241
import org.elasticsearch.repositories.gcs.GoogleCloudStorageService.InternalGoogleCloudStorageService;
3342
import org.elasticsearch.test.ESTestCase;
3443

44+
import static java.util.Collections.emptyMap;
3545
import static org.hamcrest.Matchers.containsString;
46+
import static org.mockito.Matchers.any;
47+
import static org.mockito.Matchers.anyBoolean;
48+
import static org.mockito.Mockito.mock;
49+
import static org.mockito.Mockito.times;
50+
import static org.mockito.Mockito.verify;
51+
import static org.mockito.Mockito.when;
3652

3753
public class GoogleCloudStorageServiceTests extends ESTestCase {
3854

@@ -82,4 +98,45 @@ public void testClientCredential() throws Exception {
8298
InternalGoogleCloudStorageService service = new InternalGoogleCloudStorageService(env, credentials);
8399
assertSame(cred, service.getCredential("_default_", "clientname"));
84100
}
101+
102+
/**
103+
* Test that the {@link InternalGoogleCloudStorageService.DefaultHttpRequestInitializer} attaches new instances
104+
* of {@link HttpIOExceptionHandler} and {@link HttpUnsuccessfulResponseHandler} for every HTTP requests.
105+
*/
106+
public void testDefaultHttpRequestInitializer() throws IOException {
107+
final Environment environment = mock(Environment.class);
108+
when(environment.settings()).thenReturn(Settings.EMPTY);
109+
110+
final GoogleCredential credential = mock(GoogleCredential.class);
111+
when(credential.handleResponse(any(HttpRequest.class), any(HttpResponse.class), anyBoolean())).thenReturn(false);
112+
113+
final TimeValue readTimeout = TimeValue.timeValueSeconds(randomIntBetween(1, 120));
114+
final TimeValue connectTimeout = TimeValue.timeValueSeconds(randomIntBetween(1, 120));
115+
116+
final InternalGoogleCloudStorageService service = new InternalGoogleCloudStorageService(environment, emptyMap());
117+
final HttpRequestInitializer initializer = service.new DefaultHttpRequestInitializer(credential, connectTimeout, readTimeout);
118+
final HttpRequestFactory requestFactory = new MockHttpTransport().createRequestFactory(initializer);
119+
120+
final HttpRequest request1 = requestFactory.buildGetRequest(new GenericUrl());
121+
assertEquals((int) connectTimeout.millis(), request1.getConnectTimeout());
122+
assertEquals((int) readTimeout.millis(), request1.getReadTimeout());
123+
assertSame(credential, request1.getInterceptor());
124+
assertNotNull(request1.getIOExceptionHandler());
125+
assertNotNull(request1.getUnsuccessfulResponseHandler());
126+
127+
final HttpRequest request2 = requestFactory.buildGetRequest(new GenericUrl());
128+
assertEquals((int) connectTimeout.millis(), request2.getConnectTimeout());
129+
assertEquals((int) readTimeout.millis(), request2.getReadTimeout());
130+
assertSame(request1.getInterceptor(), request2.getInterceptor());
131+
assertNotNull(request2.getIOExceptionHandler());
132+
assertNotSame(request1.getIOExceptionHandler(), request2.getIOExceptionHandler());
133+
assertNotNull(request2.getUnsuccessfulResponseHandler());
134+
assertNotSame(request1.getUnsuccessfulResponseHandler(), request2.getUnsuccessfulResponseHandler());
135+
136+
request1.getUnsuccessfulResponseHandler().handleResponse(null, null, false);
137+
verify(credential, times(1)).handleResponse(any(HttpRequest.class), any(HttpResponse.class), anyBoolean());
138+
139+
request2.getUnsuccessfulResponseHandler().handleResponse(null, null, false);
140+
verify(credential, times(2)).handleResponse(any(HttpRequest.class), any(HttpResponse.class), anyBoolean());
141+
}
85142
}

0 commit comments

Comments
 (0)