Skip to content

Commit ae31163

Browse files
committed
chore: rename BlobDescriptor related classes to instead be ObjectReadSession and move implementation into StorageDataClient with blob as an adapter around the implementation of the v2/storage based protos
1 parent b1499d6 commit ae31163

23 files changed

Lines changed: 564 additions & 365 deletions

google-cloud-storage/clirr-ignored-differences.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@
124124
<difference>
125125
<differenceType>7012</differenceType>
126126
<className>com/google/cloud/storage/Storage</className>
127-
<method>com.google.api.core.ApiFuture getBlobDescriptor(com.google.cloud.storage.BlobId, com.google.cloud.storage.Storage$BlobSourceOption[])</method>
127+
<method>com.google.api.core.ApiFuture blobReadSession(com.google.cloud.storage.BlobId, com.google.cloud.storage.Storage$BlobSourceOption[])</method>
128128
</difference>
129129

130130
<difference>

google-cloud-storage/src/main/java/com/google/cloud/storage/BlobDescriptor.java renamed to google-cloud-storage/src/main/java/com/google/cloud/storage/BlobReadSession.java

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,10 @@
1717
package com.google.cloud.storage;
1818

1919
import com.google.api.core.ApiFuture;
20-
import com.google.protobuf.ByteString;
21-
import java.io.Closeable;
2220
import java.io.IOException;
2321
import java.nio.channels.ScatteringByteChannel;
2422

