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