Skip to content

Commit c1f54cb

Browse files
committed
Merge remote-tracking branch 'upstream' into prepare-for-v3.0.0
2 parents 31f4e24 + 7595793 commit c1f54cb

File tree

65 files changed

+6987
-23
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+6987
-23
lines changed

ci/cloudbuild/builds/check-api.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ function check_abi() {
125125
# characters in the string "internal", and it should again be followed
126126
# by some other number indicating the length of the symbol within the
127127
# "internal" namespace. See: https://en.wikipedia.org/wiki/Name_mangling
128-
-skip-internal-symbols "(8internal|_internal|4absl|4grpc|6google8protobuf|6google3rpc)\d"
128+
-skip-internal-symbols "(8internal|_internal|4absl|4grpc|6google8protobuf|6google3rpc|20storage_experimental)\d"
129129
# We ignore the raw gRPC Stub class. The generated gRPC headers that
130130
# contain these classes are installed alongside our headers. When a new
131131
# RPC is added to a service, these classes gain a pure virtual method. Our

google/cloud/storage/async/client.cc

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,26 @@ future<StatusOr<google::storage::v2::Object>> AsyncClient::InsertObject(
4949
internal::MergeOptions(std::move(opts), connection_->options())});
5050
}
5151

52+
future<StatusOr<ObjectDescriptor>> AsyncClient::Open(
53+
BucketName const& bucket_name, std::string object_name, Options opts) {
54+
auto spec = google::storage::v2::BidiReadObjectSpec{};
55+
spec.set_bucket(bucket_name.FullName());
56+
spec.set_object(std::move(object_name));
57+
return Open(std::move(spec), std::move(opts));
58+
}
59+
60+
future<StatusOr<ObjectDescriptor>> AsyncClient::Open(
61+
google::storage::v2::BidiReadObjectSpec spec, Options opts) {
62+
return connection_
63+
->Open({std::move(spec),
64+
internal::MergeOptions(std::move(opts), connection_->options())})
65+
.then([](auto f) -> StatusOr<ObjectDescriptor> {
66+
auto connection = f.get();
67+
if (!connection) return std::move(connection).status();
68+
return ObjectDescriptor(*std::move(connection));
69+
});
70+
}
71+
5272
future<StatusOr<std::pair<AsyncReader, AsyncToken>>> AsyncClient::ReadObject(
5373
BucketName const& bucket_name, std::string object_name, Options opts) {
5474
auto request = google::storage::v2::ReadObjectRequest{};
@@ -92,6 +112,65 @@ future<StatusOr<ReadPayload>> AsyncClient::ReadObjectRange(
92112
internal::MergeOptions(std::move(opts), connection_->options())});
93113
}
94114

