@@ -175,20 +175,48 @@ service Storage {
175175 // true, or else it is an error.
176176 //
177177 // For a resumable write, the client should instead call
178- // `StartResumableWrite()` and provide that method an `WriteObjectSpec.`
178+ // `StartResumableWrite()`, populating a `WriteObjectSpec` into that request.
179179 // They should then attach the returned `upload_id` to the first message of
180- // each following call to `Create`. If there is an error or the connection is
181- // broken during the resumable `Create()`, the client should check the status
182- // of the `Create()` by calling `QueryWriteStatus()` and continue writing from
183- // the returned `persisted_size`. This may be less than the amount of data the
184- // client previously sent.
180+ // each following call to `WriteObject`. If the stream is closed before
181+ // finishing the upload (either explicitly by the client or due to a network
182+ // error or an error response from the server), the client should do as
183+ // follows:
184+ // - Check the result Status of the stream, to determine if writing can be
185+ // resumed on this stream or must be restarted from scratch (by calling
186+ // `StartResumableWrite()`). The resumable errors are DEADLINE_EXCEEDED,
187+ // INTERNAL, and UNAVAILABLE. For each case, the client should use binary
188+ // exponential backoff before retrying. Additionally, writes can be
189+ // resumed after RESOURCE_EXHAUSTED errors, but only after taking
190+ // appropriate measures, which may include reducing aggregate send rate
191+ // across clients and/or requesting a quota increase for your project.
192+ // - If the call to `WriteObject` returns `ABORTED`, that indicates
193+ // concurrent attempts to update the resumable write, caused either by
194+ // multiple racing clients or by a single client where the previous
195+ // request was timed out on the client side but nonetheless reached the
196+ // server. In this case the client should take steps to prevent further
197+ // concurrent writes (e.g., increase the timeouts, stop using more than
198+ // one process to perform the upload, etc.), and then should follow the
199+ // steps below for resuming the upload.
200+ // - For resumable errors, the client should call `QueryWriteStatus()` and
201+ // then continue writing from the returned `persisted_size`. This may be
202+ // less than the amount of data the client previously sent. Note also that
203+ // it is acceptable to send data starting at an offset earlier than the
204+ // returned `persisted_size`; in this case, the service will skip data at
205+ // offsets that were already persisted (without checking that it matches
206+ // the previously written data), and write only the data starting from the
207+ // persisted offset. This behavior can make client-side handling simpler
208+ // in some cases.
185209 //
186210 // The service will not view the object as complete until the client has
187211 // sent a `WriteObjectRequest` with `finish_write` set to `true`. Sending any
188212 // requests on a stream after sending a request with `finish_write` set to
189213 // `true` will cause an error. The client **should** check the response it
190214 // receives to determine how much data the service was able to commit and
191215 // whether the service views the object as complete.
216+ //
217+ // Attempting to resume an already finalized object will result in an OK
218+ // status, with a WriteObjectResponse containing the finalized object's
219+ // metadata.
192220 rpc WriteObject (stream WriteObjectRequest ) returns (WriteObjectResponse ) {
193221 }
194222
@@ -472,7 +500,8 @@ message ListNotificationsRequest {
472500
473501 // The maximum number of notifications to return. The service may return fewer
474502 // than this value.
475- // The maximum value is 100; values above 100 will be coerced to 100.
503+ // The default value is 100. Specifying a value above 100 will result in a
504+ // page_size of 100.
476505 int32 page_size = 2 ;
477506
478507 // A page token, received from a previous `ListNotifications` call.
@@ -571,7 +600,7 @@ message DeleteObjectRequest {
571600 // there are no live versions of the object.
572601 optional int64 if_generation_match = 5 ;
573602
574- // Makes the operation conditional on whether the object's current generation
603+ // Makes the operation conditional on whether the object's live generation
575604 // does not match the given value. If no live object exists, the precondition
576605 // fails. Setting to 0 makes the operation succeed only if there is a live
577606 // version of the object.
@@ -608,8 +637,8 @@ message ReadObjectRequest {
608637 // back from the end of the object to be returned. For example, if an object's
609638 // length is 15 bytes, a ReadObjectRequest with `read_offset` = -5 and
610639 // `read_limit` = 3 would return bytes 10 through 12 of the object. Requesting
611- // a negative offset whose magnitude is larger than the size of the object
612- // will result in an error .
640+ // a negative offset with magnitude larger than the size of the object will
641+ // return the entire object .
613642 int64 read_offset = 4 ;
614643
615644 // The maximum number of `data` bytes the server is allowed to return in the
@@ -626,7 +655,7 @@ message ReadObjectRequest {
626655 // there are no live versions of the object.
627656 optional int64 if_generation_match = 6 ;
628657
629- // Makes the operation conditional on whether the object's current generation
658+ // Makes the operation conditional on whether the object's live generation
630659 // does not match the given value. If no live object exists, the precondition
631660 // fails. Setting to 0 makes the operation succeed only if there is a live
632661 // version of the object.
@@ -668,7 +697,7 @@ message GetObjectRequest {
668697 // there are no live versions of the object.
669698 optional int64 if_generation_match = 4 ;
670699
671- // Makes the operation conditional on whether the object's current generation
700+ // Makes the operation conditional on whether the object's live generation
672701 // does not match the given value. If no live object exists, the precondition
673702 // fails. Setting to 0 makes the operation succeed only if there is a live
674703 // version of the object.
@@ -730,7 +759,7 @@ message WriteObjectSpec {
730759 // succeed only if there are no live versions of the object.
731760 optional int64 if_generation_match = 3 ;
732761
733- // Makes the operation conditional on whether the object's current
762+ // Makes the operation conditional on whether the object's live
734763 // generation does not match the given value. If no live object exists, the
735764 // precondition fails. Setting to 0 makes the operation succeed only if
736765 // there is a live version of the object.
@@ -970,7 +999,7 @@ message RewriteObjectRequest {
970999 // there are no live versions of the object.
9711000 optional int64 if_generation_match = 7 ;
9721001
973- // Makes the operation conditional on whether the object's current generation
1002+ // Makes the operation conditional on whether the object's live generation
9741003 // does not match the given value. If no live object exists, the precondition
9751004 // fails. Setting to 0 makes the operation succeed only if there is a live
9761005 // version of the object.
@@ -984,11 +1013,11 @@ message RewriteObjectRequest {
9841013 // metageneration does not match the given value.
9851014 optional int64 if_metageneration_not_match = 10 ;
9861015
987- // Makes the operation conditional on whether the source object's current
1016+ // Makes the operation conditional on whether the source object's live
9881017 // generation matches the given value.
9891018 optional int64 if_source_generation_match = 11 ;
9901019
991- // Makes the operation conditional on whether the source object's current
1020+ // Makes the operation conditional on whether the source object's live
9921021 // generation does not match the given value.
9931022 optional int64 if_source_generation_not_match = 12 ;
9941023
@@ -1073,15 +1102,15 @@ message UpdateObjectRequest {
10731102 // The object's bucket and name fields are used to identify the object to
10741103 // update. If present, the object's generation field selects a specific
10751104 // revision of this object whose metadata should be updated. Otherwise,
1076- // assumes the current, live version of the object.
1105+ // assumes the live version of the object.
10771106 Object object = 1 ;
10781107
10791108 // Makes the operation conditional on whether the object's current generation
10801109 // matches the given value. Setting to 0 makes the operation succeed only if
10811110 // there are no live versions of the object.
10821111 optional int64 if_generation_match = 2 ;
10831112
1084- // Makes the operation conditional on whether the object's current generation
1113+ // Makes the operation conditional on whether the object's live generation
10851114 // does not match the given value. If no live object exists, the precondition
10861115 // fails. Setting to 0 makes the operation succeed only if there is a live
10871116 // version of the object.
@@ -1483,7 +1512,8 @@ message Bucket {
14831512
14841513 // Logging-related properties of a bucket.
14851514 message Logging {
1486- // The destination bucket where the current bucket's logs should be placed.
1515+ // The destination bucket where the current bucket's logs should be placed,
1516+ // using path format (like `projects/123456/buckets/foo`).
14871517 string log_bucket = 1 ;
14881518
14891519 // A prefix for log object names.
@@ -1532,6 +1562,14 @@ message Bucket {
15321562 string not_found_page = 2 ;
15331563 }
15341564
1565+ // Configuration for Custom Dual Regions. It should specify precisely two
1566+ // eligible regions within the same Multiregion. More information on regions
1567+ // may be found [https://cloud.google.com/storage/docs/locations][here].
1568+ message CustomPlacementConfig {
1569+ // List of locations to use for data placement.
1570+ repeated string data_locations = 1 ;
1571+ }
1572+
15351573 // Configuration for a bucket's Autoclass feature.
15361574 message Autoclass {
15371575 // Enables Autoclass.
@@ -1552,6 +1590,11 @@ message Bucket {
15521590 // name" of other Cloud Storage APIs. Example: "pub".
15531591 string bucket_id = 2 [(google.api.field_behavior ) = OUTPUT_ONLY ];
15541592
1593+ // The etag of the bucket.
1594+ // If included in the metadata of an UpdateBucketRequest, the operation will
1595+ // only be performed if the etag matches that of the bucket.
1596+ string etag = 29 ;
1597+
15551598 // Immutable. The project which owns this bucket.
15561599 string project = 3 [
15571600 (google.api.field_behavior ) = IMMUTABLE ,
@@ -1677,6 +1720,10 @@ message Bucket {
16771720 // Reserved for future use.
16781721 bool satisfies_pzs = 25 ;
16791722
1723+ // Configuration that, if present, specifies the data placement for a Custom
1724+ // Dual Region.
1725+ CustomPlacementConfig custom_placement_config = 26 ;
1726+
16801727 // The bucket's Autoclass configuration. If there is no configuration, the
16811728 // Autoclass feature will be disabled and have no effect on the bucket.
16821729 Autoclass autoclass = 28 ;
@@ -1710,6 +1757,12 @@ message BucketAccessControl {
17101757 // The ID for the entity, if any.
17111758 string entity_id = 4 ;
17121759
1760+ // The etag of the BucketAccessControl.
1761+ // If included in the metadata of an update or delete request message, the
1762+ // operation operation will only be performed if the etag matches that of the
1763+ // bucket's BucketAccessControl.
1764+ string etag = 8 ;
1765+
17131766 // The email address associated with the entity, if any.
17141767 string email = 5 ;
17151768
@@ -1772,6 +1825,9 @@ message HmacKeyMetadata {
17721825
17731826 // The last modification time of the HMAC key metadata.
17741827 google.protobuf.Timestamp update_time = 7 ;
1828+
1829+ // The etag of the HMAC key.
1830+ string etag = 8 ;
17751831}
17761832
17771833// A directive to publish Pub/Sub notifications upon changes to a bucket.
@@ -1791,6 +1847,11 @@ message Notification {
17911847 // '//pubsub.googleapis.com/projects/{project-identifier}/topics/{my-topic}'
17921848 string topic = 2 [(google.api.field_behavior ) = REQUIRED ];
17931849
1850+ // The etag of the Notification.
1851+ // If included in the metadata of GetNotificationRequest, the operation will
1852+ // only be performed if the etag matches that of the Notification.
1853+ string etag = 7 ;
1854+
17941855 // Optional. If present, only send notifications about listed event types. If empty,
17951856 // sent notifications for all event types.
17961857 repeated string event_types = 3 [(google.api.field_behavior ) = OPTIONAL ];
@@ -1837,6 +1898,12 @@ message Object {
18371898 }
18381899 ];
18391900
1901+ // The etag of the object.
1902+ // If included in the metadata of an update or delete request message, the
1903+ // operation will only be performed if the etag matches that of the live
1904+ // object.
1905+ string etag = 27 ;
1906+
18401907 // Immutable. The content generation of this object. Used for object versioning.
18411908 // Attempting to set or update this field will result in a
18421909 // [FieldViolation][google.rpc.BadRequest.FieldViolation].
@@ -1998,6 +2065,12 @@ message ObjectAccessControl {
19982065 // The ID for the entity, if any.
19992066 string entity_id = 4 ;
20002067
2068+ // The etag of the ObjectAccessControl.
2069+ // If included in the metadata of an update or delete request message, the
2070+ // operation will only be performed if the etag matches that of the live
2071+ // object's ObjectAccessControl.
2072+ string etag = 8 ;
2073+
20012074 // The email address associated with the entity, if any.
20022075 string email = 5 ;
20032076
0 commit comments