Skip to content

Commit 09c426b

Browse files
committed
chore: include redirect_token in x-goog-request-params
1 parent af52279 commit 09c426b

4 files changed

Lines changed: 108 additions & 6 deletions

File tree

‎google-cloud-storage/src/main/java/com/google/cloud/storage/BlobDescriptorState.java‎

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,21 @@
2020

2121
import com.google.api.gax.grpc.GrpcCallContext;
2222
import com.google.cloud.storage.RetryContext.OnFailure;
23+
import com.google.common.collect.ImmutableList;
24+
import com.google.common.collect.ImmutableMap;
2325
import com.google.storage.v2.BidiReadHandle;
2426
import com.google.storage.v2.BidiReadObjectRequest;
27+
import com.google.storage.v2.BidiReadObjectSpec;
2528
import com.google.storage.v2.Object;
2629
import java.util.HashMap;
30+
import java.util.List;
2731
import java.util.Map;
32+
import java.util.Objects;
2833
import java.util.concurrent.atomic.AtomicLong;
2934
import java.util.concurrent.atomic.AtomicReference;
3035
import java.util.concurrent.locks.ReentrantLock;
36+
import java.util.stream.Collectors;
37+
import java.util.stream.Stream;
3138
import org.checkerframework.checker.lock.qual.GuardedBy;
3239
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
3340
import org.checkerframework.checker.nullness.qual.NonNull;
@@ -65,7 +72,8 @@ OpenArguments getOpenArguments() {
6572
BidiReadObjectRequest.Builder b = openRequest.toBuilder().clearReadRanges();
6673

6774
Object obj = metadata.get();
68-
if (obj != null && obj.getGeneration() != openRequest.getReadObjectSpec().getGeneration()) {
75+
BidiReadObjectSpec spec = openRequest.getReadObjectSpec();
76+
if (obj != null && obj.getGeneration() != spec.getGeneration()) {
6977
b.getReadObjectSpecBuilder().setGeneration(obj.getGeneration());
7078
}
7179

@@ -84,7 +92,16 @@ OpenArguments getOpenArguments() {
8492
.map(BlobDescriptorStreamRead::makeReadRange)
8593
.forEach(b::addReadRanges);
8694

87-
return OpenArguments.of(baseContext, b.build());
95+
ImmutableMap<String, List<String>> headers =
96+
ImmutableMap.of(
97+
"x-goog-request-params",
98+
ImmutableList.of(
99+
Stream.of(
100+
"bucket=" + spec.getBucket(),
101+
routingToken != null ? "routing_token=" + routingToken : null)
102+
.filter(Objects::nonNull)
103+
.collect(Collectors.joining("&"))));
104+
return OpenArguments.of(baseContext.withExtraHeaders(headers), b.build());
88105
} finally {
89106
lock.unlock();
90107
}

‎google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcStorageImpl.java‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,6 +1527,7 @@ public Blob moveBlob(MoveBlobRequest request) {
15271527

15281528
@Override
15291529
public ApiFuture<BlobDescriptor> getBlobDescriptor(BlobId id, BlobSourceOption... options) {
1530+
Opts<ObjectSourceOpt> opts = Opts.unwrap(options);
15301531
Object object = codecs.blobId().encode(id);
15311532

15321533
BidiReadObjectSpec.Builder spec =
@@ -1544,8 +1545,7 @@ public ApiFuture<BlobDescriptor> getBlobDescriptor(BlobId id, BlobSourceOption..
15441545
new ZeroCopyBidiStreamingCallable<>(
15451546
storageClient.bidiReadObjectCallable(), bidiResponseContentLifecycleManager);
15461547

1547-
GrpcCallContext context =
1548-
GrpcUtils.contextWithBucketName(object.getBucket(), GrpcCallContext.createDefault());
1548+
GrpcCallContext context = opts.grpcMetadataMapper().apply(GrpcCallContext.createDefault());
15491549

15501550
return BlobDescriptorImpl.create(req, context, callable, executor, retryContextProvider);
15511551
}

‎google-cloud-storage/src/test/java/com/google/cloud/storage/BlobDescriptorStateTest.java‎

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import com.google.api.gax.grpc.GrpcCallContext;
2424
import com.google.cloud.storage.BlobDescriptorState.OpenArguments;
2525
import com.google.cloud.storage.BlobDescriptorStreamRead.AccumulatingRead;
26+
import com.google.common.collect.ImmutableList;
27+
import com.google.common.collect.ImmutableMap;
2628
import com.google.protobuf.ByteString;
2729
import com.google.storage.v2.BidiReadHandle;
2830
import com.google.storage.v2.BidiReadObjectRequest;
@@ -31,6 +33,8 @@
3133
import com.google.storage.v2.CommonObjectRequestParams;
3234
import com.google.storage.v2.Object;
3335
import com.google.storage.v2.ReadRange;
36+
import java.util.List;
37+
import java.util.Map;
3438
import org.junit.Test;
3539

3640
public final class BlobDescriptorStateTest {
@@ -83,7 +87,11 @@ public void getOpenArguments_includesAllRelevantModifications() throws Exception
8387

8488
OpenArguments expected =
8589
OpenArguments.of(
86-
GrpcCallContext.createDefault(),
90+
GrpcCallContext.createDefault()
91+
.withExtraHeaders(
92+
ImmutableMap.of(
93+
"x-goog-request-params",
94+
ImmutableList.of("bucket=projects/_/buckets/my-bucket"))),
8795
BidiReadObjectRequest.newBuilder()
8896
.setReadObjectSpec(
8997
BidiReadObjectSpec.newBuilder()
@@ -111,4 +119,79 @@ public void getOpenArguments_includesAllRelevantModifications() throws Exception
111119
assertThat(actual.getCtx().getExtraHeaders())
112120
.isEqualTo(expected.getCtx().getExtraHeaders()));
113121
}
122+
123+
@Test
124+
public void redirectTokenPresentInHeadersIfNonNull() {
125+
BidiReadObjectRequest base =
126+
BidiReadObjectRequest.newBuilder()
127+
.setReadObjectSpec(
128+
BidiReadObjectSpec.newBuilder()
129+
.setBucket("projects/_/buckets/my-bucket")
130+
.setObject("my-object"))
131+
.build();
132+
133+
BlobDescriptorState state = new BlobDescriptorState(GrpcCallContext.createDefault(), base);
134+
135+
state.setRoutingToken("token-1");
136+
137+
OpenArguments openArguments = state.getOpenArguments();
138+
GrpcCallContext ctx = openArguments.getCtx();
139+
Map<String, List<String>> extraHeaders = ctx.getExtraHeaders();
140+
Map<String, List<String>> expected =
141+
ImmutableMap.of(
142+
"x-goog-request-params",
143+
ImmutableList.of("bucket=projects/_/buckets/my-bucket&routing_token=token-1"));
144+
145+
assertThat(extraHeaders).isEqualTo(expected);
146+
}
147+
148+
@Test
149+
public void redirectTokenNotPresentInHeadersIfNull() {
150+
BidiReadObjectRequest base =
151+
BidiReadObjectRequest.newBuilder()
152+
.setReadObjectSpec(
153+
BidiReadObjectSpec.newBuilder()
154+
.setBucket("projects/_/buckets/my-bucket")
155+
.setObject("my-object"))
156+
.build();
157+
158+
BlobDescriptorState state = new BlobDescriptorState(GrpcCallContext.createDefault(), base);
159+
160+
state.setRoutingToken(null);
161+
162+
OpenArguments openArguments = state.getOpenArguments();
163+
GrpcCallContext ctx = openArguments.getCtx();
164+
Map<String, List<String>> extraHeaders = ctx.getExtraHeaders();
165+
Map<String, List<String>> expected =
166+
ImmutableMap.of(
167+
"x-goog-request-params", ImmutableList.of("bucket=projects/_/buckets/my-bucket"));
168+
169+
assertThat(extraHeaders).isEqualTo(expected);
170+
}
171+
172+
@Test
173+
public void redirectTokenMustNotBeUrlEncoded() {
174+
BidiReadObjectRequest base =
175+
BidiReadObjectRequest.newBuilder()
176+
.setReadObjectSpec(
177+
BidiReadObjectSpec.newBuilder()
178+
.setBucket("projects/_/buckets/my-bucket")
179+
.setObject("my-object"))
180+
.build();
181+
182+
BlobDescriptorState state = new BlobDescriptorState(GrpcCallContext.createDefault(), base);
183+
184+
state.setRoutingToken("token%20with%2furl%20encoding");
185+
186+
OpenArguments openArguments = state.getOpenArguments();
187+
GrpcCallContext ctx = openArguments.getCtx();
188+
Map<String, List<String>> extraHeaders = ctx.getExtraHeaders();
189+
Map<String, List<String>> expected =
190+
ImmutableMap.of(
191+
"x-goog-request-params",
192+
ImmutableList.of(
193+
"bucket=projects/_/buckets/my-bucket&routing_token=token%20with%2furl%20encoding"));
194+
195+
assertThat(extraHeaders).isEqualTo(expected);
196+
}
114197
}

‎google-cloud-storage/src/test/java/com/google/cloud/storage/ITBlobDescriptorFakeTest.java‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.google.api.gax.rpc.UnavailableException;
3232
import com.google.cloud.storage.Crc32cValue.Crc32cLengthKnown;
3333
import com.google.cloud.storage.Hasher.UncheckedChecksumMismatchException;
34+
import com.google.cloud.storage.Storage.BlobSourceOption;
3435
import com.google.cloud.storage.it.ChecksummedTestContent;
3536
import com.google.cloud.storage.it.GrpcPlainRequestLoggingInterceptor;
3637
import com.google.common.collect.ImmutableMap;
@@ -305,7 +306,8 @@ public void onNext(BidiReadObjectRequest value) {
305306
Storage storage = fakeServer.getGrpcStorageOptions().toBuilder().build().getService()) {
306307

307308
BlobId id = BlobId.of("b", "o");
308-
ApiFuture<BlobDescriptor> futureBlobDescriptor = storage.getBlobDescriptor(id);
309+
ApiFuture<BlobDescriptor> futureBlobDescriptor =
310+
storage.getBlobDescriptor(id, BlobSourceOption.userProject("user-project"));
309311

310312
StorageException se =
311313
assertThrows(

0 commit comments

Comments
 (0)