115+
future<StatusOr<std::pair<AsyncWriter, AsyncToken>>>
116+
AsyncClient::StartAppendableObjectUpload(BucketName const& bucket_name,
117+
std::string object_name,
118+
Options opts) {
119+
auto request = google::storage::v2::BidiWriteObjectRequest{};
120+
auto& resource = *request.mutable_write_object_spec()->mutable_resource();
121+
122+
resource.set_bucket(BucketName(bucket_name).FullName());
123+
resource.set_name(std::move(object_name));
124+
request.mutable_write_object_spec()->set_appendable(true);
125+
126+
return StartAppendableObjectUpload(std::move(request), std::move(opts));
127+
}
128+
129+
future<StatusOr<std::pair<AsyncWriter, AsyncToken>>>
130+
AsyncClient::StartAppendableObjectUpload(
131+
google::storage::v2::BidiWriteObjectRequest request, Options opts) {
132+
return connection_
133+
->StartAppendableObjectUpload(
134+
{std::move(request),
135+
internal::MergeOptions(std::move(opts), connection_->options())})
136+
.then([](auto f) -> StatusOr<std::pair<AsyncWriter, AsyncToken>> {
137+
auto w = f.get();
138+
if (!w) return std::move(w).status();
139+
auto t = absl::holds_alternative<google::storage::v2::Object>(
140+
(*w)->PersistedState())
141+
? AsyncToken()
142+
: storage_internal::MakeAsyncToken(w->get());
143+
return std::make_pair(AsyncWriter(*std::move(w)), std::move(t));
144+
});
145+
}
146+
147+
future<StatusOr<std::pair<AsyncWriter, AsyncToken>>>
148+
AsyncClient::ResumeAppendableObjectUpload(BucketName const& bucket_name,
149+
std::string object_name,
150+
std::int64_t generation,
151+
Options opts) {
152+
auto request = google::storage::v2::BidiWriteObjectRequest{};
153+
auto& append_object_spec = *request.mutable_append_object_spec();
154+
155+
append_object_spec.set_bucket(BucketName(bucket_name).FullName());
156+
append_object_spec.set_object(std::move(object_name));
157+
append_object_spec.set_generation(generation);
158+
159+
return connection_
160+
->ResumeAppendableObjectUpload(
161+
{std::move(request),
162+
internal::MergeOptions(std::move(opts), connection_->options())})
163+
.then([](auto f) -> StatusOr<std::pair<AsyncWriter, AsyncToken>> {
164+
auto w = f.get();
165+
if (!w) return std::move(w).status();
166+
auto t = absl::holds_alternative<google::storage::v2::Object>(
167+
(*w)->PersistedState())
168+
? AsyncToken()
169+
: storage_internal::MakeAsyncToken(w->get());
170+
return std::make_pair(AsyncWriter(*std::move(w)), std::move(t));
171+
});
172+
}
173+
95174
future<StatusOr<std::pair<AsyncWriter, AsyncToken>>>
96175
AsyncClient::StartBufferedUpload(BucketName const& bucket_name,
97176
std::string object_name, Options opts) {

google/cloud/storage/async/client.h

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "google/cloud/storage/async/bucket_name.h"
1919
#include "google/cloud/storage/async/connection.h"
20+
#include "google/cloud/storage/async/object_descriptor.h"
2021
#include "google/cloud/storage/async/reader.h"
2122
#include "google/cloud/storage/async/rewriter.h"
2223
#include "google/cloud/storage/async/token.h"
@@ -231,6 +232,41 @@ class AsyncClient {
231232
google::storage::v2::WriteObjectRequest request, WritePayload contents,
232233
Options opts = {});
233234

235+
/**
236+
* Open an object descriptor to perform one or more ranged reads.
237+
*
238+
* @par Idempotency
239+
* This is a read-only operation and is always idempotent. The operation will
240+
* retry until the descriptor is successfully created. The descriptor itself
241+
* will resume any incomplete ranged reads if the connection(s) are
242+
* interrupted. Use `ResumePolicyOption` and `ResumePolicy` to control this.
243+
*
244+
* @param bucket_name the name of the bucket that contains the object.
245+
* @param object_name the name of the object to be read.
246+
* @param opts options controlling the behavior of this RPC, for example
247+
* the application may change the retry policy.
248+
*/
249+
future<StatusOr<ObjectDescriptor>> Open(BucketName const& bucket_name,
250+
std::string object_name,
251+
Options opts = {});
252+
253+
/**
254+
* Open an object descriptor to perform one or more ranged reads.
255+
*
256+
* @par Idempotency
257+
* This is a read-only operation and is always idempotent. The operation will
258+
* retry until the descriptor is successfully created. The descriptor itself
259+
* will resume any incomplete ranged reads if the connection(s) are
260+
* interrupted. Use `ResumePolicyOption` and `ResumePolicy` to control this.
261+
*
262+
* @param spec the BidiReadObjectSpec to use when retrieving the
263+
* ObjectDescriptor.
264+
* @param opts options controlling the behavior of this RPC, for example
265+
* the application may change the retry policy.
266+
*/
267+
future<StatusOr<ObjectDescriptor>> Open(
268+
google::storage::v2::BidiReadObjectSpec spec, Options opts = {});
269+
234270
/**
235271
* A streaming download for the contents of an object.
236272
*
@@ -243,7 +279,7 @@ class AsyncClient {
243279
* @par Idempotency
244280
* This is a read-only operation and is always idempotent. Once the download
245281
* starts, this operation will automatically resume the download if is
246-
* interrupted. Use `ResumePolicyOption` and `ResumePolicy` to control this
282+
* interrupted. Use `ResumePolicyOption` and `ResumePolicy` to control this.
247283
*
248284
* @param bucket_name the name of the bucket that contains the object.
249285
* @param object_name the name of the object to be read.
@@ -334,10 +370,82 @@ class AsyncClient {
334370
google::storage::v2::ReadObjectRequest request, std::int64_t offset,
335371
std::int64_t limit, Options opts = {});
336372

373+
/*
374+
[start-appendable-object-upload]
375+
Initiates a [resumable upload][resumable-link] for an appendable object.
376+
377+
Appendable objects allow you to create an object and upload data to it
378+
incrementally until it is finalized. This means you can start an upload
379+
and append data to the object later.
380+
381+
You can finalize an appendable object in the first call itself by providing
382+
all the data in the initial upload. You can also explicitly Flush to ensure
383+
the data is persisted.
384+
385+
The recovery can be done from most transient errors, including an unexpected
386+
closure of the streaming RPC used for the upload.
387+
388+
@par Example
389+
@snippet storage_async_samples.cc start-appendable-object-upload
390+
391+
@par Idempotency
392+
This function is always treated as idempotent, and the library will
393+
automatically retry the function on transient errors.
394+
395+
[resumable-link]: https://cloud.google.com/storage/docs/resumable-uploads
396+
[start-appendable-object-upload]
397+
*/
398+
399+
/**
400+
* Starts a new resumable upload session for appendable objects and
401+
* automatic recovery from transient failures.
402+
*
403+
* @snippet{doc} async/client.h start-appendable-object-upload
404+
*
405+
* @param bucket_name the name of the bucket that contains the object.
406+
* @param object_name the name of the object to be read.
407+
* @param opts options controlling the behavior of this RPC, for example
408+
* the application may change the retry policy.
409+
*/
410+
future<StatusOr<std::pair<AsyncWriter, AsyncToken>>>
411+
StartAppendableObjectUpload(BucketName const& bucket_name,
412+
std::string object_name, Options opts = {});
413+
414+
/**
415+
* Starts a new resumable upload session for appendable objects and
416+
* automatic recovery from transient failures.
417+
*
418+
* @snippet{doc} async/client.h start-appendable-object-upload
419+
*
420+
* @param request the request contents, it must include the bucket name and
421+
* object names. Many other fields are optional.
422+
* @param opts options controlling the behavior of this RPC, for example
423+
* the application may change the retry policy.
424+
*/
425+
future<StatusOr<std::pair<AsyncWriter, AsyncToken>>>
426+
StartAppendableObjectUpload(
427+
google::storage::v2::BidiWriteObjectRequest request, Options opts = {});
428+
429+
/**
430+
* Resume a resumable upload session for appendable objects and automatic
431+
* recovery from transient failures.
432+
*
433+
* @param bucket_name the name of the bucket that contains the object.
434+
* @param object_name the name of the object to be uploaded.
435+
* @param generation the object generation to be uploaded.
436+
* @param opts options controlling the behaviour of this RPC, for example the
437+
* application may change the retry policy.
438+
*/
439+
future<StatusOr<std::pair<AsyncWriter, AsyncToken>>>
440+
ResumeAppendableObjectUpload(BucketName const& bucket_name,
441+
std::string object_name, std::int64_t generation,
442+
Options opts = {});
443+
337444
/*
338445
[start-buffered-upload-common]
339446
This function always uses [resumable uploads][resumable-link]. The objects
340447
returned by this function buffer data until it is persisted on the service.
448+
341449
If the buffer becomes full, they stop accepting new data until the service
342450
has persisted enough data.
343451

0 commit comments

Comments
 (0)