1 // Copyright 2018 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 //     http://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 #include "google/cloud/storage/internal/retry_client.h"
16 #include "google/cloud/storage/internal/raw_client_wrapper_utils.h"
17 #include "google/cloud/storage/internal/retry_object_read_source.h"
18 #include "google/cloud/storage/internal/retry_resumable_upload_session.h"
19 #include "absl/memory/memory.h"
20 #include <sstream>
21 #include <thread>
22 
23 // Define the defaults using a pre-processor macro, this allows the application
24 // developers to change the defaults for their application by compiling with
25 // different values.
26 #ifndef STORAGE_CLIENT_DEFAULT_MAXIMUM_RETRY_PERIOD
27 #define STORAGE_CLIENT_DEFAULT_MAXIMUM_RETRY_PERIOD std::chrono::minutes(15)
28 #endif  // STORAGE_CLIENT_DEFAULT_MAXIMUM_RETRY_PERIOD
29 
30 #ifndef STORAGE_CLIENT_DEFAULT_INITIAL_BACKOFF_DELAY
31 #define STORAGE_CLIENT_DEFAULT_INITIAL_BACKOFF_DELAY std::chrono::seconds(1)
32 #endif  // STORAGE_CLIENT_DEFAULT_INITIAL_BACKOFF_DELAY
33 
34 #ifndef STORAGE_CLIENT_DEFAULT_MAXIMUM_BACKOFF_DELAY
35 #define STORAGE_CLIENT_DEFAULT_MAXIMUM_BACKOFF_DELAY std::chrono::minutes(5)
36 #endif  // STORAGE_CLIENT_DEFAULT_MAXIMUM_BACKOFF_DELAY
37 
38 #ifndef STORAGE_CLIENT_DEFAULT_BACKOFF_SCALING
39 #define STORAGE_CLIENT_DEFAULT_BACKOFF_SCALING 2.0
40 #endif  //  STORAGE_CLIENT_DEFAULT_BACKOFF_SCALING
41 
42 namespace google {
43 namespace cloud {
44 namespace storage {
45 inline namespace STORAGE_CLIENT_NS {
46 namespace internal {
47 namespace {
48 
49 using ::google::cloud::storage::internal::raw_client_wrapper_utils::Signature;
50 
51 /**
52  * Calls a client operation with retries borrowing the RPC policies.
53  *
54  * @tparam MemberFunction the signature of the member function.
55  * @param client the storage::Client object to make the call through.
56  * @param retry_policy the policy controlling what failures are retryable, and
57  *     for how long we can retry
58  * @param backoff_policy the policy controlling how long to wait before
59  *     retrying.
60  * @param function the pointer to the member function to call.
61  * @param request an initialized request parameter for the call.
62  * @param error_message include this message in any exception or error log.
63  * @return the result from making the call;
64  * @throw std::exception with a description of the last error.
65  */
66 template <typename MemberFunction>
MakeCall(RetryPolicy & retry_policy,BackoffPolicy & backoff_policy,bool is_idempotent,RawClient & client,MemberFunction function,typename Signature<MemberFunction>::RequestType const & request,char const * error_message)67 typename Signature<MemberFunction>::ReturnType MakeCall(
68     RetryPolicy& retry_policy, BackoffPolicy& backoff_policy,
69     bool is_idempotent, RawClient& client, MemberFunction function,
70     typename Signature<MemberFunction>::RequestType const& request,
71     char const* error_message) {
72   Status last_status(StatusCode::kDeadlineExceeded,
73                      "Retry policy exhausted before first attempt was made.");
74   auto error = [&last_status](std::string const& msg) {
75     return Status(last_status.code(), msg);
76   };
77 
78   while (!retry_policy.IsExhausted()) {
79     auto result = (client.*function)(request);
80     if (result.ok()) {
81       return result;
82     }
83     last_status = std::move(result).status();
84     if (!is_idempotent) {
85       std::ostringstream os;
86       os << "Error in non-idempotent operation " << error_message << ": "
87          << last_status;
88       return error(std::move(os).str());
89     }
90     if (!retry_policy.OnFailure(last_status)) {
91       if (internal::StatusTraits::IsPermanentFailure(last_status)) {
92         // The last error cannot be retried, but it is not because the retry
93         // policy is exhausted, we call these "permanent errors", and they
94         // get a special message.
95         std::ostringstream os;
96         os << "Permanent error in " << error_message << ": " << last_status;
97         return error(std::move(os).str());
98       }
99       // Exit the loop immediately instead of sleeping before trying again.
100       break;
101     }
102     auto delay = backoff_policy.OnCompletion();
103     std::this_thread::sleep_for(delay);
104   }
105   std::ostringstream os;
106   os << "Retry policy exhausted in " << error_message << ": " << last_status;
107   return error(std::move(os).str());
108 }
109 }  // namespace
110 
RetryClient(std::shared_ptr<RawClient> client,DefaultPolicies)111 RetryClient::RetryClient(std::shared_ptr<RawClient> client, DefaultPolicies)
112     : client_(std::move(client)) {
113   retry_policy_prototype_ =
114       LimitedTimeRetryPolicy(STORAGE_CLIENT_DEFAULT_MAXIMUM_RETRY_PERIOD)
115           .clone();
116   backoff_policy_prototype_ =
117       ExponentialBackoffPolicy(STORAGE_CLIENT_DEFAULT_INITIAL_BACKOFF_DELAY,
118                                STORAGE_CLIENT_DEFAULT_MAXIMUM_BACKOFF_DELAY,
119                                STORAGE_CLIENT_DEFAULT_BACKOFF_SCALING)
120           .clone();
121   idempotency_policy_ = AlwaysRetryIdempotencyPolicy().clone();
122 }
123 
client_options() const124 ClientOptions const& RetryClient::client_options() const {
125   return client_->client_options();
126 }
127 
ListBuckets(ListBucketsRequest const & request)128 StatusOr<ListBucketsResponse> RetryClient::ListBuckets(
129     ListBucketsRequest const& request) {
130   auto retry_policy = retry_policy_prototype_->clone();
131   auto backoff_policy = backoff_policy_prototype_->clone();
132   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
133   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
134                   &RawClient::ListBuckets, request, __func__);
135 }
136 
CreateBucket(CreateBucketRequest const & request)137 StatusOr<BucketMetadata> RetryClient::CreateBucket(
138     CreateBucketRequest const& request) {
139   auto retry_policy = retry_policy_prototype_->clone();
140   auto backoff_policy = backoff_policy_prototype_->clone();
141   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
142   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
143                   &RawClient::CreateBucket, request, __func__);
144 }
145 
GetBucketMetadata(GetBucketMetadataRequest const & request)146 StatusOr<BucketMetadata> RetryClient::GetBucketMetadata(
147     GetBucketMetadataRequest const& request) {
148   auto retry_policy = retry_policy_prototype_->clone();
149   auto backoff_policy = backoff_policy_prototype_->clone();
150   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
151   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
152                   &RawClient::GetBucketMetadata, request, __func__);
153 }
154 
DeleteBucket(DeleteBucketRequest const & request)155 StatusOr<EmptyResponse> RetryClient::DeleteBucket(
156     DeleteBucketRequest const& request) {
157   auto retry_policy = retry_policy_prototype_->clone();
158   auto backoff_policy = backoff_policy_prototype_->clone();
159   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
160   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
161                   &RawClient::DeleteBucket, request, __func__);
162 }
163 
UpdateBucket(UpdateBucketRequest const & request)164 StatusOr<BucketMetadata> RetryClient::UpdateBucket(
165     UpdateBucketRequest const& request) {
166   auto retry_policy = retry_policy_prototype_->clone();
167   auto backoff_policy = backoff_policy_prototype_->clone();
168   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
169   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
170                   &RawClient::UpdateBucket, request, __func__);
171 }
172 
PatchBucket(PatchBucketRequest const & request)173 StatusOr<BucketMetadata> RetryClient::PatchBucket(
174     PatchBucketRequest const& request) {
175   auto retry_policy = retry_policy_prototype_->clone();
176   auto backoff_policy = backoff_policy_prototype_->clone();
177   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
178   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
179                   &RawClient::PatchBucket, request, __func__);
180 }
181 
GetBucketIamPolicy(GetBucketIamPolicyRequest const & request)182 StatusOr<IamPolicy> RetryClient::GetBucketIamPolicy(
183     GetBucketIamPolicyRequest const& request) {
184   auto retry_policy = retry_policy_prototype_->clone();
185   auto backoff_policy = backoff_policy_prototype_->clone();
186   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
187   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
188                   &RawClient::GetBucketIamPolicy, request, __func__);
189 }
190 
GetNativeBucketIamPolicy(GetBucketIamPolicyRequest const & request)191 StatusOr<NativeIamPolicy> RetryClient::GetNativeBucketIamPolicy(
192     GetBucketIamPolicyRequest const& request) {
193   auto retry_policy = retry_policy_prototype_->clone();
194   auto backoff_policy = backoff_policy_prototype_->clone();
195   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
196   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
197                   &RawClient::GetNativeBucketIamPolicy, request, __func__);
198 }
199 
SetBucketIamPolicy(SetBucketIamPolicyRequest const & request)200 StatusOr<IamPolicy> RetryClient::SetBucketIamPolicy(
201     SetBucketIamPolicyRequest const& request) {
202   auto retry_policy = retry_policy_prototype_->clone();
203   auto backoff_policy = backoff_policy_prototype_->clone();
204   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
205   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
206                   &RawClient::SetBucketIamPolicy, request, __func__);
207 }
208 
SetNativeBucketIamPolicy(SetNativeBucketIamPolicyRequest const & request)209 StatusOr<NativeIamPolicy> RetryClient::SetNativeBucketIamPolicy(
210     SetNativeBucketIamPolicyRequest const& request) {
211   auto retry_policy = retry_policy_prototype_->clone();
212   auto backoff_policy = backoff_policy_prototype_->clone();
213   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
214   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
215                   &RawClient::SetNativeBucketIamPolicy, request, __func__);
216 }
217 
218 StatusOr<TestBucketIamPermissionsResponse>
TestBucketIamPermissions(TestBucketIamPermissionsRequest const & request)219 RetryClient::TestBucketIamPermissions(
220     TestBucketIamPermissionsRequest const& request) {
221   auto retry_policy = retry_policy_prototype_->clone();
222   auto backoff_policy = backoff_policy_prototype_->clone();
223   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
224   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
225                   &RawClient::TestBucketIamPermissions, request, __func__);
226 }
227 
LockBucketRetentionPolicy(LockBucketRetentionPolicyRequest const & request)228 StatusOr<BucketMetadata> RetryClient::LockBucketRetentionPolicy(
229     LockBucketRetentionPolicyRequest const& request) {
230   auto retry_policy = retry_policy_prototype_->clone();
231   auto backoff_policy = backoff_policy_prototype_->clone();
232   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
233   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
234                   &RawClient::LockBucketRetentionPolicy, request, __func__);
235 }
236 
InsertObjectMedia(InsertObjectMediaRequest const & request)237 StatusOr<ObjectMetadata> RetryClient::InsertObjectMedia(
238     InsertObjectMediaRequest const& request) {
239   auto retry_policy = retry_policy_prototype_->clone();
240   auto backoff_policy = backoff_policy_prototype_->clone();
241   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
242   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
243                   &RawClient::InsertObjectMedia, request, __func__);
244 }
245 
CopyObject(CopyObjectRequest const & request)246 StatusOr<ObjectMetadata> RetryClient::CopyObject(
247     CopyObjectRequest const& request) {
248   auto retry_policy = retry_policy_prototype_->clone();
249   auto backoff_policy = backoff_policy_prototype_->clone();
250   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
251   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
252                   &RawClient::CopyObject, request, __func__);
253 }
254 
GetObjectMetadata(GetObjectMetadataRequest const & request)255 StatusOr<ObjectMetadata> RetryClient::GetObjectMetadata(
256     GetObjectMetadataRequest const& request) {
257   auto retry_policy = retry_policy_prototype_->clone();
258   auto backoff_policy = backoff_policy_prototype_->clone();
259   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
260   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
261                   &RawClient::GetObjectMetadata, request, __func__);
262 }
263 
ReadObjectNotWrapped(ReadObjectRangeRequest const & request,RetryPolicy & retry_policy,BackoffPolicy & backoff_policy)264 StatusOr<std::unique_ptr<ObjectReadSource>> RetryClient::ReadObjectNotWrapped(
265     ReadObjectRangeRequest const& request, RetryPolicy& retry_policy,
266     BackoffPolicy& backoff_policy) {
267   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
268   return MakeCall(retry_policy, backoff_policy, is_idempotent, *client_,
269                   &RawClient::ReadObject, request, __func__);
270 }
271 
ReadObject(ReadObjectRangeRequest const & request)272 StatusOr<std::unique_ptr<ObjectReadSource>> RetryClient::ReadObject(
273     ReadObjectRangeRequest const& request) {
274   auto retry_policy = retry_policy_prototype_->clone();
275   auto backoff_policy = backoff_policy_prototype_->clone();
276   auto child = ReadObjectNotWrapped(request, *retry_policy, *backoff_policy);
277   if (!child) {
278     return child;
279   }
280   auto self = shared_from_this();
281   return std::unique_ptr<ObjectReadSource>(new RetryObjectReadSource(
282       self, request, *std::move(child), std::move(retry_policy),
283       std::move(backoff_policy)));
284 }
285 
ListObjects(ListObjectsRequest const & request)286 StatusOr<ListObjectsResponse> RetryClient::ListObjects(
287     ListObjectsRequest const& request) {
288   auto retry_policy = retry_policy_prototype_->clone();
289   auto backoff_policy = backoff_policy_prototype_->clone();
290   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
291   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
292                   &RawClient::ListObjects, request, __func__);
293 }
294 
DeleteObject(DeleteObjectRequest const & request)295 StatusOr<EmptyResponse> RetryClient::DeleteObject(
296     DeleteObjectRequest const& request) {
297   auto retry_policy = retry_policy_prototype_->clone();
298   auto backoff_policy = backoff_policy_prototype_->clone();
299   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
300   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
301                   &RawClient::DeleteObject, request, __func__);
302 }
303 
UpdateObject(UpdateObjectRequest const & request)304 StatusOr<ObjectMetadata> RetryClient::UpdateObject(
305     UpdateObjectRequest const& request) {
306   auto retry_policy = retry_policy_prototype_->clone();
307   auto backoff_policy = backoff_policy_prototype_->clone();
308   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
309   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
310                   &RawClient::UpdateObject, request, __func__);
311 }
312 
PatchObject(PatchObjectRequest const & request)313 StatusOr<ObjectMetadata> RetryClient::PatchObject(
314     PatchObjectRequest const& request) {
315   auto retry_policy = retry_policy_prototype_->clone();
316   auto backoff_policy = backoff_policy_prototype_->clone();
317   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
318   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
319                   &RawClient::PatchObject, request, __func__);
320 }
321 
ComposeObject(ComposeObjectRequest const & request)322 StatusOr<ObjectMetadata> RetryClient::ComposeObject(
323     ComposeObjectRequest const& request) {
324   auto retry_policy = retry_policy_prototype_->clone();
325   auto backoff_policy = backoff_policy_prototype_->clone();
326   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
327   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
328                   &RawClient::ComposeObject, request, __func__);
329 }
330 
RewriteObject(RewriteObjectRequest const & request)331 StatusOr<RewriteObjectResponse> RetryClient::RewriteObject(
332     RewriteObjectRequest const& request) {
333   auto retry_policy = retry_policy_prototype_->clone();
334   auto backoff_policy = backoff_policy_prototype_->clone();
335   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
336   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
337                   &RawClient::RewriteObject, request, __func__);
338 }
339 
340 StatusOr<std::unique_ptr<ResumableUploadSession>>
CreateResumableSession(ResumableUploadRequest const & request)341 RetryClient::CreateResumableSession(ResumableUploadRequest const& request) {
342   auto retry_policy = retry_policy_prototype_->clone();
343   auto backoff_policy = backoff_policy_prototype_->clone();
344   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
345   auto result =
346       MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
347                &RawClient::CreateResumableSession, request, __func__);
348   if (!result.ok()) {
349     return result;
350   }
351 
352   return std::unique_ptr<ResumableUploadSession>(
353       absl::make_unique<RetryResumableUploadSession>(
354           std::move(result).value(), std::move(retry_policy),
355           std::move(backoff_policy)));
356 }
357 
358 StatusOr<std::unique_ptr<ResumableUploadSession>>
RestoreResumableSession(std::string const & request)359 RetryClient::RestoreResumableSession(std::string const& request) {
360   auto retry_policy = retry_policy_prototype_->clone();
361   auto backoff_policy = backoff_policy_prototype_->clone();
362   auto is_idempotent = true;
363   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
364                   &RawClient::RestoreResumableSession, request, __func__);
365 }
366 
DeleteResumableUpload(DeleteResumableUploadRequest const & request)367 StatusOr<EmptyResponse> RetryClient::DeleteResumableUpload(
368     DeleteResumableUploadRequest const& request) {
369   auto retry_policy = retry_policy_prototype_->clone();
370   auto backoff_policy = backoff_policy_prototype_->clone();
371   auto is_idempotent = true;
372   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
373                   &RawClient::DeleteResumableUpload, request, __func__);
374 }
375 
ListBucketAcl(ListBucketAclRequest const & request)376 StatusOr<ListBucketAclResponse> RetryClient::ListBucketAcl(
377     ListBucketAclRequest const& request) {
378   auto retry_policy = retry_policy_prototype_->clone();
379   auto backoff_policy = backoff_policy_prototype_->clone();
380   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
381   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
382                   &RawClient::ListBucketAcl, request, __func__);
383 }
384 
GetBucketAcl(GetBucketAclRequest const & request)385 StatusOr<BucketAccessControl> RetryClient::GetBucketAcl(
386     GetBucketAclRequest const& request) {
387   auto retry_policy = retry_policy_prototype_->clone();
388   auto backoff_policy = backoff_policy_prototype_->clone();
389   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
390   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
391                   &RawClient::GetBucketAcl, request, __func__);
392 }
393 
CreateBucketAcl(CreateBucketAclRequest const & request)394 StatusOr<BucketAccessControl> RetryClient::CreateBucketAcl(
395     CreateBucketAclRequest const& request) {
396   auto retry_policy = retry_policy_prototype_->clone();
397   auto backoff_policy = backoff_policy_prototype_->clone();
398   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
399   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
400                   &RawClient::CreateBucketAcl, request, __func__);
401 }
402 
DeleteBucketAcl(DeleteBucketAclRequest const & request)403 StatusOr<EmptyResponse> RetryClient::DeleteBucketAcl(
404     DeleteBucketAclRequest const& request) {
405   auto retry_policy = retry_policy_prototype_->clone();
406   auto backoff_policy = backoff_policy_prototype_->clone();
407   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
408   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
409                   &RawClient::DeleteBucketAcl, request, __func__);
410 }
411 
ListObjectAcl(ListObjectAclRequest const & request)412 StatusOr<ListObjectAclResponse> RetryClient::ListObjectAcl(
413     ListObjectAclRequest const& request) {
414   auto retry_policy = retry_policy_prototype_->clone();
415   auto backoff_policy = backoff_policy_prototype_->clone();
416   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
417   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
418                   &RawClient::ListObjectAcl, request, __func__);
419 }
420 
UpdateBucketAcl(UpdateBucketAclRequest const & request)421 StatusOr<BucketAccessControl> RetryClient::UpdateBucketAcl(
422     UpdateBucketAclRequest const& request) {
423   auto retry_policy = retry_policy_prototype_->clone();
424   auto backoff_policy = backoff_policy_prototype_->clone();
425   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
426   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
427                   &RawClient::UpdateBucketAcl, request, __func__);
428 }
429 
PatchBucketAcl(PatchBucketAclRequest const & request)430 StatusOr<BucketAccessControl> RetryClient::PatchBucketAcl(
431     PatchBucketAclRequest const& request) {
432   auto retry_policy = retry_policy_prototype_->clone();
433   auto backoff_policy = backoff_policy_prototype_->clone();
434   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
435   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
436                   &RawClient::PatchBucketAcl, request, __func__);
437 }
438 
CreateObjectAcl(CreateObjectAclRequest const & request)439 StatusOr<ObjectAccessControl> RetryClient::CreateObjectAcl(
440     CreateObjectAclRequest const& request) {
441   auto retry_policy = retry_policy_prototype_->clone();
442   auto backoff_policy = backoff_policy_prototype_->clone();
443   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
444   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
445                   &RawClient::CreateObjectAcl, request, __func__);
446 }
447 
DeleteObjectAcl(DeleteObjectAclRequest const & request)448 StatusOr<EmptyResponse> RetryClient::DeleteObjectAcl(
449     DeleteObjectAclRequest const& request) {
450   auto retry_policy = retry_policy_prototype_->clone();
451   auto backoff_policy = backoff_policy_prototype_->clone();
452   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
453   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
454                   &RawClient::DeleteObjectAcl, request, __func__);
455 }
456 
GetObjectAcl(GetObjectAclRequest const & request)457 StatusOr<ObjectAccessControl> RetryClient::GetObjectAcl(
458     GetObjectAclRequest const& request) {
459   auto retry_policy = retry_policy_prototype_->clone();
460   auto backoff_policy = backoff_policy_prototype_->clone();
461   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
462   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
463                   &RawClient::GetObjectAcl, request, __func__);
464 }
465 
UpdateObjectAcl(UpdateObjectAclRequest const & request)466 StatusOr<ObjectAccessControl> RetryClient::UpdateObjectAcl(
467     UpdateObjectAclRequest const& request) {
468   auto retry_policy = retry_policy_prototype_->clone();
469   auto backoff_policy = backoff_policy_prototype_->clone();
470   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
471   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
472                   &RawClient::UpdateObjectAcl, request, __func__);
473 }
474 
PatchObjectAcl(PatchObjectAclRequest const & request)475 StatusOr<ObjectAccessControl> RetryClient::PatchObjectAcl(
476     PatchObjectAclRequest const& request) {
477   auto retry_policy = retry_policy_prototype_->clone();
478   auto backoff_policy = backoff_policy_prototype_->clone();
479   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
480   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
481                   &RawClient::PatchObjectAcl, request, __func__);
482 }
483 
ListDefaultObjectAcl(ListDefaultObjectAclRequest const & request)484 StatusOr<ListDefaultObjectAclResponse> RetryClient::ListDefaultObjectAcl(
485     ListDefaultObjectAclRequest const& request) {
486   auto retry_policy = retry_policy_prototype_->clone();
487   auto backoff_policy = backoff_policy_prototype_->clone();
488   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
489   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
490                   &RawClient::ListDefaultObjectAcl, request, __func__);
491 }
492 
CreateDefaultObjectAcl(CreateDefaultObjectAclRequest const & request)493 StatusOr<ObjectAccessControl> RetryClient::CreateDefaultObjectAcl(
494     CreateDefaultObjectAclRequest const& request) {
495   auto retry_policy = retry_policy_prototype_->clone();
496   auto backoff_policy = backoff_policy_prototype_->clone();
497   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
498   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
499                   &RawClient::CreateDefaultObjectAcl, request, __func__);
500 }
501 
DeleteDefaultObjectAcl(DeleteDefaultObjectAclRequest const & request)502 StatusOr<EmptyResponse> RetryClient::DeleteDefaultObjectAcl(
503     DeleteDefaultObjectAclRequest const& request) {
504   auto retry_policy = retry_policy_prototype_->clone();
505   auto backoff_policy = backoff_policy_prototype_->clone();
506   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
507   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
508                   &RawClient::DeleteDefaultObjectAcl, request, __func__);
509 }
510 
GetDefaultObjectAcl(GetDefaultObjectAclRequest const & request)511 StatusOr<ObjectAccessControl> RetryClient::GetDefaultObjectAcl(
512     GetDefaultObjectAclRequest const& request) {
513   auto retry_policy = retry_policy_prototype_->clone();
514   auto backoff_policy = backoff_policy_prototype_->clone();
515   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
516   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
517                   &RawClient::GetDefaultObjectAcl, request, __func__);
518 }
519 
UpdateDefaultObjectAcl(UpdateDefaultObjectAclRequest const & request)520 StatusOr<ObjectAccessControl> RetryClient::UpdateDefaultObjectAcl(
521     UpdateDefaultObjectAclRequest const& request) {
522   auto retry_policy = retry_policy_prototype_->clone();
523   auto backoff_policy = backoff_policy_prototype_->clone();
524   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
525   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
526                   &RawClient::UpdateDefaultObjectAcl, request, __func__);
527 }
528 
PatchDefaultObjectAcl(PatchDefaultObjectAclRequest const & request)529 StatusOr<ObjectAccessControl> RetryClient::PatchDefaultObjectAcl(
530     PatchDefaultObjectAclRequest const& request) {
531   auto retry_policy = retry_policy_prototype_->clone();
532   auto backoff_policy = backoff_policy_prototype_->clone();
533   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
534   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
535                   &RawClient::PatchDefaultObjectAcl, request, __func__);
536 }
537 
GetServiceAccount(GetProjectServiceAccountRequest const & request)538 StatusOr<ServiceAccount> RetryClient::GetServiceAccount(
539     GetProjectServiceAccountRequest const& request) {
540   auto retry_policy = retry_policy_prototype_->clone();
541   auto backoff_policy = backoff_policy_prototype_->clone();
542   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
543   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
544                   &RawClient::GetServiceAccount, request, __func__);
545 }
546 
ListHmacKeys(ListHmacKeysRequest const & request)547 StatusOr<ListHmacKeysResponse> RetryClient::ListHmacKeys(
548     ListHmacKeysRequest const& request) {
549   auto retry_policy = retry_policy_prototype_->clone();
550   auto backoff_policy = backoff_policy_prototype_->clone();
551   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
552   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
553                   &RawClient::ListHmacKeys, request, __func__);
554 }
555 
CreateHmacKey(CreateHmacKeyRequest const & request)556 StatusOr<CreateHmacKeyResponse> RetryClient::CreateHmacKey(
557     CreateHmacKeyRequest const& request) {
558   auto retry_policy = retry_policy_prototype_->clone();
559   auto backoff_policy = backoff_policy_prototype_->clone();
560   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
561   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
562                   &RawClient::CreateHmacKey, request, __func__);
563 }
564 
DeleteHmacKey(DeleteHmacKeyRequest const & request)565 StatusOr<EmptyResponse> RetryClient::DeleteHmacKey(
566     DeleteHmacKeyRequest const& request) {
567   auto retry_policy = retry_policy_prototype_->clone();
568   auto backoff_policy = backoff_policy_prototype_->clone();
569   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
570   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
571                   &RawClient::DeleteHmacKey, request, __func__);
572 }
573 
GetHmacKey(GetHmacKeyRequest const & request)574 StatusOr<HmacKeyMetadata> RetryClient::GetHmacKey(
575     GetHmacKeyRequest const& request) {
576   auto retry_policy = retry_policy_prototype_->clone();
577   auto backoff_policy = backoff_policy_prototype_->clone();
578   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
579   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
580                   &RawClient::GetHmacKey, request, __func__);
581 }
582 
UpdateHmacKey(UpdateHmacKeyRequest const & request)583 StatusOr<HmacKeyMetadata> RetryClient::UpdateHmacKey(
584     UpdateHmacKeyRequest const& request) {
585   auto retry_policy = retry_policy_prototype_->clone();
586   auto backoff_policy = backoff_policy_prototype_->clone();
587   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
588   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
589                   &RawClient::UpdateHmacKey, request, __func__);
590 }
591 
SignBlob(SignBlobRequest const & request)592 StatusOr<SignBlobResponse> RetryClient::SignBlob(
593     SignBlobRequest const& request) {
594   auto retry_policy = retry_policy_prototype_->clone();
595   auto backoff_policy = backoff_policy_prototype_->clone();
596   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
597   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
598                   &RawClient::SignBlob, request, __func__);
599 }
600 
ListNotifications(ListNotificationsRequest const & request)601 StatusOr<ListNotificationsResponse> RetryClient::ListNotifications(
602     ListNotificationsRequest const& request) {
603   auto retry_policy = retry_policy_prototype_->clone();
604   auto backoff_policy = backoff_policy_prototype_->clone();
605   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
606   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
607                   &RawClient::ListNotifications, request, __func__);
608 }
609 
CreateNotification(CreateNotificationRequest const & request)610 StatusOr<NotificationMetadata> RetryClient::CreateNotification(
611     CreateNotificationRequest const& request) {
612   auto retry_policy = retry_policy_prototype_->clone();
613   auto backoff_policy = backoff_policy_prototype_->clone();
614   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
615   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
616                   &RawClient::CreateNotification, request, __func__);
617 }
618 
GetNotification(GetNotificationRequest const & request)619 StatusOr<NotificationMetadata> RetryClient::GetNotification(
620     GetNotificationRequest const& request) {
621   auto retry_policy = retry_policy_prototype_->clone();
622   auto backoff_policy = backoff_policy_prototype_->clone();
623   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
624   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
625                   &RawClient::GetNotification, request, __func__);
626 }
627 
DeleteNotification(DeleteNotificationRequest const & request)628 StatusOr<EmptyResponse> RetryClient::DeleteNotification(
629     DeleteNotificationRequest const& request) {
630   auto retry_policy = retry_policy_prototype_->clone();
631   auto backoff_policy = backoff_policy_prototype_->clone();
632   auto is_idempotent = idempotency_policy_->IsIdempotent(request);
633   return MakeCall(*retry_policy, *backoff_policy, is_idempotent, *client_,
634                   &RawClient::DeleteNotification, request, __func__);
635 }
636 
637 }  // namespace internal
638 }  // namespace STORAGE_CLIENT_NS
639 }  // namespace storage
640 }  // namespace cloud
641 }  // namespace google
642