1717import com .google .cloud .http .HttpTransportOptions ;
1818import com .google .cloud .storage .StorageOptions ;
1919import com .google .cloud .storage .StorageRetryStrategy ;
20- import com .sun .net .httpserver .Headers ;
2120import com .sun .net .httpserver .HttpExchange ;
2221import com .sun .net .httpserver .HttpHandler ;
2322
5756import java .util .Collection ;
5857import java .util .Collections ;
5958import java .util .Map ;
60- import java .util .regex .Matcher ;
61- import java .util .regex .Pattern ;
6259
6360import static org .elasticsearch .common .io .Streams .readFully ;
6461import static org .elasticsearch .repositories .blobstore .BlobStoreTestUtil .randomPurpose ;
6562import static org .elasticsearch .repositories .gcs .GoogleCloudStorageClientSettings .CREDENTIALS_FILE_SETTING ;
6663import static org .elasticsearch .repositories .gcs .GoogleCloudStorageClientSettings .ENDPOINT_SETTING ;
6764import static org .elasticsearch .repositories .gcs .GoogleCloudStorageClientSettings .TOKEN_URI_SETTING ;
68- import static org .elasticsearch .repositories .gcs .GoogleCloudStorageOperationsStats .Operation ;
6965import static org .elasticsearch .repositories .gcs .GoogleCloudStorageRepository .BASE_PATH ;
7066import static org .elasticsearch .repositories .gcs .GoogleCloudStorageRepository .BUCKET ;
7167import static org .elasticsearch .repositories .gcs .GoogleCloudStorageRepository .CLIENT_NAME ;
@@ -107,7 +103,11 @@ protected Map<String, HttpHandler> createHttpHandlers() {
107103
108104 @ Override
109105 protected HttpHandler createErroneousHttpHandler (final HttpHandler delegate ) {
110- return new GoogleErroneousHttpHandler (delegate , randomIntBetween (2 , 3 ));
106+ if (delegate instanceof FakeOAuth2HttpHandler ) {
107+ return new GoogleErroneousHttpHandler (delegate , randomIntBetween (2 , 3 ));
108+ } else {
109+ return new GoogleCloudStorageStatsCollectorHttpHandler (new GoogleErroneousHttpHandler (delegate , randomIntBetween (2 , 3 )));
110+ }
111111 }
112112
113113 @ Override
@@ -223,15 +223,20 @@ public void testWriteFileMultipleOfChunkSize() throws IOException {
223223 }
224224 }
225225
226+ @ Override
227+ public void testRequestStats () throws Exception {
228+ super .testRequestStats ();
229+ }
230+
226231 public static class TestGoogleCloudStoragePlugin extends GoogleCloudStoragePlugin {
227232
228233 public TestGoogleCloudStoragePlugin (Settings settings ) {
229234 super (settings );
230235 }
231236
232237 @ Override
233- protected GoogleCloudStorageService createStorageService (Settings settings ) {
234- return new GoogleCloudStorageService (settings ) {
238+ protected GoogleCloudStorageService createStorageService (boolean isServerless ) {
239+ return new GoogleCloudStorageService () {
235240 @ Override
236241 StorageOptions createStorageOptions (
237242 final GoogleCloudStorageClientSettings gcsClientSettings ,
@@ -277,7 +282,8 @@ public Map<String, Repository.Factory> getRepositories(
277282 this .storageService ,
278283 clusterService ,
279284 bigArrays ,
280- recoverySettings
285+ recoverySettings ,
286+ new GcsRepositoryStatsCollector ()
281287 ) {
282288 @ Override
283289 protected GoogleCloudStorageBlobStore createBlobStore () {
@@ -288,7 +294,8 @@ protected GoogleCloudStorageBlobStore createBlobStore() {
288294 storageService ,
289295 bigArrays ,
290296 randomIntBetween (1 , 8 ) * 1024 ,
291- BackoffPolicy .noBackoff ()
297+ BackoffPolicy .noBackoff (),
298+ this .statsCollector ()
292299 ) {
293300 @ Override
294301 long getLargeBlobThresholdInBytes () {
@@ -356,43 +363,24 @@ protected boolean canFailRequest(final HttpExchange exchange) {
356363 @ SuppressForbidden (reason = "this tests uses a HttpServer to emulate an GCS endpoint" )
357364 private static class GoogleCloudStorageStatsCollectorHttpHandler extends HttpStatsCollectorHandler {
358365
359- public static final Pattern contentRangeMatcher = Pattern .compile ("bytes \\ d+-(\\ d+)/(\\ d+)" );
360-
361366 GoogleCloudStorageStatsCollectorHttpHandler (final HttpHandler delegate ) {
362367 super (delegate );
363368 }
364369
365370 @ Override
366371 public void maybeTrack (HttpExchange exchange ) {
367372 final String request = exchange .getRequestMethod () + " " + exchange .getRequestURI ().toString ();
368- final Headers requestHeaders = exchange .getRequestHeaders ();
369373 if (Regex .simpleMatch ("GET */storage/v1/b/*/o/*" , request )) {
370- trackRequest (Operation . GET_OBJECT .key ());
374+ trackRequest (StorageOperation . GET .key ());
371375 } else if (Regex .simpleMatch ("GET /storage/v1/b/*/o*" , request )) {
372- trackRequest (Operation .LIST_OBJECTS .key ());
373- } else if (Regex .simpleMatch ("PUT /upload/storage/v1/b/*uploadType=resumable*" , request ) && isLastPart (requestHeaders )) {
374- // Resumable uploads are billed as a single operation, that's the reason we're tracking
375- // the request only when it's the last part.
376- // See https://cloud.google.com/storage/docs/resumable-uploads#introduction
377- trackRequest (Operation .INSERT_OBJECT .key ());
376+ trackRequest (StorageOperation .LIST .key ());
377+ } else if (Regex .simpleMatch ("POST /upload/storage/v1/b/*uploadType=resumable*" , request )) {
378+ trackRequest (StorageOperation .INSERT .key ());
379+ } else if (Regex .simpleMatch ("PUT /upload/storage/v1/b/*uploadType=resumable*" , request )) {
380+ trackRequest (StorageOperation .INSERT .key ());
378381 } else if (Regex .simpleMatch ("POST /upload/storage/v1/b/*uploadType=multipart*" , request )) {
379- trackRequest (Operation . INSERT_OBJECT .key ());
382+ trackRequest (StorageOperation . INSERT .key ());
380383 }
381384 }
382-
383- boolean isLastPart (Headers requestHeaders ) {
384- if (requestHeaders .containsKey ("Content-range" ) == false ) return false ;
385-
386- // https://cloud.google.com/storage/docs/json_api/v1/parameters#contentrange
387- final String contentRange = requestHeaders .getFirst ("Content-range" );
388-
389- final Matcher matcher = contentRangeMatcher .matcher (contentRange );
390-
391- if (matcher .matches () == false ) return false ;
392-
393- String upperBound = matcher .group (1 );
394- String totalLength = matcher .group (2 );
395- return Integer .parseInt (upperBound ) == Integer .parseInt (totalLength ) - 1 ;
396- }
397385 }
398386}
0 commit comments