1+ syntax = "proto3" ;
2+ option java_multiple_files = true ;
3+ package org.vss ;
4+
5+ message GetObjectRequest {
6+
7+ // store_id is a keyspace identifier.
8+ // Ref: https://en.wikipedia.org/wiki/Keyspace_(distributed_data_store)
9+ // All APIs operate within a single store_id.
10+ // It is up to clients to use single or multiple stores for their use-case.
11+ // This can be used for client-isolation/ rate-limiting / throttling on the server-side.
12+ // Authorization and billing can also be performed at the store_id level.
13+ string store_id = 1 ;
14+
15+ // Key for which the value is to be fetched.
16+ //
17+ // Consistency Guarantee:
18+ // Get(read) operations against a key are consistent reads and will reflect all previous writes,
19+ // since Put/Write provides read-after-write and read-after-update consistency guarantees.
20+ //
21+ // Read Isolation:
22+ // Get/Read operations against a key are ensured to have read-committed isolation.
23+ // Ref: https://en.wikipedia.org/wiki/Isolation_(database_systems)#Read_committed
24+ string key = 2 ;
25+ }
26+
27+ message GetObjectResponse {
28+
29+ // Fetched value and version along with the corresponding key in the request.
30+ KeyValue value = 2 ;
31+ }
32+
33+ message PutObjectRequest {
34+
35+ // store_id is a keyspace identifier.
36+ // Ref: https://en.wikipedia.org/wiki/Keyspace_(distributed_data_store)
37+ // All APIs operate within a single store_id.
38+ // It is up to clients to use single or multiple stores for their use-case.
39+ // This can be used for client-isolation/ rate-limiting / throttling on the server-side.
40+ // Authorization and billing can also be performed at the store_id level.
41+ string store_id = 1 ;
42+
43+ // global_version is a sequence-number/version of the whole store. This can be used for versioning
44+ // and ensures that multiple updates in case of multiple devices can only be done linearly, even
45+ // if those updates did not directly conflict with each other based on keys/transaction_items.
46+ //
47+ // If present, the write will only succeed if the current server-side global_version against
48+ // the store_id is same as in the request.
49+ // Clients are expected to store (client-side) the global version against store_id.
50+ // The request must contain their client-side value of global_version if global versioning and
51+ // conflict detection is desired.
52+ //
53+ // For the first write of the store, global version should be '0'. If the write succeeds, clients
54+ // must increment their global version (client-side) by 1.
55+ // The server increments global_version (server-side) for every successful write, hence this
56+ // client-side increment is required to ensure matching versions. This updated global version
57+ // should be used in subsequent PutObjectRequests for the store.
58+ //
59+ // Requests with a conflicting version will fail with `CONFLICT_EXCEPTION` as ErrorCode.
60+ optional int64 global_version = 2 ;
61+
62+ // Items to be written as a result of this PutObjectRequest.
63+ //
64+ // In an item, each key is supplied with its corresponding value and version.
65+ // Clients can choose to encrypt the keys client-side in order to obfuscate their usage patterns.
66+ // If the write is successful, the previous value corresponding to the key will be overwritten.
67+ //
68+ // Multiple items in transaction_items of a single PutObjectRequest are written in
69+ // a database-transaction in an all-or-nothing fashion.
70+ // Items in a single PutObjectRequest must have distinct keys.
71+ //
72+ // Clients are expected to store a version against every key.
73+ // The write will succeed if the current DB version against the key is the same as in the request.
74+ // When initiating a PutObjectRequest, the request should contain their client-side version for
75+ // that key-value.
76+ //
77+ // For the first write of any key, the version should be '0'. If the write succeeds, the client
78+ // must increment their corresponding key versions (client-side) by 1.
79+ // The server increments key versions (server-side) for every successful write, hence this
80+ // client-side increment is required to ensure matching versions. These updated key versions should
81+ // be used in subsequent PutObjectRequests for the keys.
82+ //
83+ // Requests with a conflicting version will fail with `CONFLICT_EXCEPTION` as ErrorCode.
84+ //
85+ // Considerations for transactions:
86+ // Transaction writes of multiple items have a performance overhead, hence it is recommended to use
87+ // them only if required by the client application to ensure logic/code correctness.
88+ // That is, transaction_items are not a substitute for batch-write of multiple unrelated items.
89+ // When a write of multiple unrelated items is desired, it is recommended to use separate
90+ // PutObjectRequests.
91+ //
92+ // Consistency guarantee:
93+ // All PutObjectRequests are strongly consistent i.e. they provide read-after-write and
94+ // read-after-update consistency guarantees.
95+ repeated KeyValue transaction_items = 3 ;
96+ }
97+
98+ message PutObjectResponse {
99+ }
100+
101+ message ListKeyVersionsRequest {
102+
103+ // store_id is a keyspace identifier.
104+ // Ref: https://en.wikipedia.org/wiki/Keyspace_(distributed_data_store)
105+ // All APIs operate within a single store_id.
106+ // It is up to clients to use single or multiple stores for their use-case.
107+ // This can be used for client-isolation/ rate-limiting / throttling on the server-side.
108+ // Authorization and billing can also be performed at the store_id level.
109+ string store_id = 1 ;
110+
111+ // A key_prefix is a string of characters at the beginning of the key. Prefixes can be used as
112+ // a way to organize key-values in a similar way to directories.
113+ //
114+ // If key_prefix is specified, the response results will be limited to those keys that begin with
115+ // the specified prefix.
116+ //
117+ // If no key_prefix is specified or it is empty (""), all the keys are eligible to be returned in
118+ // the response.
119+ optional string key_prefix = 2 ;
120+
121+ // page_size is used by clients to specify the maximum number of results that can be returned by
122+ // the server.
123+ // The server may further constrain the maximum number of results returned in a single page.
124+ // If the page_size is 0 or not set, the server will decide the number of results to be returned.
125+ optional int32 page_size = 3 ;
126+
127+ // page_token is a pagination token.
128+ //
129+ // To query for the first page of ListKeyVersions, page_token must not be specified.
130+ //
131+ // For subsequent pages, use the value that was returned as `next_page_token` in the previous
132+ // page's ListKeyVersionsResponse.
133+ optional string page_token = 4 ;
134+ }
135+
136+ message ListKeyVersionsResponse {
137+
138+ // Fetched keys and versions.
139+ // Even though this API reuses KeyValue struct, the value sub-field will not be set by the server.
140+ repeated KeyValue key_versions = 1 ;
141+
142+ // next_page_token is a pagination token, used to retrieve the next page of results.
143+ // Use this value to query for next_page of paginated ListKeyVersions operation, by specifying
144+ // this value as the `page_token` in the next request.
145+ //
146+ // If next_page_token is empty (""), then the "last page" of results has been processed and
147+ // there is no more data to be retrieved.
148+ //
149+ // If next_page_token is not empty, it does not necessarily mean that there is more data in the
150+ // result set. The only way to know when you have reached the end of the result set is when
151+ // next_page_token is empty.
152+ //
153+ // Caution: Clients must not assume a specific number of key_versions to be present in a page for
154+ // paginated response.
155+ optional string next_page_token = 2 ;
156+
157+ // global_version is a sequence-number/version of the whole store.
158+ //
159+ // global_version is only returned in response for the first page of the ListKeyVersionsResponse
160+ // and is guaranteed to be read before reading any key-versions.
161+ //
162+ // In case of refreshing the complete key-version view on the client-side, correct usage for
163+ // the returned global_version is as following:
164+ // 1. Read global_version from the first page of paginated response and save it as local variable.
165+ // 2. Update all the key_versions on client-side from all the pages of paginated response.
166+ // 3. Update global_version on client_side from the local variable saved in step-1.
167+ // This ensures that on client-side, all current key_versions were stored at global_version or later.
168+ // This guarantee is helpful for ensuring the versioning correctness if using the global_version
169+ // in PutObject API and can help avoid the race conditions related to it.
170+ optional int64 global_version = 3 ;
171+ }
172+
173+ // When HttpStatusCode is not ok (200), the response `content` contains a serialized ErrorResponse
174+ // with the relevant ErrorCode and message
175+ message ErrorResponse {
176+
177+ // The error code uniquely identifying an error condition.
178+ // It is meant to be read and understood programmatically by code that detects/handles errors by
179+ // type.
180+ ErrorCode error_code = 1 ;
181+
182+ // The error message containing a generic description of the error condition in English.
183+ // It is intended for a human audience only and should not be parsed to extract any information
184+ // programmatically. Client-side code may use it for logging only.
185+ string message = 2 ;
186+ }
187+
188+ // ErrorCodes to be used in ErrorResponse
189+ enum ErrorCode {
190+
191+ // Default protobuf Enum value. Will not be used as ErrorCode by server.
192+ UNKNOWN = 0 ;
193+
194+ // CONFLICT_EXCEPTION is used when the request contains mismatched version (either key or global)
195+ // in PutObjectRequest. For more info refer PutObjectRequest.
196+ CONFLICT_EXCEPTION = 1 ;
197+
198+ // INVALID_REQUEST_EXCEPTION is used in the following cases:
199+ // - The request was missing a required argument.
200+ // - The specified argument was invalid, incomplete or in the wrong format.
201+ // - The request body of api cannot be deserialized into corresponding protobuf object.
202+ INVALID_REQUEST_EXCEPTION = 2 ;
203+
204+ // An internal server error occurred, client is probably at no fault and can safely retry this
205+ // error with exponential backoff.
206+ INTERNAL_SERVER_EXCEPTION = 3 ;
207+ }
208+
209+ message KeyValue {
210+
211+ // Key against which the value is stored.
212+ string key = 1 ;
213+
214+ // Version field is used for key-level versioning.
215+ // For first write of key, version should be '0'. If the write succeeds, clients must increment
216+ // their corresponding key version (client-side) by 1.
217+ // The server increments key version (server-side) for every successful write, hence this
218+ // client-side increment is required to ensure matching versions. These updated key versions should
219+ // be used in subsequent PutObjectRequests for the keys.
220+ int64 version = 2 ;
221+
222+ // Object value in bytes which is stored (in put) and fetched (in get).
223+ // Clients must encrypt this blob client-side before sending it over the wire to server in order
224+ // to preserve privacy and security.
225+ bytes value = 3 ;
226+ }
0 commit comments