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/idempotency_policy.h"
16 #include "absl/memory/memory.h"
17
18 namespace google {
19 namespace cloud {
20 namespace storage {
21 inline namespace STORAGE_CLIENT_NS {
clone() const22 std::unique_ptr<IdempotencyPolicy> AlwaysRetryIdempotencyPolicy::clone() const {
23 return absl::make_unique<AlwaysRetryIdempotencyPolicy>(*this);
24 }
25
IsIdempotent(internal::ListBucketsRequest const &) const26 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
27 internal::ListBucketsRequest const&) const {
28 return true;
29 }
IsIdempotent(internal::CreateBucketRequest const &) const30 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
31 internal::CreateBucketRequest const&) const {
32 return true;
33 }
IsIdempotent(internal::GetBucketMetadataRequest const &) const34 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
35 internal::GetBucketMetadataRequest const&) const {
36 return true;
37 }
IsIdempotent(internal::DeleteBucketRequest const &) const38 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
39 internal::DeleteBucketRequest const&) const {
40 return true;
41 }
IsIdempotent(internal::UpdateBucketRequest const &) const42 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
43 internal::UpdateBucketRequest const&) const {
44 return true;
45 }
IsIdempotent(internal::PatchBucketRequest const &) const46 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
47 internal::PatchBucketRequest const&) const {
48 return true;
49 }
IsIdempotent(internal::GetBucketIamPolicyRequest const &) const50 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
51 internal::GetBucketIamPolicyRequest const&) const {
52 return true;
53 }
IsIdempotent(internal::SetBucketIamPolicyRequest const &) const54 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
55 internal::SetBucketIamPolicyRequest const&) const {
56 return true;
57 }
IsIdempotent(internal::SetNativeBucketIamPolicyRequest const &) const58 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
59 internal::SetNativeBucketIamPolicyRequest const&) const {
60 return true;
61 }
IsIdempotent(internal::TestBucketIamPermissionsRequest const &) const62 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
63 internal::TestBucketIamPermissionsRequest const&) const {
64 return true;
65 }
IsIdempotent(internal::LockBucketRetentionPolicyRequest const &) const66 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
67 internal::LockBucketRetentionPolicyRequest const&) const {
68 return true;
69 }
70
IsIdempotent(internal::InsertObjectMediaRequest const &) const71 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
72 internal::InsertObjectMediaRequest const&) const {
73 return true;
74 }
IsIdempotent(internal::CopyObjectRequest const &) const75 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
76 internal::CopyObjectRequest const&) const {
77 return true;
78 }
IsIdempotent(internal::GetObjectMetadataRequest const &) const79 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
80 internal::GetObjectMetadataRequest const&) const {
81 return true;
82 }
IsIdempotent(internal::ReadObjectRangeRequest const &) const83 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
84 internal::ReadObjectRangeRequest const&) const {
85 return true;
86 }
IsIdempotent(internal::ListObjectsRequest const &) const87 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
88 internal::ListObjectsRequest const&) const {
89 return true;
90 }
IsIdempotent(internal::DeleteObjectRequest const &) const91 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
92 internal::DeleteObjectRequest const&) const {
93 return true;
94 }
IsIdempotent(internal::UpdateObjectRequest const &) const95 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
96 internal::UpdateObjectRequest const&) const {
97 return true;
98 }
IsIdempotent(internal::PatchObjectRequest const &) const99 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
100 internal::PatchObjectRequest const&) const {
101 return true;
102 }
IsIdempotent(internal::ComposeObjectRequest const &) const103 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
104 internal::ComposeObjectRequest const&) const {
105 return true;
106 }
IsIdempotent(internal::RewriteObjectRequest const &) const107 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
108 internal::RewriteObjectRequest const&) const {
109 return true;
110 }
IsIdempotent(internal::ResumableUploadRequest const &) const111 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
112 internal::ResumableUploadRequest const&) const {
113 return true;
114 }
IsIdempotent(internal::UploadChunkRequest const &) const115 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
116 internal::UploadChunkRequest const&) const {
117 return true;
118 }
119
IsIdempotent(internal::ListBucketAclRequest const &) const120 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
121 internal::ListBucketAclRequest const&) const {
122 return true;
123 }
IsIdempotent(internal::CreateBucketAclRequest const &) const124 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
125 internal::CreateBucketAclRequest const&) const {
126 return true;
127 }
IsIdempotent(internal::DeleteBucketAclRequest const &) const128 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
129 internal::DeleteBucketAclRequest const&) const {
130 return true;
131 }
IsIdempotent(internal::GetBucketAclRequest const &) const132 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
133 internal::GetBucketAclRequest const&) const {
134 return true;
135 }
IsIdempotent(internal::UpdateBucketAclRequest const &) const136 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
137 internal::UpdateBucketAclRequest const&) const {
138 return true;
139 }
IsIdempotent(internal::PatchBucketAclRequest const &) const140 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
141 internal::PatchBucketAclRequest const&) const {
142 return true;
143 }
144
IsIdempotent(internal::ListObjectAclRequest const &) const145 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
146 internal::ListObjectAclRequest const&) const {
147 return true;
148 }
IsIdempotent(internal::CreateObjectAclRequest const &) const149 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
150 internal::CreateObjectAclRequest const&) const {
151 return true;
152 }
IsIdempotent(internal::DeleteObjectAclRequest const &) const153 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
154 internal::DeleteObjectAclRequest const&) const {
155 return true;
156 }
IsIdempotent(internal::GetObjectAclRequest const &) const157 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
158 internal::GetObjectAclRequest const&) const {
159 return true;
160 }
IsIdempotent(internal::UpdateObjectAclRequest const &) const161 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
162 internal::UpdateObjectAclRequest const&) const {
163 return true;
164 }
IsIdempotent(internal::PatchObjectAclRequest const &) const165 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
166 internal::PatchObjectAclRequest const&) const {
167 return true;
168 }
169
IsIdempotent(internal::ListDefaultObjectAclRequest const &) const170 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
171 internal::ListDefaultObjectAclRequest const&) const {
172 return true;
173 }
IsIdempotent(internal::CreateDefaultObjectAclRequest const &) const174 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
175 internal::CreateDefaultObjectAclRequest const&) const {
176 return true;
177 }
IsIdempotent(internal::DeleteDefaultObjectAclRequest const &) const178 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
179 internal::DeleteDefaultObjectAclRequest const&) const {
180 return true;
181 }
IsIdempotent(internal::GetDefaultObjectAclRequest const &) const182 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
183 internal::GetDefaultObjectAclRequest const&) const {
184 return true;
185 }
IsIdempotent(internal::UpdateDefaultObjectAclRequest const &) const186 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
187 internal::UpdateDefaultObjectAclRequest const&) const {
188 return true;
189 }
IsIdempotent(internal::PatchDefaultObjectAclRequest const &) const190 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
191 internal::PatchDefaultObjectAclRequest const&) const {
192 return true;
193 }
194
IsIdempotent(internal::GetProjectServiceAccountRequest const &) const195 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
196 internal::GetProjectServiceAccountRequest const&) const {
197 return true;
198 }
IsIdempotent(internal::ListHmacKeysRequest const &) const199 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
200 internal::ListHmacKeysRequest const&) const {
201 return true;
202 }
IsIdempotent(internal::CreateHmacKeyRequest const &) const203 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
204 internal::CreateHmacKeyRequest const&) const {
205 return true;
206 }
IsIdempotent(internal::DeleteHmacKeyRequest const &) const207 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
208 internal::DeleteHmacKeyRequest const&) const {
209 return true;
210 }
IsIdempotent(internal::GetHmacKeyRequest const &) const211 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
212 internal::GetHmacKeyRequest const&) const {
213 return true;
214 }
IsIdempotent(internal::UpdateHmacKeyRequest const &) const215 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
216 internal::UpdateHmacKeyRequest const&) const {
217 return true;
218 }
IsIdempotent(internal::SignBlobRequest const &) const219 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
220 internal::SignBlobRequest const&) const {
221 return true;
222 }
223
IsIdempotent(internal::ListNotificationsRequest const &) const224 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
225 internal::ListNotificationsRequest const&) const {
226 return true;
227 }
IsIdempotent(internal::CreateNotificationRequest const &) const228 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
229 internal::CreateNotificationRequest const&) const {
230 return true;
231 }
IsIdempotent(internal::GetNotificationRequest const &) const232 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
233 internal::GetNotificationRequest const&) const {
234 return true;
235 }
IsIdempotent(internal::DeleteNotificationRequest const &) const236 bool AlwaysRetryIdempotencyPolicy::IsIdempotent(
237 internal::DeleteNotificationRequest const&) const {
238 return true;
239 }
240
clone() const241 std::unique_ptr<IdempotencyPolicy> StrictIdempotencyPolicy::clone() const {
242 return absl::make_unique<StrictIdempotencyPolicy>(*this);
243 }
244
IsIdempotent(internal::ListBucketsRequest const &) const245 bool StrictIdempotencyPolicy::IsIdempotent(
246 internal::ListBucketsRequest const&) const {
247 // Read operations are always idempotent.
248 return true;
249 }
250
IsIdempotent(internal::CreateBucketRequest const &) const251 bool StrictIdempotencyPolicy::IsIdempotent(
252 internal::CreateBucketRequest const&) const {
253 // Creating a bucket is idempotent because you cannot create a new version
254 // of a bucket, it succeeds only once.
255 return true;
256 }
257
IsIdempotent(internal::GetBucketMetadataRequest const &) const258 bool StrictIdempotencyPolicy::IsIdempotent(
259 internal::GetBucketMetadataRequest const&) const {
260 // Read operations are always idempotent.
261 return true;
262 }
263
IsIdempotent(internal::DeleteBucketRequest const & request) const264 bool StrictIdempotencyPolicy::IsIdempotent(
265 internal::DeleteBucketRequest const& request) const {
266 return (request.HasOption<IfMatchEtag>() ||
267 request.HasOption<IfMetagenerationMatch>());
268 }
269
IsIdempotent(internal::UpdateBucketRequest const & request) const270 bool StrictIdempotencyPolicy::IsIdempotent(
271 internal::UpdateBucketRequest const& request) const {
272 return (request.HasOption<IfMatchEtag>() ||
273 request.HasOption<IfMetagenerationMatch>());
274 }
275
IsIdempotent(internal::PatchBucketRequest const & request) const276 bool StrictIdempotencyPolicy::IsIdempotent(
277 internal::PatchBucketRequest const& request) const {
278 return (request.HasOption<IfMatchEtag>() ||
279 request.HasOption<IfMetagenerationMatch>());
280 }
281
IsIdempotent(internal::GetBucketIamPolicyRequest const &) const282 bool StrictIdempotencyPolicy::IsIdempotent(
283 internal::GetBucketIamPolicyRequest const&) const {
284 return true;
285 }
286
IsIdempotent(internal::SetBucketIamPolicyRequest const & request) const287 bool StrictIdempotencyPolicy::IsIdempotent(
288 internal::SetBucketIamPolicyRequest const& request) const {
289 return request.HasOption<IfMatchEtag>();
290 }
291
IsIdempotent(internal::SetNativeBucketIamPolicyRequest const & request) const292 bool StrictIdempotencyPolicy::IsIdempotent(
293 internal::SetNativeBucketIamPolicyRequest const& request) const {
294 return request.HasOption<IfMatchEtag>();
295 }
296
IsIdempotent(internal::TestBucketIamPermissionsRequest const &) const297 bool StrictIdempotencyPolicy::IsIdempotent(
298 internal::TestBucketIamPermissionsRequest const&) const {
299 return true;
300 }
301
IsIdempotent(internal::LockBucketRetentionPolicyRequest const &) const302 bool StrictIdempotencyPolicy::IsIdempotent(
303 internal::LockBucketRetentionPolicyRequest const&) const {
304 // This request type always requires a metageneration pre-condition.
305 return true;
306 }
307
IsIdempotent(internal::InsertObjectMediaRequest const & request) const308 bool StrictIdempotencyPolicy::IsIdempotent(
309 internal::InsertObjectMediaRequest const& request) const {
310 return request.HasOption<IfGenerationMatch>();
311 }
312
IsIdempotent(internal::CopyObjectRequest const & request) const313 bool StrictIdempotencyPolicy::IsIdempotent(
314 internal::CopyObjectRequest const& request) const {
315 // Only the pre-conditions on the destination matter. If they are not set, it
316 // is possible for the request to succeed more than once, even if the source
317 // pre-conditions are set. If they are set, the operation can only succeed
318 // once, but the results may be different.
319 return request.HasOption<IfGenerationMatch>();
320 }
321
IsIdempotent(internal::GetObjectMetadataRequest const &) const322 bool StrictIdempotencyPolicy::IsIdempotent(
323 internal::GetObjectMetadataRequest const&) const {
324 return true;
325 }
326
IsIdempotent(internal::ReadObjectRangeRequest const &) const327 bool StrictIdempotencyPolicy::IsIdempotent(
328 internal::ReadObjectRangeRequest const&) const {
329 return true;
330 }
331
IsIdempotent(internal::ListObjectsRequest const &) const332 bool StrictIdempotencyPolicy::IsIdempotent(
333 internal::ListObjectsRequest const&) const {
334 return true;
335 }
336
IsIdempotent(internal::DeleteObjectRequest const & request) const337 bool StrictIdempotencyPolicy::IsIdempotent(
338 internal::DeleteObjectRequest const& request) const {
339 return request.HasOption<Generation>() ||
340 request.HasOption<IfGenerationMatch>();
341 }
342
IsIdempotent(internal::UpdateObjectRequest const & request) const343 bool StrictIdempotencyPolicy::IsIdempotent(
344 internal::UpdateObjectRequest const& request) const {
345 return request.HasOption<IfMatchEtag>() ||
346 request.HasOption<IfMetagenerationMatch>();
347 }
348
IsIdempotent(internal::PatchObjectRequest const & request) const349 bool StrictIdempotencyPolicy::IsIdempotent(
350 internal::PatchObjectRequest const& request) const {
351 return request.HasOption<IfMatchEtag>() ||
352 request.HasOption<IfMetagenerationMatch>();
353 }
354
IsIdempotent(internal::ComposeObjectRequest const & request) const355 bool StrictIdempotencyPolicy::IsIdempotent(
356 internal::ComposeObjectRequest const& request) const {
357 // Only the pre-conditions on the destination matter. If they are not set, it
358 // is possible for the request to succeed more than once, even if the source
359 // pre-conditions are set. If they are set, the operation can only succeed
360 // once, but the results may be different.
361 return request.HasOption<IfGenerationMatch>();
362 }
363
IsIdempotent(internal::RewriteObjectRequest const & request) const364 bool StrictIdempotencyPolicy::IsIdempotent(
365 internal::RewriteObjectRequest const& request) const {
366 // Only the pre-conditions on the destination matter. If they are not set, it
367 // is possible for the request to succeed more than once, even if the source
368 // pre-conditions are set. If they are set, the operation can only succeed
369 // once, but the results may be different.
370 return request.HasOption<IfGenerationMatch>();
371 }
372
IsIdempotent(internal::ResumableUploadRequest const & request) const373 bool StrictIdempotencyPolicy::IsIdempotent(
374 internal::ResumableUploadRequest const& request) const {
375 // Only the pre-conditions on the destination matter. If they are not set, it
376 // is possible for the request to succeed more than once, even if the source
377 // pre-conditions are set. If they are set, the operation can only succeed
378 // once, but the results may be different.
379 return request.HasOption<IfGenerationMatch>();
380 }
381
IsIdempotent(internal::UploadChunkRequest const &) const382 bool StrictIdempotencyPolicy::IsIdempotent(
383 internal::UploadChunkRequest const&) const {
384 return true;
385 }
386
IsIdempotent(internal::ListBucketAclRequest const &) const387 bool StrictIdempotencyPolicy::IsIdempotent(
388 internal::ListBucketAclRequest const&) const {
389 return true;
390 }
391
IsIdempotent(internal::CreateBucketAclRequest const & request) const392 bool StrictIdempotencyPolicy::IsIdempotent(
393 internal::CreateBucketAclRequest const& request) const {
394 return request.HasOption<IfMatchEtag>();
395 }
396
IsIdempotent(internal::DeleteBucketAclRequest const & request) const397 bool StrictIdempotencyPolicy::IsIdempotent(
398 internal::DeleteBucketAclRequest const& request) const {
399 return request.HasOption<IfMatchEtag>();
400 }
401
IsIdempotent(internal::GetBucketAclRequest const &) const402 bool StrictIdempotencyPolicy::IsIdempotent(
403 internal::GetBucketAclRequest const&) const {
404 return true;
405 }
406
IsIdempotent(internal::UpdateBucketAclRequest const & request) const407 bool StrictIdempotencyPolicy::IsIdempotent(
408 internal::UpdateBucketAclRequest const& request) const {
409 return request.HasOption<IfMatchEtag>();
410 }
411
IsIdempotent(internal::PatchBucketAclRequest const & request) const412 bool StrictIdempotencyPolicy::IsIdempotent(
413 internal::PatchBucketAclRequest const& request) const {
414 return request.HasOption<IfMatchEtag>();
415 }
416
IsIdempotent(internal::ListObjectAclRequest const &) const417 bool StrictIdempotencyPolicy::IsIdempotent(
418 internal::ListObjectAclRequest const&) const {
419 return true;
420 }
421
IsIdempotent(internal::CreateObjectAclRequest const & request) const422 bool StrictIdempotencyPolicy::IsIdempotent(
423 internal::CreateObjectAclRequest const& request) const {
424 return request.HasOption<IfMatchEtag>();
425 }
426
IsIdempotent(internal::DeleteObjectAclRequest const & request) const427 bool StrictIdempotencyPolicy::IsIdempotent(
428 internal::DeleteObjectAclRequest const& request) const {
429 return request.HasOption<IfMatchEtag>();
430 }
431
IsIdempotent(internal::GetObjectAclRequest const &) const432 bool StrictIdempotencyPolicy::IsIdempotent(
433 internal::GetObjectAclRequest const&) const {
434 return true;
435 }
436
IsIdempotent(internal::UpdateObjectAclRequest const & request) const437 bool StrictIdempotencyPolicy::IsIdempotent(
438 internal::UpdateObjectAclRequest const& request) const {
439 return request.HasOption<IfMatchEtag>();
440 }
441
IsIdempotent(internal::PatchObjectAclRequest const & request) const442 bool StrictIdempotencyPolicy::IsIdempotent(
443 internal::PatchObjectAclRequest const& request) const {
444 return request.HasOption<IfMatchEtag>();
445 }
446
IsIdempotent(internal::ListDefaultObjectAclRequest const &) const447 bool StrictIdempotencyPolicy::IsIdempotent(
448 internal::ListDefaultObjectAclRequest const&) const {
449 return true;
450 }
451
IsIdempotent(internal::CreateDefaultObjectAclRequest const & request) const452 bool StrictIdempotencyPolicy::IsIdempotent(
453 internal::CreateDefaultObjectAclRequest const& request) const {
454 return request.HasOption<IfMatchEtag>();
455 }
456
IsIdempotent(internal::DeleteDefaultObjectAclRequest const & request) const457 bool StrictIdempotencyPolicy::IsIdempotent(
458 internal::DeleteDefaultObjectAclRequest const& request) const {
459 return request.HasOption<IfMatchEtag>();
460 }
461
IsIdempotent(internal::GetDefaultObjectAclRequest const &) const462 bool StrictIdempotencyPolicy::IsIdempotent(
463 internal::GetDefaultObjectAclRequest const&) const {
464 return true;
465 }
466
IsIdempotent(internal::UpdateDefaultObjectAclRequest const & request) const467 bool StrictIdempotencyPolicy::IsIdempotent(
468 internal::UpdateDefaultObjectAclRequest const& request) const {
469 return request.HasOption<IfMatchEtag>();
470 }
471
IsIdempotent(internal::PatchDefaultObjectAclRequest const & request) const472 bool StrictIdempotencyPolicy::IsIdempotent(
473 internal::PatchDefaultObjectAclRequest const& request) const {
474 return request.HasOption<IfMatchEtag>();
475 }
476
IsIdempotent(internal::GetProjectServiceAccountRequest const &) const477 bool StrictIdempotencyPolicy::IsIdempotent(
478 internal::GetProjectServiceAccountRequest const&) const {
479 return true;
480 }
481
IsIdempotent(internal::ListHmacKeysRequest const &) const482 bool StrictIdempotencyPolicy::IsIdempotent(
483 internal::ListHmacKeysRequest const&) const {
484 return true;
485 }
486
IsIdempotent(internal::CreateHmacKeyRequest const &) const487 bool StrictIdempotencyPolicy::IsIdempotent(
488 internal::CreateHmacKeyRequest const&) const {
489 return false;
490 }
491
IsIdempotent(internal::DeleteHmacKeyRequest const &) const492 bool StrictIdempotencyPolicy::IsIdempotent(
493 internal::DeleteHmacKeyRequest const&) const {
494 return true;
495 }
496
IsIdempotent(internal::GetHmacKeyRequest const &) const497 bool StrictIdempotencyPolicy::IsIdempotent(
498 internal::GetHmacKeyRequest const&) const {
499 return true;
500 }
501
IsIdempotent(internal::UpdateHmacKeyRequest const & request) const502 bool StrictIdempotencyPolicy::IsIdempotent(
503 internal::UpdateHmacKeyRequest const& request) const {
504 // The plan of record is to support `If-Match-Etag` headers *and* the `etag`
505 // attribute on the payload as preconditions for `HmacKeys: update`.
506 return !request.resource().etag().empty() || request.HasOption<IfMatchEtag>();
507 }
508
IsIdempotent(internal::SignBlobRequest const &) const509 bool StrictIdempotencyPolicy::IsIdempotent(
510 internal::SignBlobRequest const&) const {
511 return true;
512 }
513
IsIdempotent(internal::ListNotificationsRequest const &) const514 bool StrictIdempotencyPolicy::IsIdempotent(
515 internal::ListNotificationsRequest const&) const {
516 return true;
517 }
518
IsIdempotent(internal::CreateNotificationRequest const &) const519 bool StrictIdempotencyPolicy::IsIdempotent(
520 internal::CreateNotificationRequest const&) const {
521 return true;
522 }
523
IsIdempotent(internal::GetNotificationRequest const &) const524 bool StrictIdempotencyPolicy::IsIdempotent(
525 internal::GetNotificationRequest const&) const {
526 return true;
527 }
528
IsIdempotent(internal::DeleteNotificationRequest const &) const529 bool StrictIdempotencyPolicy::IsIdempotent(
530 internal::DeleteNotificationRequest const&) const {
531 return true;
532 }
533
534 } // namespace STORAGE_CLIENT_NS
535 } // namespace storage
536 } // namespace cloud
537 } // namespace google
538