25-
/** Blob Descriptor is to blob, what File Descriptor is to a file */
26-
public interface BlobDescriptor extends IOAutoCloseable {
23+
public interface BlobReadSession extends IOAutoCloseable {
2724

2825
BlobInfo getBlobInfo();
2926

@@ -40,13 +37,4 @@ public interface BlobDescriptor extends IOAutoCloseable {
4037

4138
@Override
4239
void close() throws IOException;
43-
44-
interface ZeroCopySupport {
45-
interface DisposableByteString extends AutoCloseable, Closeable {
46-
ByteString byteString();
47-
48-
@Override
49-
void close() throws IOException;
50-
}
51-
}
5240
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright 2024 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.storage;
18+
19+
import com.google.api.core.ApiFuture;
20+
import com.google.api.core.ApiFutures;
21+
import com.google.common.annotations.VisibleForTesting;
22+
import com.google.common.util.concurrent.MoreExecutors;
23+
import java.io.IOException;
24+
import java.nio.channels.ScatteringByteChannel;
25+
26+
final class BlobReadSessionAdapter implements BlobReadSession {
27+
28+
@VisibleForTesting final ObjectReadSession session;
29+
30+
BlobReadSessionAdapter(ObjectReadSession session) {
31+
this.session = session;
32+
}
33+
34+
@Override
35+
public BlobInfo getBlobInfo() {
36+
return Conversions.grpc().blobInfo().decode(session.getResource());
37+
}
38+
39+
@Override
40+
public ApiFuture<byte[]> readRangeAsBytes(RangeSpec range) {
41+
return StorageException.coalesceAsync(session.readRangeAsBytes(range));
42+
}
43+
44+
@Override
45+
public ScatteringByteChannel readRangeAsChannel(RangeSpec range) {
46+
return session.readRangeAsChannel(range);
47+
}
48+
49+
@Override
50+
public void close() throws IOException {
51+
session.close();
52+
}
53+
54+
static ApiFuture<BlobReadSession> wrap(ApiFuture<ObjectReadSession> session) {
55+
return ApiFutures.transform(
56+
StorageException.coalesceAsync(session),
57+
BlobReadSessionAdapter::new,
58+
MoreExecutors.directExecutor());
59+
}
60+
}

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

Lines changed: 6 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,14 @@
3232
import com.google.api.core.ApiFuture;
3333
import com.google.api.core.ApiFutures;
3434
import com.google.api.core.BetaApi;
35-
import com.google.api.gax.core.InstantiatingExecutorProvider;
3635
import com.google.api.gax.grpc.GrpcCallContext;
3736
import com.google.api.gax.paging.AbstractPage;
3837
import com.google.api.gax.paging.Page;
39-
import com.google.api.gax.retrying.BasicResultRetryAlgorithm;
4038
import com.google.api.gax.retrying.ResultRetryAlgorithm;
4139
import com.google.api.gax.rpc.ApiException;
4240
import com.google.api.gax.rpc.ApiExceptions;
4341
import com.google.api.gax.rpc.ClientStreamingCallable;
4442
import com.google.api.gax.rpc.NotFoundException;
45-
import com.google.api.gax.rpc.OutOfRangeException;
4643
import com.google.api.gax.rpc.StatusCode;
4744
import com.google.api.gax.rpc.UnaryCallable;
4845
import com.google.cloud.BaseService;
@@ -52,14 +49,11 @@
5249
import com.google.cloud.storage.BlobWriteSessionConfig.WriterFactory;
5350
import com.google.cloud.storage.BufferedWritableByteChannelSession.BufferedWritableByteChannel;
5451
import com.google.cloud.storage.Conversions.Decoder;
55-
import com.google.cloud.storage.GrpcUtils.ZeroCopyBidiStreamingCallable;
5652
import com.google.cloud.storage.GrpcUtils.ZeroCopyServerStreamingCallable;
57-
import com.google.cloud.storage.Hasher.UncheckedChecksumMismatchException;
5853
import com.google.cloud.storage.HmacKey.HmacKeyMetadata;
5954
import com.google.cloud.storage.HmacKey.HmacKeyState;
6055
import com.google.cloud.storage.PostPolicyV4.PostConditionsV4;
6156
import com.google.cloud.storage.PostPolicyV4.PostFieldsV4;
62-
import com.google.cloud.storage.RetryContext.RetryContextProvider;
6357
import com.google.cloud.storage.Storage.ComposeRequest.SourceBlob;
6458
import com.google.cloud.storage.UnbufferedReadableByteChannelSession.UnbufferedReadableByteChannel;
6559
import com.google.cloud.storage.UnbufferedWritableByteChannelSession.UnbufferedWritableByteChannel;
@@ -86,7 +80,6 @@
8680
import com.google.iam.v1.SetIamPolicyRequest;
8781
import com.google.iam.v1.TestIamPermissionsRequest;
8882
import com.google.storage.v2.BidiReadObjectRequest;
89-
import com.google.storage.v2.BidiReadObjectResponse;
9083
import com.google.storage.v2.BidiReadObjectSpec;
9184
import com.google.storage.v2.BidiWriteObjectRequest;
9285
import com.google.storage.v2.BidiWriteObjectResponse;
@@ -111,7 +104,6 @@
111104
import com.google.storage.v2.RewriteObjectRequest;
112105
import com.google.storage.v2.RewriteResponse;
113106
import com.google.storage.v2.StorageClient;
114-
import com.google.storage.v2.StorageSettings;
115107
import com.google.storage.v2.UpdateBucketRequest;
116108
import com.google.storage.v2.UpdateObjectRequest;
117109
import com.google.storage.v2.WriteObjectRequest;
@@ -141,7 +133,6 @@
141133
import java.util.Spliterators.AbstractSpliterator;
142134
import java.util.concurrent.Callable;
143135
import java.util.concurrent.ExecutionException;
144-
import java.util.concurrent.ScheduledExecutorService;
145136
import java.util.concurrent.TimeUnit;
146137
import java.util.function.Consumer;
147138
import java.util.function.Predicate;
@@ -175,59 +166,34 @@ final class GrpcStorageImpl extends BaseService<StorageOptions>
175166
.collect(ImmutableSet.toImmutableSet())));
176167

177168
final StorageClient storageClient;
169+
final StorageDataClient storageDataClient;
178170
final ResponseContentLifecycleManager<ReadObjectResponse> responseContentLifecycleManager;
179-
final ResponseContentLifecycleManager<BidiReadObjectResponse> bidiResponseContentLifecycleManager;
180171
final WriterFactory writerFactory;
181172
final GrpcConversions codecs;
182173
final GrpcRetryAlgorithmManager retryAlgorithmManager;
183174
final SyntaxDecoders syntaxDecoders;
184-
final ScheduledExecutorService executor;
185175

186176
// workaround for https://github.com/googleapis/java-storage/issues/1736
187177
private final Opts<UserProject> defaultOpts;
188178
@Deprecated private final Supplier<ProjectId> defaultProjectId;
189-
private final RetryContextProvider retryContextProvider;
190179

191180
GrpcStorageImpl(
192181
GrpcStorageOptions options,
193182
StorageClient storageClient,
183+
StorageDataClient storageDataClient,
194184
ResponseContentLifecycleManager<ReadObjectResponse> responseContentLifecycleManager,
195-
ResponseContentLifecycleManager<BidiReadObjectResponse> bidiResponseContentLifecycleManager,
196185
WriterFactory writerFactory,
197186
Opts<UserProject> defaultOpts) {
198187
super(options);
199188
this.storageClient = storageClient;
189+
this.storageDataClient = storageDataClient;
200190
this.responseContentLifecycleManager = responseContentLifecycleManager;
201-
this.bidiResponseContentLifecycleManager = bidiResponseContentLifecycleManager;
202191
this.writerFactory = writerFactory;
203192
this.defaultOpts = defaultOpts;
204193
this.codecs = Conversions.grpc();
205194
this.retryAlgorithmManager = options.getRetryAlgorithmManager();
206195
this.syntaxDecoders = new SyntaxDecoders();
207196
this.defaultProjectId = Suppliers.memoize(() -> UnifiedOpts.projectId(options.getProjectId()));
208-
this.executor =
209-
Utils.firstNonNull(
210-
() -> {
211-
if (storageClient == null) {
212-
return null;
213-
}
214-
StorageSettings settings = storageClient.getSettings();
215-
if (settings == null) {
216-
return null;
217-
}
218-
return settings.getBackgroundExecutorProvider();
219-
},
220-
() -> {
221-
// TODO: if we make it to here, ensure we track the need to shutdown the executor
222-
// separate from StorageClient
223-
return InstantiatingExecutorProvider.newBuilder().build();
224-
})
225-
.getExecutor();
226-
retryContextProvider =
227-
RetryContext.providerFrom(
228-
executor,
229-
getOptions(),
230-
new ReadObjectRangeResultRetryAlgorithmDecorator(retryAlgorithmManager.idempotent()));
231197
}
232198

233199
@Override
@@ -1518,7 +1484,7 @@ public Blob moveBlob(MoveBlobRequest request) {
15181484
}
15191485

15201486
@Override
1521-
public ApiFuture<BlobDescriptor> getBlobDescriptor(BlobId id, BlobSourceOption... options) {
1487+
public ApiFuture<BlobReadSession> blobReadSession(BlobId id, BlobSourceOption... options) {
15221488
Opts<ObjectSourceOpt> opts = Opts.unwrap(options);
15231489
Object object = codecs.blobId().encode(id);
15241490

@@ -1534,13 +1500,10 @@ public ApiFuture<BlobDescriptor> getBlobDescriptor(BlobId id, BlobSourceOption..
15341500
opts.bidiReadObjectRequest().apply(b);
15351501
BidiReadObjectRequest req = b.build();
15361502

1537-
ZeroCopyBidiStreamingCallable<BidiReadObjectRequest, BidiReadObjectResponse> callable =
1538-
new ZeroCopyBidiStreamingCallable<>(
1539-
storageClient.bidiReadObjectCallable(), bidiResponseContentLifecycleManager);
1540-
15411503
GrpcCallContext context = opts.grpcMetadataMapper().apply(GrpcCallContext.createDefault());
1504+
ApiFuture<ObjectReadSession> session = storageDataClient.readSession(req, context);
15421505

1543-
return BlobDescriptorImpl.create(req, context, callable, executor, retryContextProvider);
1506+
return BlobReadSessionAdapter.wrap(session);
15441507
}
15451508

15461509
@Override
@@ -2084,22 +2047,4 @@ private ZeroCopyServerStreamingCallable<ReadObjectRequest, ReadObjectResponse> r
20842047
storageClient.readObjectCallable().withDefaultCallContext(grpcCallContext),
20852048
responseContentLifecycleManager);
20862049
}
2087-
2088-
private static class ReadObjectRangeResultRetryAlgorithmDecorator
2089-
extends BasicResultRetryAlgorithm<Object> {
2090-
2091-
private final ResultRetryAlgorithm<?> delegate;
2092-
2093-
private ReadObjectRangeResultRetryAlgorithmDecorator(ResultRetryAlgorithm<?> delegate) {
2094-
this.delegate = delegate;
2095-
}
2096-
2097-
@Override
2098-
public boolean shouldRetry(Throwable previousThrowable, Object previousResponse) {
2099-
// this is only retryable with read object range, not other requests
2100-
return previousThrowable instanceof UncheckedChecksumMismatchException
2101-
|| previousThrowable instanceof OutOfRangeException
2102-
|| delegate.shouldRetry(StorageException.coalesce(previousThrowable), null);
2103-
}
2104-
}
21052050
}

0 commit comments

Comments
 (0)