[#56] object: Introduce Patch method

* Introduce rpc `Patch` and corresponding types;
* Generate docs.

Signed-off-by: Airat Arifullin <aarifullin@yadro.com>
This commit is contained in:
Airat Arifullin 2024-07-23 14:12:49 +03:00 committed by Evgenii Stratonikov
parent 8dd63c451c
commit 2efdc8fedb
2 changed files with 232 additions and 1 deletions

View file

@ -283,6 +283,51 @@ service ObjectService {
// - **TOKEN_EXPIRED** (4097, SECTION_SESSION): \
// provided session token has expired.
rpc PutSingle(PutSingleRequest) returns (PutSingleResponse);
// Patch the object. Request uses gRPC stream. First message must set
// the address of the object that is going to get patched. If the object's attributes
// are patched, then these attrubutes must be set only within the first stream message.
//
// If the patch request is performed by NOT the object's owner but if the actor has the permission
// to perform the patch, then `OwnerID` of the object is changed. In this case the object's owner
// loses the object's ownership after the patch request is successfully done.
//
// As objects are content-addressable the patching causes new object ID generation for the patched object.
// This object id is set witihn `PatchResponse`. But the object id may remain unchanged in such cases:
// 1. The chunk of the applying patch contains the same value as the object's payload within the same range;
// 2. The patch that reverts the changes applied by preceding patch;
// 3. The application of the same patches for the object a few times.
//
// Extended headers can change `Patch` behaviour:
// * [ __SYSTEM__NETMAP_EPOCH \
// (`__NEOFS__NETMAP_EPOCH` is deprecated) \
// Will use the requsted version of Network Map for object placement
// calculation.
//
// Please refer to detailed `XHeader` description.
//
// Statuses:
// - **OK** (0, SECTION_SUCCESS): \
// object has been successfully patched and saved in the container;
// - Common failures (SECTION_FAILURE_COMMON);
// - **ACCESS_DENIED** (2048, SECTION_OBJECT): \
// write access to the container is denied;
// - **OBJECT_NOT_FOUND** (2049, SECTION_OBJECT): \
// object not found in container;
// - **OBJECT_ALREADY_REMOVED** (2052, SECTION_OBJECT): \
// the requested object has been marked as deleted.
// - **OUT_OF_RANGE** (2053, SECTION_OBJECT): \
// the requested range is out of bounds;
// - **CONTAINER_NOT_FOUND** (3072, SECTION_CONTAINER): \
// object storage container not found;
// - **CONTAINER_ACCESS_DENIED** (3074, SECTION_CONTAINER): \
// access to container is denied;
// - **TOKEN_NOT_FOUND** (4096, SECTION_SESSION): \
// (for trusted object preparation) session private key does not exist or
// has been deleted;
// - **TOKEN_EXPIRED** (4097, SECTION_SESSION): \
// provided session token has expired.
rpc Patch(stream PatchRequest) returns (PatchResponse);
}
// GET object request
@ -816,4 +861,70 @@ message PutSingleResponse {
// authenticate the nodes of the message route and check the correctness of
// transmission.
neo.fs.v2.session.ResponseVerificationHeader verify_header = 3;
}
}
// Object PATCH request
message PatchRequest {
// PATCH request body
message Body {
// The address of the object that is requested to get patched.
neo.fs.v2.refs.Address address = 1;
// New attributes for the object. See `replace_attributes` flag usage to define how
// new attributes should be set.
repeated neo.fs.v2.object.Header.Attribute new_attributes = 2;
// If this flag is set, then the object's attributes will be entirely replaced by `new_attributes` list.
// The empty `new_attributes` list with `replace_attributes = true` just resets attributes list for the object.
//
// Default `false` value for this flag means the attributes will be just merged. If the incoming `new_attributes`
// list contains already existing key, then it just replaces it while merging the lists.
bool replace_attributes = 3;
// The patch for the object's payload.
message Patch {
// The range of the source object for which the payload is replaced by the patch's chunk.
// If the range's `length = 0`, then the patch's chunk is just appended to the original payload
// starting from the `offest` without any replace.
Range source_range = 1;
// The chunk that is being appended to or that replaces the original payload on the given range.
bytes chunk = 2;
}
// The patch that is applied for the object.
Patch patch = 4;
}
// Body for patch request message.
Body body = 1;
// Carries request meta information. Header data is used only to regulate
// message transport and does not affect request execution.
neo.fs.v2.session.RequestMetaHeader meta_header = 2;
// Carries request verification information. This header is used to
// authenticate the nodes of the message route and check the correctness of
// transmission.
neo.fs.v2.session.RequestVerificationHeader verify_header = 3;
}
// Object PATCH response
message PatchResponse {
// PATCH response body
message Body {
// The object ID of the saved patched object.
neo.fs.v2.refs.ObjectID object_id = 1;
}
// Body for patch response message.
Body body = 1;
// Carries response meta information. Header data is used only to regulate
// message transport and does not affect request execution.
neo.fs.v2.session.ResponseMetaHeader meta_header = 2;
// Carries response verification information. This header is used to authenticate
// the nodes of the message route and check the correctness of transmission.
neo.fs.v2.session.ResponseVerificationHeader verify_header = 3;
}