Google Cloud Storage C++ Client 2.13.0
A C++ Client Library for Google Cloud Storage
Loading...
Searching...
No Matches
async_client.h
1// Copyright 2022 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_ASYNC_CLIENT_H
16#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_ASYNC_CLIENT_H
17
18#include "google/cloud/storage/internal/async_connection.h"
19#include "google/cloud/storage/internal/object_requests.h"
20#include "google/cloud/storage/version.h"
21#include "google/cloud/background_threads.h"
22#include "google/cloud/internal/group_options.h"
23#include "google/cloud/status_or.h"
24
25namespace google {
26namespace cloud {
27namespace storage_experimental {
28GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
29
30/**
31 * A client for Google Cloud Storage offering asynchronous operations.
32 *
33 * @note This class is experimental, it is subject to change without notice.
34 *
35 * @par Optional Request Options
36 * Most of the member functions in this class can receive optional request
37 * options. For example, the default when deleting an object is to delete the
38 * latest version:
39 *
40 * @code
41 * auto pending = gcs.DeleteObject("my-bucket", "my-object");
42 * @endcode
43 *
44 * Some applications may want to delete a specific version. In this case just
45 * provide the `Generation` request option:
46 *
47 * @code
48 * auto pending = gcs.DeleteObject(
49 * "my-bucket", "my-object", gcs::Generation(generation));
50 * @endcode
51 *
52 * Each function documents the types accepted as optional request options. These
53 * parameters can be specified in any order. Specifying a request option that is
54 * not applicable to a member function results in a compile-time error.
55 *
56 * All operations support the following common request options:
57 *
58 * - `Fields`: return a [partial response], which includes only the desired
59 * fields.
60 * - `QuotaUser`: attribute the request to this specific label for quota
61 * purposes.
62 * - `UserProject`: change the request costs (if applicable) to this GCP
63 * project.
64 * - `CustomHeader`: include a custom header with the request. These are
65 * typically used for testing, though they are sometimes helpful if
66 * environments where HTTPS traffic is mediated by a proxy.
67 * - `UserIp`: attribute the request to this specific IP address for quota
68 * purpose. Not recommended, prefer `QuotaUser` instead.
69 *
70 * [partial response]:
71 * https://cloud.google.com/storage/docs/json_api#partial-response
72 *
73 * @par Per-operation Overrides
74 *
75 * In addition to the request options, which are passed on to the service to
76 * modify the request, you can specify options that override the local behavior
77 * of the library. For example, you can override the local retry policy:
78 *
79 * @code
80 * auto pending = gcs.DeleteObject(
81 * "my-bucket", "my-object",
82 * google::cloud::Options{}
83 * .set<gcs::RetryPolicyOption>(
84 * gcs::LimitedErrorCountRetryPolicy(5).clone()));
85 * @endcode
86 *
87 * @par Retry, Backoff, and Idempotency Policies
88 *
89 * The library automatically retries requests that fail with transient errors,
90 * and follows the [recommended practice][exponential-backoff] to backoff
91 * between retries.
92 *
93 * The default policies are to continue retrying for up to 15 minutes, and to
94 * use truncated (at 5 minutes) exponential backoff, doubling the maximum
95 * backoff period between retries. Likewise, the idempotency policy is
96 * configured to retry all operations.
97 *
98 * The application can override these policies when constructing objects of this
99 * class. The documentation for the constructors shows examples of this in
100 * action.
101 *
102 * [exponential-backoff]:
103 * https://cloud.google.com/storage/docs/exponential-backoff
104 */
105class AsyncClient {
106 public:
107 ~AsyncClient() = default;
108
109 /**
110 * Reads the contents of an object.
111 *
112 * When satisfied, the returned future has the contents of the given object
113 * between @p offset and @p offset + @p limit (exclusive).
114 *
115 * Be aware that this will accumulate all the bytes in memory, you need to
116 * consider whether @p limit is too large for your deployment environment.
117 *
118 * @param bucket_name the name of the bucket that contains the object.
119 * @param object_name the name of the object to be read.
120 * @param offset where to begin reading from the object, results in an error
121 * if the offset is larger than the object
122 * @param limit how much data to read starting at @p offset
123 * @param options a list of optional query parameters and/or request headers.
124 * Valid types for this operation include `DisableCrc32cChecksum`,
125 * `DisableMD5Hash`, `EncryptionKey`, `Generation`, `IfGenerationMatch`,
126 * `IfGenerationNotMatch`, `IfMetagenerationMatch`,
127 * `IfMetagenerationNotMatch`, `UserProject`, and `AcceptEncoding`.
128 *
129 * @par Idempotency
130 * This is a read-only operation and is always idempotent.
131 */
132 template <typename... RequestOptions>
134 std::string const& bucket_name, std::string const& object_name,
135 std::int64_t offset, std::int64_t limit, RequestOptions&&... options) {
136 struct HasReadRange
137 : public absl::disjunction<
138 std::is_same<storage::ReadRange, RequestOptions>...> {};
139 struct HasReadFromOffset
140 : public absl::disjunction<
141 std::is_same<storage::ReadFromOffset, RequestOptions>...> {};
142 struct HasReadLast
143 : public absl::disjunction<
144 std::is_same<storage::ReadLast, RequestOptions>...> {};
145
146 static_assert(!HasReadRange::value,
147 "Cannot use `ReadRange()` as a request option in "
148 "`AsyncClient::ReadObject()`, use the `offset` and `limit` "
149 "parameters instead.");
150 static_assert(!HasReadFromOffset::value,
151 "Cannot use `ReadFromOffset()` as a request option in "
152 "`AsyncClient::ReadObject()`, use the `offset` and `limit` "
153 "parameters instead.");
154 static_assert(!HasReadLast::value,
155 "Cannot use `ReadLast()` as a request option in "
156 "`AsyncClient::ReadObject()`, use the `offset` and `limit` "
157 "parameters instead.");
158
159 google::cloud::internal::OptionsSpan const span(
160 SpanOptions(std::forward<Options>(options)...));
161 storage::internal::ReadObjectRangeRequest request(bucket_name, object_name);
162 request.set_multiple_options(std::forward<Options>(options)...,
163 storage::ReadRange(offset, offset + limit));
164 return connection_->AsyncReadObjectRange(std::move(request));
165 }
166
167 /**
168 * Composes existing objects into a new object in the same bucket.
169 *
170 * @param bucket_name the name of the bucket used for source object and
171 * destination object.
172 * @param source_objects objects used to compose `destination_object_name`.
173 * @param destination_object_name the composed object name.
174 * @param options a list of optional query parameters and/or request headers.
175 * Valid types for this operation include
176 * `DestinationPredefinedAcl`, `EncryptionKey`, `IfGenerationMatch`,
177 * `IfMetagenerationMatch`, `KmsKeyName`, `UserProject`, and
178 * `WithObjectMetadata`.
179 *
180 * @par Idempotency
181 * This operation is only idempotent if restricted by pre-conditions, in this
182 * case, `IfGenerationMatch`.
183 */
184 template <typename... Options>
186 std::string bucket_name,
187 std::vector<storage::ComposeSourceObject> source_objects,
188 std::string destination_object_name, Options&&... options) {
189 google::cloud::internal::OptionsSpan const span(
190 SpanOptions(std::forward<Options>(options)...));
191 storage::internal::ComposeObjectRequest request(
192 std::move(bucket_name), std::move(source_objects),
193 std::move(destination_object_name));
194 request.set_multiple_options(std::forward<Options>(options)...);
195 return connection_->AsyncComposeObject(request);
196 }
197
198 /**
199 * Deletes an object.
200 *
201 * @param bucket_name the name of the bucket that contains the object.
202 * @param object_name the name of the object to be deleted.
203 * @param options a list of optional query parameters and/or request headers.
204 * Valid types for this operation include `Generation`,
205 * `IfGenerationMatch`, `IfGenerationNotMatch`, `IfMetagenerationMatch`,
206 * `IfMetagenerationNotMatch`, and `UserProject`.
207 * See the class description for common request options.
208 *
209 * @par Idempotency
210 * This operation is only idempotent if:
211 * - restricted by pre-conditions, in this case, `IfGenerationMatch`
212 * - or, if it applies to only one object version via `Generation`.
213 */
214 template <typename... RequestOptions>
215 future<Status> DeleteObject(std::string const& bucket_name,
216 std::string const& object_name,
217 RequestOptions&&... options) {
218 google::cloud::internal::OptionsSpan const span(
219 SpanOptions(std::forward<RequestOptions>(options)...));
220 storage::internal::DeleteObjectRequest request(bucket_name, object_name);
221 request.set_multiple_options(std::forward<RequestOptions>(options)...);
222 return connection_->AsyncDeleteObject(std::move(request));
223 }
224
225 /**
226 * Starts a resumable upload.
227 *
228 * This creates an upload id, which later can be used to upload an object.
229 * [Resumable uploads][resumable-link] can continue, even if the program
230 * performing the upload needs to restart.
231 *
232 * @note When resuming uploads it is the application's responsibility to save
233 * the upload id to restart the upload later.
234 *
235 * For small uploads we recommend using `InsertObject`, consult
236 * [the documentation][how-to-upload-link] for details.
237 *
238 * @param bucket_name the name of the bucket that contains the object.
239 * @param object_name the name of the object to be read.
240 * @param options a list of optional query parameters and/or request headers.
241 * Valid types for this operation include `ContentEncoding`, `ContentType`,
242 * `Crc32cChecksumValue`, `DisableCrc32cChecksum`, `DisableMD5Hash`,
243 * `EncryptionKey`, `IfGenerationMatch`, `IfGenerationNotMatch`,
244 * `IfMetagenerationMatch`, `IfMetagenerationNotMatch`, `KmsKeyName`,
245 * `MD5HashValue`, `PredefinedAcl`, `Projection`, `UserProject`,
246 * `WithObjectMetadata`, `UploadContentLength`, `AutoFinalize`, and
247 * `UploadBufferSize`.
248 *
249 * @par Idempotency
250 * This operation is always idempotent. The only side-effect is the creation
251 * of a resumable upload id, which are automatically garbage collected after
252 * 7 days, and have no additional costs. Furthermore, this side-effect is
253 * not observable, as there is no way to list the current upload ids.
254 *
255 * @see [Resumable Uploads][resumable-link] for more information about
256 * resumable uploads.
257 *
258 * [resumable-link]: https://cloud.google.com/storage/docs/resumable-uploads
259 * [how-to-upload-link]:
260 * https://cloud.google.com/storage/docs/json_api/v1/how-tos/upload
261 */
262 template <typename... RequestOptions>
263 future<StatusOr<std::string>> StartResumableUpload(
264 std::string const& bucket_name, std::string const& object_name,
265 RequestOptions&&... options) {
266 struct HasUseResumableUploadSession
267 : public absl::disjunction<std::is_same<
268 storage::UseResumableUploadSession, RequestOptions>...> {};
269 static_assert(!HasUseResumableUploadSession::value,
270 "Cannot use `UseResumableUploadSession` as a request option "
271 "in `AsyncClient::StartResumableUpload()`. If you want to "
272 "resume the upload, simply use the existing upload id.");
273
274 google::cloud::internal::OptionsSpan const span(
275 SpanOptions(std::forward<Options>(options)...));
276 storage::internal::ResumableUploadRequest request(bucket_name, object_name);
277 request.set_multiple_options(std::forward<Options>(options)...);
278 return connection_->AsyncStartResumableWrite(std::move(request));
279 }
280
281 private:
283 explicit AsyncClient(
284 std::shared_ptr<google::cloud::BackgroundThreads> background,
285 std::shared_ptr<storage_internal::AsyncConnection> connection);
286
287 template <typename... RequestOptions>
288 google::cloud::Options SpanOptions(RequestOptions&&... o) const {
289 return google::cloud::internal::GroupOptions(
290 connection_->options(), std::forward<RequestOptions>(o)...);
291 }
292
293 std::shared_ptr<google::cloud::BackgroundThreads> background_;
294 std::shared_ptr<storage_internal::AsyncConnection> connection_;
295};
296
297// TODO(#7142) - expose a factory function / constructor consuming
298// std::shared_ptr<AsyncConnection> when we have a plan for mocking
299/// Creates a new GCS client exposing asynchronous APIs.
301
302GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
303} // namespace storage_experimental
304} // namespace cloud
305} // namespace google
306
307#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_ASYNC_CLIENT_H
friend friend class future
Represents the metadata for a Google Cloud Storage Object.
Definition: object_metadata.h:94
A client for Google Cloud Storage offering asynchronous operations.
Definition: async_client.h:105
future< Status > DeleteObject(std::string const &bucket_name, std::string const &object_name, RequestOptions &&... options)
Deletes an object.
Definition: async_client.h:215
future< AsyncReadObjectRangeResponse > ReadObject(std::string const &bucket_name, std::string const &object_name, std::int64_t offset, std::int64_t limit, RequestOptions &&... options)
Reads the contents of an object.
Definition: async_client.h:133
future< StatusOr< std::string > > StartResumableUpload(std::string const &bucket_name, std::string const &object_name, RequestOptions &&... options)
Starts a resumable upload.
Definition: async_client.h:263
friend AsyncClient MakeAsyncClient(Options opts)
Creates a new GCS client exposing asynchronous APIs.
future< StatusOr< storage::ObjectMetadata > > ComposeObject(std::string bucket_name, std::vector< storage::ComposeSourceObject > source_objects, std::string destination_object_name, Options &&... options)
Composes existing objects into a new object in the same bucket.
Definition: async_client.h:185
Contains experimental features for the GCS C++ Client Library.
Definition: async_client.h:27
Contains all the Google Cloud Storage C++ client APIs.
Definition: auto_finalize.h:24
Defines one of the source objects for a compose operation.
Definition: object_metadata.h:44
Download all the data from the GCS object starting at the given offset.
Definition: download_options.h:54
Read last N bytes from the GCS object.
Definition: download_options.h:65
Request only a portion of the GCS object in a ReadObject operation.
Definition: download_options.h:38
ReadRange(std::int64_t begin, std::int64_t end)
Definition: download_options.h:40
Request a resumable upload, restoring a previous session if necessary.
Definition: upload_options.h:38
Represents the response from reading a subset of an object.
Definition: async_object_responses.h:32