Skip to content

Commit 15baa27

Browse files
docs: Clarified how clients should work with resumable uploads (#1457)
* docs: Clarified how clients should work with resumable uploads docs: Clarified ListNotifications pagination docs: Made "live generation" wording consistent with docs for other Cloud Storage APIs fix: Made negative offsets larger in magnitude that object size return the full object for ReadObject operations fix: Made naming format for Logging.log_bucket be a path rather than raw bucket name, to be consistent with the rest of the API feat: Changed Custom Dual Regions to be specified in a proto message rather than a syntactic encoding within the bucket location feat: Added etag support PiperOrigin-RevId: 455465509 Source-Link: googleapis/googleapis@0470cd6 Source-Link: https://github.com/googleapis/googleapis-gen/commit/1b1667395e707a60abca093e8ffd512f4a0a0116 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiMWIxNjY3Mzk1ZTcwN2E2MGFiY2EwOTNlOGZmZDUxMmY0YTBhMDExNiJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * chore: update clirr-ignored-differences.xml Allow list new etag and CustomPlacementConfig properties Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com> Co-authored-by: BenWhitehead <[email protected]>
1 parent fef5059 commit 15baa27

32 files changed

+3281
-601
lines changed

gapic-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StorageClient.java

+28-8
Original file line numberDiff line numberDiff line change
@@ -2035,8 +2035,8 @@ public final ServerStreamingCallable<ReadObjectRequest, ReadObjectResponse> read
20352035
*
20362036
* @param object The object to update. The object's bucket and name fields are used to identify
20372037
* the object to update. If present, the object's generation field selects a specific revision
2038-
* of this object whose metadata should be updated. Otherwise, assumes the current, live
2039-
* version of the object.
2038+
* of this object whose metadata should be updated. Otherwise, assumes the live version of the
2039+
* object.
20402040
* @param updateMask List of fields to be updated.
20412041
* <p>To specify ALL fields, equivalent to the JSON API's "update" function, specify a single
20422042
* field with the value `&#42;`. Note: not recommended. If a new field is introduced at a
@@ -2125,19 +2125,39 @@ public final UnaryCallable<UpdateObjectRequest, Object> updateObjectCallable() {
21252125
* preconditions. Additionally, the final message must set 'finish_write' to true, or else it is
21262126
* an error.
21272127
*
2128-
* <p>For a resumable write, the client should instead call `StartResumableWrite()` and provide
2129-
* that method an `WriteObjectSpec.` They should then attach the returned `upload_id` to the first
2130-
* message of each following call to `Create`. If there is an error or the connection is broken
2131-
* during the resumable `Create()`, the client should check the status of the `Create()` by
2132-
* calling `QueryWriteStatus()` and continue writing from the returned `persisted_size`. This may
2133-
* be less than the amount of data the client previously sent.
2128+
* <p>For a resumable write, the client should instead call `StartResumableWrite()`, populating a
2129+
* `WriteObjectSpec` into that request. They should then attach the returned `upload_id` to the
2130+
* first message of each following call to `WriteObject`. If the stream is closed before finishing
2131+
* the upload (either explicitly by the client or due to a network error or an error response from
2132+
* the server), the client should do as follows: - Check the result Status of the stream, to
2133+
* determine if writing can be resumed on this stream or must be restarted from scratch (by
2134+
* calling `StartResumableWrite()`). The resumable errors are DEADLINE_EXCEEDED, INTERNAL, and
2135+
* UNAVAILABLE. For each case, the client should use binary exponential backoff before retrying.
2136+
* Additionally, writes can be resumed after RESOURCE_EXHAUSTED errors, but only after taking
2137+
* appropriate measures, which may include reducing aggregate send rate across clients and/or
2138+
* requesting a quota increase for your project. - If the call to `WriteObject` returns `ABORTED`,
2139+
* that indicates concurrent attempts to update the resumable write, caused either by multiple
2140+
* racing clients or by a single client where the previous request was timed out on the client
2141+
* side but nonetheless reached the server. In this case the client should take steps to prevent
2142+
* further concurrent writes (e.g., increase the timeouts, stop using more than one process to
2143+
* perform the upload, etc.), and then should follow the steps below for resuming the upload. -
2144+
* For resumable errors, the client should call `QueryWriteStatus()` and then continue writing
2145+
* from the returned `persisted_size`. This may be less than the amount of data the client
2146+
* previously sent. Note also that it is acceptable to send data starting at an offset earlier
2147+
* than the returned `persisted_size`; in this case, the service will skip data at offsets that
2148+
* were already persisted (without checking that it matches the previously written data), and
2149+
* write only the data starting from the persisted offset. This behavior can make client-side
2150+
* handling simpler in some cases.
21342151
*
21352152
* <p>The service will not view the object as complete until the client has sent a
21362153
* `WriteObjectRequest` with `finish_write` set to `true`. Sending any requests on a stream after
21372154
* sending a request with `finish_write` set to `true` will cause an error. The client
21382155
* &#42;&#42;should&#42;&#42; check the response it receives to determine how much data the
21392156
* service was able to commit and whether the service views the object as complete.
21402157
*
2158+
* <p>Attempting to resume an already finalized object will result in an OK status, with a
2159+
* WriteObjectResponse containing the finalized object's metadata.
2160+
*
21412161
* <p>Sample code:
21422162
*
21432163
* <pre>{@code

gapic-google-cloud-storage-v2/src/test/java/com/google/storage/v2/StorageClientTest.java

+25
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ public void getBucketTest() throws Exception {
175175
Bucket.newBuilder()
176176
.setName(BucketName.of("[PROJECT]", "[BUCKET]").toString())
177177
.setBucketId("bucketId-1603305307")
178+
.setEtag("etag3123477")
178179
.setProject(ProjectName.of("[PROJECT]").toString())
179180
.setMetageneration(1048558813)
180181
.setLocation("location1901043637")
@@ -198,6 +199,7 @@ public void getBucketTest() throws Exception {
198199
.setRetentionPolicy(Bucket.RetentionPolicy.newBuilder().build())
199200
.setIamConfig(Bucket.IamConfig.newBuilder().build())
200201
.setSatisfiesPzs(true)
202+
.setCustomPlacementConfig(Bucket.CustomPlacementConfig.newBuilder().build())
201203
.setAutoclass(Bucket.Autoclass.newBuilder().build())
202204
.build();
203205
mockStorage.addResponse(expectedResponse);
@@ -238,6 +240,7 @@ public void getBucketTest2() throws Exception {
238240
Bucket.newBuilder()
239241
.setName(BucketName.of("[PROJECT]", "[BUCKET]").toString())
240242
.setBucketId("bucketId-1603305307")
243+
.setEtag("etag3123477")
241244
.setProject(ProjectName.of("[PROJECT]").toString())
242245
.setMetageneration(1048558813)
243246
.setLocation("location1901043637")
@@ -261,6 +264,7 @@ public void getBucketTest2() throws Exception {
261264
.setRetentionPolicy(Bucket.RetentionPolicy.newBuilder().build())
262265
.setIamConfig(Bucket.IamConfig.newBuilder().build())
263266
.setSatisfiesPzs(true)
267+
.setCustomPlacementConfig(Bucket.CustomPlacementConfig.newBuilder().build())
264268
.setAutoclass(Bucket.Autoclass.newBuilder().build())
265269
.build();
266270
mockStorage.addResponse(expectedResponse);
@@ -301,6 +305,7 @@ public void createBucketTest() throws Exception {
301305
Bucket.newBuilder()
302306
.setName(BucketName.of("[PROJECT]", "[BUCKET]").toString())
303307
.setBucketId("bucketId-1603305307")
308+
.setEtag("etag3123477")
304309
.setProject(ProjectName.of("[PROJECT]").toString())
305310
.setMetageneration(1048558813)
306311
.setLocation("location1901043637")
@@ -324,6 +329,7 @@ public void createBucketTest() throws Exception {
324329
.setRetentionPolicy(Bucket.RetentionPolicy.newBuilder().build())
325330
.setIamConfig(Bucket.IamConfig.newBuilder().build())
326331
.setSatisfiesPzs(true)
332+
.setCustomPlacementConfig(Bucket.CustomPlacementConfig.newBuilder().build())
327333
.setAutoclass(Bucket.Autoclass.newBuilder().build())
328334
.build();
329335
mockStorage.addResponse(expectedResponse);
@@ -370,6 +376,7 @@ public void createBucketTest2() throws Exception {
370376
Bucket.newBuilder()
371377
.setName(BucketName.of("[PROJECT]", "[BUCKET]").toString())
372378
.setBucketId("bucketId-1603305307")
379+
.setEtag("etag3123477")
373380
.setProject(ProjectName.of("[PROJECT]").toString())
374381
.setMetageneration(1048558813)
375382
.setLocation("location1901043637")
@@ -393,6 +400,7 @@ public void createBucketTest2() throws Exception {
393400
.setRetentionPolicy(Bucket.RetentionPolicy.newBuilder().build())
394401
.setIamConfig(Bucket.IamConfig.newBuilder().build())
395402
.setSatisfiesPzs(true)
403+
.setCustomPlacementConfig(Bucket.CustomPlacementConfig.newBuilder().build())
396404
.setAutoclass(Bucket.Autoclass.newBuilder().build())
397405
.build();
398406
mockStorage.addResponse(expectedResponse);
@@ -527,6 +535,7 @@ public void lockBucketRetentionPolicyTest() throws Exception {
527535
Bucket.newBuilder()
528536
.setName(BucketName.of("[PROJECT]", "[BUCKET]").toString())
529537
.setBucketId("bucketId-1603305307")
538+
.setEtag("etag3123477")
530539
.setProject(ProjectName.of("[PROJECT]").toString())
531540
.setMetageneration(1048558813)
532541
.setLocation("location1901043637")
@@ -550,6 +559,7 @@ public void lockBucketRetentionPolicyTest() throws Exception {
550559
.setRetentionPolicy(Bucket.RetentionPolicy.newBuilder().build())
551560
.setIamConfig(Bucket.IamConfig.newBuilder().build())
552561
.setSatisfiesPzs(true)
562+
.setCustomPlacementConfig(Bucket.CustomPlacementConfig.newBuilder().build())
553563
.setAutoclass(Bucket.Autoclass.newBuilder().build())
554564
.build();
555565
mockStorage.addResponse(expectedResponse);
@@ -591,6 +601,7 @@ public void lockBucketRetentionPolicyTest2() throws Exception {
591601
Bucket.newBuilder()
592602
.setName(BucketName.of("[PROJECT]", "[BUCKET]").toString())
593603
.setBucketId("bucketId-1603305307")
604+
.setEtag("etag3123477")
594605
.setProject(ProjectName.of("[PROJECT]").toString())
595606
.setMetageneration(1048558813)
596607
.setLocation("location1901043637")
@@ -614,6 +625,7 @@ public void lockBucketRetentionPolicyTest2() throws Exception {
614625
.setRetentionPolicy(Bucket.RetentionPolicy.newBuilder().build())
615626
.setIamConfig(Bucket.IamConfig.newBuilder().build())
616627
.setSatisfiesPzs(true)
628+
.setCustomPlacementConfig(Bucket.CustomPlacementConfig.newBuilder().build())
617629
.setAutoclass(Bucket.Autoclass.newBuilder().build())
618630
.build();
619631
mockStorage.addResponse(expectedResponse);
@@ -909,6 +921,7 @@ public void updateBucketTest() throws Exception {
909921
Bucket.newBuilder()
910922
.setName(BucketName.of("[PROJECT]", "[BUCKET]").toString())
911923
.setBucketId("bucketId-1603305307")
924+
.setEtag("etag3123477")
912925
.setProject(ProjectName.of("[PROJECT]").toString())
913926
.setMetageneration(1048558813)
914927
.setLocation("location1901043637")
@@ -932,6 +945,7 @@ public void updateBucketTest() throws Exception {
932945
.setRetentionPolicy(Bucket.RetentionPolicy.newBuilder().build())
933946
.setIamConfig(Bucket.IamConfig.newBuilder().build())
934947
.setSatisfiesPzs(true)
948+
.setCustomPlacementConfig(Bucket.CustomPlacementConfig.newBuilder().build())
935949
.setAutoclass(Bucket.Autoclass.newBuilder().build())
936950
.build();
937951
mockStorage.addResponse(expectedResponse);
@@ -1043,6 +1057,7 @@ public void getNotificationTest() throws Exception {
10431057
Notification.newBuilder()
10441058
.setName(NotificationName.of("[PROJECT]", "[BUCKET]", "[NOTIFICATION]").toString())
10451059
.setTopic("topic110546223")
1060+
.setEtag("etag3123477")
10461061
.addAllEventTypes(new ArrayList<String>())
10471062
.putAllCustomAttributes(new HashMap<String, String>())
10481063
.setObjectNamePrefix("objectNamePrefix-1978236516")
@@ -1086,6 +1101,7 @@ public void getNotificationTest2() throws Exception {
10861101
Notification.newBuilder()
10871102
.setName(NotificationName.of("[PROJECT]", "[BUCKET]", "[NOTIFICATION]").toString())
10881103
.setTopic("topic110546223")
1104+
.setEtag("etag3123477")
10891105
.addAllEventTypes(new ArrayList<String>())
10901106
.putAllCustomAttributes(new HashMap<String, String>())
10911107
.setObjectNamePrefix("objectNamePrefix-1978236516")
@@ -1129,6 +1145,7 @@ public void createNotificationTest() throws Exception {
11291145
Notification.newBuilder()
11301146
.setName(NotificationName.of("[PROJECT]", "[BUCKET]", "[NOTIFICATION]").toString())
11311147
.setTopic("topic110546223")
1148+
.setEtag("etag3123477")
11321149
.addAllEventTypes(new ArrayList<String>())
11331150
.putAllCustomAttributes(new HashMap<String, String>())
11341151
.setObjectNamePrefix("objectNamePrefix-1978236516")
@@ -1175,6 +1192,7 @@ public void createNotificationTest2() throws Exception {
11751192
Notification.newBuilder()
11761193
.setName(NotificationName.of("[PROJECT]", "[BUCKET]", "[NOTIFICATION]").toString())
11771194
.setTopic("topic110546223")
1195+
.setEtag("etag3123477")
11781196
.addAllEventTypes(new ArrayList<String>())
11791197
.putAllCustomAttributes(new HashMap<String, String>())
11801198
.setObjectNamePrefix("objectNamePrefix-1978236516")
@@ -1309,6 +1327,7 @@ public void composeObjectTest() throws Exception {
13091327
Object.newBuilder()
13101328
.setName("name3373707")
13111329
.setBucket(BucketName.of("[PROJECT]", "[BUCKET]").toString())
1330+
.setEtag("etag3123477")
13121331
.setGeneration(305703192)
13131332
.setMetageneration(1048558813)
13141333
.setStorageClass("storageClass871353277")
@@ -1482,6 +1501,7 @@ public void getObjectTest() throws Exception {
14821501
Object.newBuilder()
14831502
.setName("name3373707")
14841503
.setBucket(BucketName.of("[PROJECT]", "[BUCKET]").toString())
1504+
.setEtag("etag3123477")
14851505
.setGeneration(305703192)
14861506
.setMetageneration(1048558813)
14871507
.setStorageClass("storageClass871353277")
@@ -1550,6 +1570,7 @@ public void getObjectTest2() throws Exception {
15501570
Object.newBuilder()
15511571
.setName("name3373707")
15521572
.setBucket(BucketName.of("[PROJECT]", "[BUCKET]").toString())
1573+
.setEtag("etag3123477")
15531574
.setGeneration(305703192)
15541575
.setMetageneration(1048558813)
15551576
.setStorageClass("storageClass871353277")
@@ -1692,6 +1713,7 @@ public void updateObjectTest() throws Exception {
16921713
Object.newBuilder()
16931714
.setName("name3373707")
16941715
.setBucket(BucketName.of("[PROJECT]", "[BUCKET]").toString())
1716+
.setEtag("etag3123477")
16951717
.setGeneration(305703192)
16961718
.setMetageneration(1048558813)
16971719
.setStorageClass("storageClass871353277")
@@ -2352,6 +2374,7 @@ public void getHmacKeyTest() throws Exception {
23522374
.setState("state109757585")
23532375
.setCreateTime(Timestamp.newBuilder().build())
23542376
.setUpdateTime(Timestamp.newBuilder().build())
2377+
.setEtag("etag3123477")
23552378
.build();
23562379
mockStorage.addResponse(expectedResponse);
23572380

@@ -2399,6 +2422,7 @@ public void getHmacKeyTest2() throws Exception {
23992422
.setState("state109757585")
24002423
.setCreateTime(Timestamp.newBuilder().build())
24012424
.setUpdateTime(Timestamp.newBuilder().build())
2425+
.setEtag("etag3123477")
24022426
.build();
24032427
mockStorage.addResponse(expectedResponse);
24042428

@@ -2534,6 +2558,7 @@ public void updateHmacKeyTest() throws Exception {
25342558
.setState("state109757585")
25352559
.setCreateTime(Timestamp.newBuilder().build())
25362560
.setUpdateTime(Timestamp.newBuilder().build())
2561+
.setEtag("etag3123477")
25372562
.build();
25382563
mockStorage.addResponse(expectedResponse);
25392564

0 commit comments

Comments
 (0)