├── .gitignore ├── .travis.yml ├── Cargo.toml ├── LICENSE ├── README.md ├── build.rs ├── dummy_credentials_file_for_tests.json ├── protos └── google │ ├── api │ ├── annotations.proto │ ├── client.proto │ ├── field_behavior.proto │ ├── http.proto │ └── resource.proto │ ├── bigtable │ └── v2 │ │ ├── bigtable.proto │ │ └── data.proto │ ├── protobuf │ ├── any.proto │ ├── descriptor.proto │ └── wrappers.proto │ └── rpc │ └── status.proto ├── random_rsa_for_tests └── src ├── error.rs ├── lib.rs ├── method.rs ├── request.rs ├── support.rs ├── utils.rs └── wraps.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | /pk.pem 4 | .idea* 5 | src/protos 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: rust 3 | addons: 4 | apt: 5 | packages: 6 | - libcurl4-openssl-dev 7 | - libelf-dev 8 | - libdw-dev 9 | - binutils-dev 10 | rust: 11 | - stable 12 | before_script: 13 | - | 14 | pip install 'travis-cargo<0.2' --user && 15 | export PATH=$HOME/.local/bin:$PATH 16 | script: 17 | - "travis-cargo build &&\n \ntravis-cargo --only stable doc\n" 18 | after_success: 19 | - travis-cargo doc-upload 20 | - travis-cargo coveralls --no-sudo --verify 21 | env: 22 | global: 23 | - TRAVIS_CARGO_NIGHTLY_FEATURE="" 24 | - secure: HnfO26DIDzo7ROvcC4PMeWbfkrgtI+WipliEzNPUaelWpCNp0PLGjaUe22Q0iBLXvHcxuc8v3yOI+LFQkiWpajaVCITEYZd8AJ6zfEfsxiSI3AM/kGetC12zNLl9iVwEU1eEX50ZwTFcUz38p1mFsukWh4ItZ5BGxUz6DALa19M7YxsoHWsp7TQf+DHTVzTIphqDMB75MPDBdybh94T6ENI6uxGk0Aj90HcknNrsyrvBCE32ELPjYZEWMPomjOh6hH6g5mnmNQtI6pac2R623ouZ46NWuNGLsUpvLIe+r4AWVWtIr2z10IU4Nn2xxvY7NdQRRE7320XlQcfUgXKWjA3ZtPUBI1p89KM4kyrQKcuEZHiBK4mvEgNIUx2aI1Z3ijUkamhz8hP6a1glmVxSsWvfQTAqG7ntpnCw2764haxtF2UmKLmXKfVxOf9JYntMVQ1AZQTEwc4Ghfi1hmN6NhWk5KT0HA5T4rhYWSUjgRT2JvzqB8AjDNBLLaqKa/0GfE48efdeel1bo1lsENCJyIRv16VYzkuGnK2qiOJZJiV9qV+fXEF2ccMlXuX6mqqEgnS2GrUZQGPU5kEAbqbHeMYNKMNf5v9zKALenFkOASLtYC23rRgfvPd+aoKhspcVEzBz1wpkF5DQoU1ZPdxdXiAP1K6uwjJjnUxRNxSpOMw= 25 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bigtable" 3 | version = "0.5.0" 4 | authors = ["Drazen Urch "] 5 | description = "Lib for interfacing with Google BigTable Data API" 6 | repository = "https://github.com/durch/rust-bigtable" 7 | readme = "README.md" 8 | keywords = ["Google", "Cloud", "BigTable", "Data", "API"] 9 | license = "MIT" 10 | documentation = "https://durch.github.io/rust-bigtable" 11 | edition = "2018" 12 | build = "build.rs" 13 | 14 | [lib] 15 | name = "bigtable" 16 | path = "src/lib.rs" 17 | 18 | [dependencies] 19 | protobuf = "2.8.1" 20 | smpl_jwt = "0.4" 21 | goauth = "0.6" 22 | log = "0.4.8" 23 | curl = "0.4" 24 | serde = "1.0.103" 25 | serde_derive = "1.0.103" 26 | serde_json = "1.0.44" 27 | rustc-serialize = "0.3.24" 28 | protobuf-json-temp = "0.3.0" 29 | 30 | [build-dependencies] 31 | protobuf-codegen-pure = "2.8.1" 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Drazen Urch 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![](https://travis-ci.org/durch/rust-bigtable.svg?branch=master)](https://travis-ci.org/durch/rust-bigtable) 2 | [![](http://meritbadge.herokuapp.com/bigtable)](https://crates.io/crates/bigtable) 3 | [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/durch/rust-bigtable/blob/master/LICENSE.md) 4 | [![Join the chat at https://gitter.im/durch/rust-bigtable](https://badges.gitter.im/durch/rust-bigtable.svg)](https://gitter.im/durch/rust-bigtable?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 5 | [![Mentioned in Awesome Bigtable](https://awesome.re/mentioned-badge-flat.svg)](https://github.com/zrosenbauer/awesome-bigtable) 6 | 7 | ## rust-bigtable [[docs](https://durch.github.io/rust-bigtable/)] 8 | 9 | Rust library for working with [Google Bigtable](https://cloud.google.com/bigtable/docs/) [Data API](https://cloud.google.com/bigtable/docs/reference/data/rpc/google.bigtable.v2) 10 | 11 | ### Intro 12 | Interface towards Cloud Bigtable, supports all [Data API](https://cloud.google.com/bigtable/docs/reference/data/rpc/google.bigtable.v2) methods. 13 | 14 | + CheckAndMutateRow 15 | + MutateRow 16 | + MutateRows 17 | + ReadModifyWriteRow 18 | + ReadRows 19 | + SampleRowKeys 20 | 21 | Includes support for [JWT auth](https://cloud.google.com/docs/authentication): 22 | 23 | ### How it works 24 | 25 | Initial plans was to go full `grpc` over `http/2`, unfortunately Rust support is not there yet, so a middle way was taken :). 26 | 27 | Requests objects are `protobuf` messages, generated using `proto` definitions available from [Google](https://github.com/googleapis/googleapis/blob/master/google/bigtable/v2/bigtable.proto). And all configuration is done through very nice interfaces generated in this way. These messages are then transparently converted to `json`, and sent to predefined `google.api.http` endpoints, also defined [here](https://github.com/googleapis/googleapis/blob/master/google/bigtable/v2/bigtable.proto). Responses are returned as [serde_json::Value](https://docs.serde.rs/serde_json/value/index.html). 28 | 29 | In theory this should enable easy upgrade to full `grpc` over `http/2` as soon as it becomes viable, the only remaining work would be utilising proper return types, also available as `protobuf` messages. 30 | 31 | ### Configuration 32 | 33 | You can provide the `json` service accounts credentials obtained from Google Cloud Console or the private key file in `pem` or (see [random_rsa_for_testing](https://github.com/durch/rust-bigtable/blob/master/random_rsa_for_tests) for proper format) format as well as Google Cloud service account with proper scopes (scopes are handled by [goauth](https://crates.io/crates/goauth), as part of authentication), 34 | 35 | ### Usage 36 | 37 | *In your Cargo.toml* 38 | 39 | ``` 40 | [dependencies] 41 | bigtable = '0.3' 42 | ``` 43 | 44 | #### Higher level wrappers (`wraps`) 45 | 46 | There and higher wrappers available for reading and writing rows, so there is not need to craft `protobufs` manually. Write can also be used to update, but not very robustly yet, coming soon :). 47 | 48 | ##### Read and Write 49 | 50 | Read wrappers allows for simple limit on the number of rows, it uses the `ReadRows` underlying method. 51 | 52 | There are two write strategies available, `bulk_write_rows` and `write_rows`. `bulk_write_rows` first collects all writes and fires only one request, underlying method is `MutateRows`, this results in a much higher write throughput. `write_rows` shoots one request per row to be written, underlying method is `ReadModifyWriteRow`. 53 | 54 | ```rust 55 | 56 | extern crate bigtable as bt; 57 | 58 | use bt::utils::*; 59 | use bt::wraps; 60 | 61 | const TOKEN_URL: &'static str = "https://www.googleapis.com/oauth2/v4/token"; 62 | const ISS: &'static str = "some-service-account@developer.gserviceaccount.com"; 63 | const PK: &'static str = "pk_for_the_acc_above.pem"; 64 | 65 | fn read_rows(limit: i64) -> Result<(serde_json::Value), BTErr> { 66 | 67 | let token = get_auth_token(TOKEN_URL, ISS, PK)?; 68 | let table = Default::default(); 69 | 70 | wraps::read_rows(table, &token, Some(limit)) 71 | 72 | } 73 | 74 | fn write_rows(n: usize, bulk: bool) -> Result<(), BTErr> { 75 | let mut rows: Vec = vec!(wraps::Row::default()); // put some real data here 76 | let token = get_auth_token(TOKEN_URL, ISS, PK)?; 77 | let table = Default::default(); // Again use a real table here 78 | if bulk { 79 | let _ = wraps::bulk_write_rows(&mut rows, &token, table); 80 | } else { 81 | let _ = wraps::write_rows(&mut rows, &token, table); 82 | } 83 | Ok(()) 84 | } 85 | ``` 86 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | extern crate protobuf_codegen_pure; 2 | 3 | fn main() { 4 | protobuf_codegen_pure::run(protobuf_codegen_pure::Args { 5 | out_dir: "src/protos", 6 | input: &[ 7 | "protos/google/bigtable/v2/bigtable.proto", 8 | "protos/google/bigtable/v2/data.proto", 9 | "protos/google/rpc/status.proto" 10 | ], 11 | includes: &["protos"], 12 | customize: protobuf_codegen_pure::Customize { 13 | ..Default::default() 14 | }, 15 | }) 16 | .expect("protoc"); 17 | } 18 | -------------------------------------------------------------------------------- /dummy_credentials_file_for_tests.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "service_account", 3 | "project_id": "dummy", 4 | "private_key_id": "dummy", 5 | "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDNk6cKkWP/4NMu\nWb3s24YHfM639IXzPtTev06PUVVQnyHmT1bZgQ/XB6BvIRaReqAqnQd61PAGtX3e\n8XocTw+u/ZfiPJOf+jrXMkRBpiBh9mbyEIqBy8BC20OmsUc+O/YYh/qRccvRfPI7\n3XMabQ8eFWhI6z/t35oRpvEVFJnSIgyV4JR/L/cjtoKnxaFwjBzEnxPiwtdy4olU\nKO/1maklXexvlO7onC7CNmPAjuEZKzdMLzFszikCDnoKJC8k6+2GZh0/JDMAcAF4\nwxlKNQ89MpHVRXZ566uKZg0MqZqkq5RXPn6u7yvNHwZ0oahHT+8ixPPrAEjuPEKM\nUPzVRz71AgMBAAECggEAfdbVWLW5Befkvam3hea2+5xdmeN3n3elrJhkiXxbAhf3\nE1kbq9bCEHmdrokNnI34vz0SWBFCwIiWfUNJ4UxQKGkZcSZto270V8hwWdNMXUsM\npz6S2nMTxJkdp0s7dhAUS93o9uE2x4x5Z0XecJ2ztFGcXY6Lupu2XvnW93V9109h\nkY3uICLdbovJq7wS/fO/AL97QStfEVRWW2agIXGvoQG5jOwfPh86GZZRYP9b8VNw\ntkAUJe4qpzNbWs9AItXOzL+50/wsFkD/iWMGWFuU8DY5ZwsL434N+uzFlaD13wtZ\n63D+tNAxCSRBfZGQbd7WxJVFfZe/2vgjykKWsdyNAQKBgQDnEBgSI836HGSRk0Ub\nDwiEtdfh2TosV+z6xtyU7j/NwjugTOJEGj1VO/TMlZCEfpkYPLZt3ek2LdNL66n8\nDyxwzTT5Q3D/D0n5yE3mmxy13Qyya6qBYvqqyeWNwyotGM7hNNOix1v9lEMtH5Rd\nUT0gkThvJhtrV663bcAWCALmtQKBgQDjw2rYlMUp2TUIa2/E7904WOnSEG85d+nc\norhzthX8EWmPgw1Bbfo6NzH4HhebTw03j3NjZdW2a8TG/uEmZFWhK4eDvkx+rxAa\n6EwamS6cmQ4+vdep2Ac4QCSaTZj02YjHb06Be3gptvpFaFrotH2jnpXxggdiv8ul\n6x+ooCffQQKBgQCR3ykzGoOI6K/c75prELyR+7MEk/0TzZaAY1cSdq61GXBHLQKT\nd/VMgAN1vN51pu7DzGBnT/dRCvEgNvEjffjSZdqRmrAVdfN/y6LSeQ5RCfJgGXSV\nJoWVmMxhCNrxiX3h01Xgp/c9SYJ3VD54AzeR/dwg32/j/oEAsDraLciXGQKBgQDF\nMNc8k/DvfmJv27R06Ma6liA6AoiJVMxgfXD8nVUDW3/tBCVh1HmkFU1p54PArvxe\nchAQqoYQ3dUMBHeh6ZRJaYp2ATfxJlfnM99P1/eHFOxEXdBt996oUMBf53bZ5cyJ\n/lAVwnQSiZy8otCyUDHGivJ+mXkTgcIq8BoEwERFAQKBgQDmImBaFqoMSVihqHIf\nDa4WZqwM7ODqOx0JnBKrKO8UOc51J5e1vpwP/qRpNhUipoILvIWJzu4efZY7GN5C\nImF9sN3PP6Sy044fkVPyw4SYEisxbvp9tfw8Xmpj/pbmugkB2ut6lz5frmEBoJSN\n3osZlZTgx+pM3sO6ITV6U4ID2Q==\n-----END PRIVATE KEY-----\n", 6 | "client_email": "dummy@developer.gserviceaccount.com", 7 | "client_id": "dummy", 8 | "auth_uri": "https://accounts.google.com/o/oauth2/auth", 9 | "token_uri": "https://accounts.google.com/o/oauth2/token", 10 | "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", 11 | "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/457015483506-compute%40developer.gserviceaccount.com" 12 | } 13 | -------------------------------------------------------------------------------- /protos/google/api/annotations.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015, Google Inc. 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 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/http.proto"; 20 | import "google/protobuf/descriptor.proto"; 21 | 22 | option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; 23 | option java_multiple_files = true; 24 | option java_outer_classname = "AnnotationsProto"; 25 | option java_package = "com.google.api"; 26 | option objc_class_prefix = "GAPI"; 27 | 28 | extend google.protobuf.MethodOptions { 29 | // See `HttpRule`. 30 | HttpRule http = 72295728; 31 | } -------------------------------------------------------------------------------- /protos/google/api/client.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | 16 | syntax = "proto3"; 17 | 18 | package google.api; 19 | 20 | import "google/protobuf/descriptor.proto"; 21 | 22 | option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; 23 | option java_multiple_files = true; 24 | option java_outer_classname = "ClientProto"; 25 | option java_package = "com.google.api"; 26 | option objc_class_prefix = "GAPI"; 27 | 28 | extend google.protobuf.MethodOptions { 29 | // A definition of a client library method signature. 30 | // 31 | // In client libraries, each proto RPC corresponds to one or more methods 32 | // which the end user is able to call, and calls the underlying RPC. 33 | // Normally, this method receives a single argument (a struct or instance 34 | // corresponding to the RPC request object). Defining this field will 35 | // add one or more overloads providing flattened or simpler method signatures 36 | // in some languages. 37 | // 38 | // The fields on the method signature are provided as a comma-separated 39 | // string. 40 | // 41 | // For example, the proto RPC and annotation: 42 | // 43 | // rpc CreateSubscription(CreateSubscriptionRequest) 44 | // returns (Subscription) { 45 | // option (google.api.method_signature) = "name,topic"; 46 | // } 47 | // 48 | // Would add the following Java overload (in addition to the method accepting 49 | // the request object): 50 | // 51 | // public final Subscription createSubscription(String name, String topic) 52 | // 53 | // The following backwards-compatibility guidelines apply: 54 | // 55 | // * Adding this annotation to an unannotated method is backwards 56 | // compatible. 57 | // * Adding this annotation to a method which already has existing 58 | // method signature annotations is backwards compatible if and only if 59 | // the new method signature annotation is last in the sequence. 60 | // * Modifying or removing an existing method signature annotation is 61 | // a breaking change. 62 | // * Re-ordering existing method signature annotations is a breaking 63 | // change. 64 | repeated string method_signature = 1051; 65 | } 66 | 67 | extend google.protobuf.ServiceOptions { 68 | // The hostname for this service. 69 | // This should be specified with no prefix or protocol. 70 | // 71 | // Example: 72 | // 73 | // service Foo { 74 | // option (google.api.default_host) = "foo.googleapi.com"; 75 | // ... 76 | // } 77 | string default_host = 1049; 78 | 79 | // OAuth scopes needed for the client. 80 | // 81 | // Example: 82 | // 83 | // service Foo { 84 | // option (google.api.oauth_scopes) = \ 85 | // "https://www.googleapis.com/auth/cloud-platform"; 86 | // ... 87 | // } 88 | // 89 | // If there is more than one scope, use a comma-separated string: 90 | // 91 | // Example: 92 | // 93 | // service Foo { 94 | // option (google.api.oauth_scopes) = \ 95 | // "https://www.googleapis.com/auth/cloud-platform," 96 | // "https://www.googleapis.com/auth/monitoring"; 97 | // ... 98 | // } 99 | string oauth_scopes = 1050; 100 | } -------------------------------------------------------------------------------- /protos/google/api/field_behavior.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | 16 | syntax = "proto3"; 17 | 18 | package google.api; 19 | 20 | import "google/protobuf/descriptor.proto"; 21 | 22 | option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; 23 | option java_multiple_files = true; 24 | option java_outer_classname = "FieldBehaviorProto"; 25 | option java_package = "com.google.api"; 26 | option objc_class_prefix = "GAPI"; 27 | 28 | extend google.protobuf.FieldOptions { 29 | // A designation of a specific field behavior (required, output only, etc.) 30 | // in protobuf messages. 31 | // 32 | // Examples: 33 | // 34 | // string name = 1 [(google.api.field_behavior) = REQUIRED]; 35 | // State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY]; 36 | // google.protobuf.Duration ttl = 1 37 | // [(google.api.field_behavior) = INPUT_ONLY]; 38 | // google.protobuf.Timestamp expire_time = 1 39 | // [(google.api.field_behavior) = OUTPUT_ONLY, 40 | // (google.api.field_behavior) = IMMUTABLE]; 41 | repeated google.api.FieldBehavior field_behavior = 1052; 42 | } 43 | 44 | // An indicator of the behavior of a given field (for example, that a field 45 | // is required in requests, or given as output but ignored as input). 46 | // This **does not** change the behavior in protocol buffers itself; it only 47 | // denotes the behavior and may affect how API tooling handles the field. 48 | // 49 | // Note: This enum **may** receive new values in the future. 50 | enum FieldBehavior { 51 | // Conventional default for enums. Do not use this. 52 | FIELD_BEHAVIOR_UNSPECIFIED = 0; 53 | 54 | // Specifically denotes a field as optional. 55 | // While all fields in protocol buffers are optional, this may be specified 56 | // for emphasis if appropriate. 57 | OPTIONAL = 1; 58 | 59 | // Denotes a field as required. 60 | // This indicates that the field **must** be provided as part of the request, 61 | // and failure to do so will cause an error (usually `INVALID_ARGUMENT`). 62 | REQUIRED = 2; 63 | 64 | // Denotes a field as output only. 65 | // This indicates that the field is provided in responses, but including the 66 | // field in a request does nothing (the server *must* ignore it and 67 | // *must not* throw an error as a result of the field's presence). 68 | OUTPUT_ONLY = 3; 69 | 70 | // Denotes a field as input only. 71 | // This indicates that the field is provided in requests, and the 72 | // corresponding field is not included in output. 73 | INPUT_ONLY = 4; 74 | 75 | // Denotes a field as immutable. 76 | // This indicates that the field may be set once in a request to create a 77 | // resource, but may not be changed thereafter. 78 | IMMUTABLE = 5; 79 | } -------------------------------------------------------------------------------- /protos/google/api/http.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | 16 | syntax = "proto3"; 17 | 18 | package google.api; 19 | 20 | option cc_enable_arenas = true; 21 | option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; 22 | option java_multiple_files = true; 23 | option java_outer_classname = "HttpProto"; 24 | option java_package = "com.google.api"; 25 | option objc_class_prefix = "GAPI"; 26 | 27 | // Defines the HTTP configuration for an API service. It contains a list of 28 | // [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method 29 | // to one or more HTTP REST API methods. 30 | message Http { 31 | // A list of HTTP configuration rules that apply to individual API methods. 32 | // 33 | // **NOTE:** All service configuration rules follow "last one wins" order. 34 | repeated HttpRule rules = 1; 35 | 36 | // When set to true, URL path parameters will be fully URI-decoded except in 37 | // cases of single segment matches in reserved expansion, where "%2F" will be 38 | // left encoded. 39 | // 40 | // The default behavior is to not decode RFC 6570 reserved characters in multi 41 | // segment matches. 42 | bool fully_decode_reserved_expansion = 2; 43 | } 44 | 45 | // # gRPC Transcoding 46 | // 47 | // gRPC Transcoding is a feature for mapping between a gRPC method and one or 48 | // more HTTP REST endpoints. It allows developers to build a single API service 49 | // that supports both gRPC APIs and REST APIs. Many systems, including [Google 50 | // APIs](https://github.com/googleapis/googleapis), 51 | // [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC 52 | // Gateway](https://github.com/grpc-ecosystem/grpc-gateway), 53 | // and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature 54 | // and use it for large scale production services. 55 | // 56 | // `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies 57 | // how different portions of the gRPC request message are mapped to the URL 58 | // path, URL query parameters, and HTTP request body. It also controls how the 59 | // gRPC response message is mapped to the HTTP response body. `HttpRule` is 60 | // typically specified as an `google.api.http` annotation on the gRPC method. 61 | // 62 | // Each mapping specifies a URL path template and an HTTP method. The path 63 | // template may refer to one or more fields in the gRPC request message, as long 64 | // as each field is a non-repeated field with a primitive (non-message) type. 65 | // The path template controls how fields of the request message are mapped to 66 | // the URL path. 67 | // 68 | // Example: 69 | // 70 | // service Messaging { 71 | // rpc GetMessage(GetMessageRequest) returns (Message) { 72 | // option (google.api.http) = { 73 | // get: "/v1/{name=messages/*}" 74 | // }; 75 | // } 76 | // } 77 | // message GetMessageRequest { 78 | // string name = 1; // Mapped to URL path. 79 | // } 80 | // message Message { 81 | // string text = 1; // The resource content. 82 | // } 83 | // 84 | // This enables an HTTP REST to gRPC mapping as below: 85 | // 86 | // HTTP | gRPC 87 | // -----|----- 88 | // `GET /v1/messages/123456` | `GetMessage(name: "messages/123456")` 89 | // 90 | // Any fields in the request message which are not bound by the path template 91 | // automatically become HTTP query parameters if there is no HTTP request body. 92 | // For example: 93 | // 94 | // service Messaging { 95 | // rpc GetMessage(GetMessageRequest) returns (Message) { 96 | // option (google.api.http) = { 97 | // get:"/v1/messages/{message_id}" 98 | // }; 99 | // } 100 | // } 101 | // message GetMessageRequest { 102 | // message SubMessage { 103 | // string subfield = 1; 104 | // } 105 | // string message_id = 1; // Mapped to URL path. 106 | // int64 revision = 2; // Mapped to URL query parameter `revision`. 107 | // SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`. 108 | // } 109 | // 110 | // This enables a HTTP JSON to RPC mapping as below: 111 | // 112 | // HTTP | gRPC 113 | // -----|----- 114 | // `GET /v1/messages/123456?revision=2&sub.subfield=foo` | 115 | // `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: 116 | // "foo"))` 117 | // 118 | // Note that fields which are mapped to URL query parameters must have a 119 | // primitive type or a repeated primitive type or a non-repeated message type. 120 | // In the case of a repeated type, the parameter can be repeated in the URL 121 | // as `...?param=A¶m=B`. In the case of a message type, each field of the 122 | // message is mapped to a separate parameter, such as 123 | // `...?foo.a=A&foo.b=B&foo.c=C`. 124 | // 125 | // For HTTP methods that allow a request body, the `body` field 126 | // specifies the mapping. Consider a REST update method on the 127 | // message resource collection: 128 | // 129 | // service Messaging { 130 | // rpc UpdateMessage(UpdateMessageRequest) returns (Message) { 131 | // option (google.api.http) = { 132 | // patch: "/v1/messages/{message_id}" 133 | // body: "message" 134 | // }; 135 | // } 136 | // } 137 | // message UpdateMessageRequest { 138 | // string message_id = 1; // mapped to the URL 139 | // Message message = 2; // mapped to the body 140 | // } 141 | // 142 | // The following HTTP JSON to RPC mapping is enabled, where the 143 | // representation of the JSON in the request body is determined by 144 | // protos JSON encoding: 145 | // 146 | // HTTP | gRPC 147 | // -----|----- 148 | // `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: 149 | // "123456" message { text: "Hi!" })` 150 | // 151 | // The special name `*` can be used in the body mapping to define that 152 | // every field not bound by the path template should be mapped to the 153 | // request body. This enables the following alternative definition of 154 | // the update method: 155 | // 156 | // service Messaging { 157 | // rpc UpdateMessage(Message) returns (Message) { 158 | // option (google.api.http) = { 159 | // patch: "/v1/messages/{message_id}" 160 | // body: "*" 161 | // }; 162 | // } 163 | // } 164 | // message Message { 165 | // string message_id = 1; 166 | // string text = 2; 167 | // } 168 | // 169 | // 170 | // The following HTTP JSON to RPC mapping is enabled: 171 | // 172 | // HTTP | gRPC 173 | // -----|----- 174 | // `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: 175 | // "123456" text: "Hi!")` 176 | // 177 | // Note that when using `*` in the body mapping, it is not possible to 178 | // have HTTP parameters, as all fields not bound by the path end in 179 | // the body. This makes this option more rarely used in practice when 180 | // defining REST APIs. The common usage of `*` is in custom methods 181 | // which don't use the URL at all for transferring data. 182 | // 183 | // It is possible to define multiple HTTP methods for one RPC by using 184 | // the `additional_bindings` option. Example: 185 | // 186 | // service Messaging { 187 | // rpc GetMessage(GetMessageRequest) returns (Message) { 188 | // option (google.api.http) = { 189 | // get: "/v1/messages/{message_id}" 190 | // additional_bindings { 191 | // get: "/v1/users/{user_id}/messages/{message_id}" 192 | // } 193 | // }; 194 | // } 195 | // } 196 | // message GetMessageRequest { 197 | // string message_id = 1; 198 | // string user_id = 2; 199 | // } 200 | // 201 | // This enables the following two alternative HTTP JSON to RPC mappings: 202 | // 203 | // HTTP | gRPC 204 | // -----|----- 205 | // `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` 206 | // `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: 207 | // "123456")` 208 | // 209 | // ## Rules for HTTP mapping 210 | // 211 | // 1. Leaf request fields (recursive expansion nested messages in the request 212 | // message) are classified into three categories: 213 | // - Fields referred by the path template. They are passed via the URL path. 214 | // - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They are passed via the HTTP 215 | // request body. 216 | // - All other fields are passed via the URL query parameters, and the 217 | // parameter name is the field path in the request message. A repeated 218 | // field can be represented as multiple query parameters under the same 219 | // name. 220 | // 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL query parameter, all fields 221 | // are passed via URL path and HTTP request body. 222 | // 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP request body, all 223 | // fields are passed via URL path and URL query parameters. 224 | // 225 | // ### Path template syntax 226 | // 227 | // Template = "/" Segments [ Verb ] ; 228 | // Segments = Segment { "/" Segment } ; 229 | // Segment = "*" | "**" | LITERAL | Variable ; 230 | // Variable = "{" FieldPath [ "=" Segments ] "}" ; 231 | // FieldPath = IDENT { "." IDENT } ; 232 | // Verb = ":" LITERAL ; 233 | // 234 | // The syntax `*` matches a single URL path segment. The syntax `**` matches 235 | // zero or more URL path segments, which must be the last part of the URL path 236 | // except the `Verb`. 237 | // 238 | // The syntax `Variable` matches part of the URL path as specified by its 239 | // template. A variable template must not contain other variables. If a variable 240 | // matches a single path segment, its template may be omitted, e.g. `{var}` 241 | // is equivalent to `{var=*}`. 242 | // 243 | // The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL` 244 | // contains any reserved character, such characters should be percent-encoded 245 | // before the matching. 246 | // 247 | // If a variable contains exactly one path segment, such as `"{var}"` or 248 | // `"{var=*}"`, when such a variable is expanded into a URL path on the client 249 | // side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The 250 | // server side does the reverse decoding. Such variables show up in the 251 | // [Discovery 252 | // Document](https://developers.google.com/discovery/v1/reference/apis) as 253 | // `{var}`. 254 | // 255 | // If a variable contains multiple path segments, such as `"{var=foo/*}"` 256 | // or `"{var=**}"`, when such a variable is expanded into a URL path on the 257 | // client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. 258 | // The server side does the reverse decoding, except "%2F" and "%2f" are left 259 | // unchanged. Such variables show up in the 260 | // [Discovery 261 | // Document](https://developers.google.com/discovery/v1/reference/apis) as 262 | // `{+var}`. 263 | // 264 | // ## Using gRPC API Service Configuration 265 | // 266 | // gRPC API Service Configuration (service config) is a configuration language 267 | // for configuring a gRPC service to become a user-facing product. The 268 | // service config is simply the YAML representation of the `google.api.Service` 269 | // proto message. 270 | // 271 | // As an alternative to annotating your proto file, you can configure gRPC 272 | // transcoding in your service config YAML files. You do this by specifying a 273 | // `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same 274 | // effect as the proto annotation. This can be particularly useful if you 275 | // have a proto that is reused in multiple services. Note that any transcoding 276 | // specified in the service config will override any matching transcoding 277 | // configuration in the proto. 278 | // 279 | // Example: 280 | // 281 | // http: 282 | // rules: 283 | // # Selects a gRPC method and applies HttpRule to it. 284 | // - selector: example.v1.Messaging.GetMessage 285 | // get: /v1/messages/{message_id}/{sub.subfield} 286 | // 287 | // ## Special notes 288 | // 289 | // When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the 290 | // proto to JSON conversion must follow the [proto3 291 | // specification](https://developers.google.com/protocol-buffers/docs/proto3#json). 292 | // 293 | // While the single segment variable follows the semantics of 294 | // [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String 295 | // Expansion, the multi segment variable **does not** follow RFC 6570 Section 296 | // 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion 297 | // does not expand special characters like `?` and `#`, which would lead 298 | // to invalid URLs. As the result, gRPC Transcoding uses a custom encoding 299 | // for multi segment variables. 300 | // 301 | // The path variables **must not** refer to any repeated or mapped field, 302 | // because client libraries are not capable of handling such variable expansion. 303 | // 304 | // The path variables **must not** capture the leading "/" character. The reason 305 | // is that the most common use case "{var}" does not capture the leading "/" 306 | // character. For consistency, all path variables must share the same behavior. 307 | // 308 | // Repeated message fields must not be mapped to URL query parameters, because 309 | // no client library can support such complicated mapping. 310 | // 311 | // If an API needs to use a JSON array for request or response body, it can map 312 | // the request or response body to a repeated field. However, some gRPC 313 | // Transcoding implementations may not support this feature. 314 | message HttpRule { 315 | // Selects a method to which this rule applies. 316 | // 317 | // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. 318 | string selector = 1; 319 | 320 | // Determines the URL pattern is matched by this rules. This pattern can be 321 | // used with any of the {get|put|post|delete|patch} methods. A custom method 322 | // can be defined using the 'custom' field. 323 | oneof pattern { 324 | // Maps to HTTP GET. Used for listing and getting information about 325 | // resources. 326 | string get = 2; 327 | 328 | // Maps to HTTP PUT. Used for replacing a resource. 329 | string put = 3; 330 | 331 | // Maps to HTTP POST. Used for creating a resource or performing an action. 332 | string post = 4; 333 | 334 | // Maps to HTTP DELETE. Used for deleting a resource. 335 | string delete = 5; 336 | 337 | // Maps to HTTP PATCH. Used for updating a resource. 338 | string patch = 6; 339 | 340 | // The custom pattern is used for specifying an HTTP method that is not 341 | // included in the `pattern` field, such as HEAD, or "*" to leave the 342 | // HTTP method unspecified for this rule. The wild-card rule is useful 343 | // for services that provide content to Web (HTML) clients. 344 | CustomHttpPattern custom = 8; 345 | } 346 | 347 | // The name of the request field whose value is mapped to the HTTP request 348 | // body, or `*` for mapping all request fields not captured by the path 349 | // pattern to the HTTP body, or omitted for not having any HTTP request body. 350 | // 351 | // NOTE: the referred field must be present at the top-level of the request 352 | // message type. 353 | string body = 7; 354 | 355 | // Optional. The name of the response field whose value is mapped to the HTTP 356 | // response body. When omitted, the entire response message will be used 357 | // as the HTTP response body. 358 | // 359 | // NOTE: The referred field must be present at the top-level of the response 360 | // message type. 361 | string response_body = 12; 362 | 363 | // Additional HTTP bindings for the selector. Nested bindings must 364 | // not contain an `additional_bindings` field themselves (that is, 365 | // the nesting may only be one level deep). 366 | repeated HttpRule additional_bindings = 11; 367 | } 368 | 369 | // A custom pattern is used for defining custom HTTP verb. 370 | message CustomHttpPattern { 371 | // The name of this custom HTTP verb. 372 | string kind = 1; 373 | 374 | // The path matched by this custom verb. 375 | string path = 2; 376 | } -------------------------------------------------------------------------------- /protos/google/api/resource.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | 16 | syntax = "proto3"; 17 | 18 | package google.api; 19 | 20 | import "google/protobuf/descriptor.proto"; 21 | 22 | option cc_enable_arenas = true; 23 | option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; 24 | option java_multiple_files = true; 25 | option java_outer_classname = "ResourceProto"; 26 | option java_package = "com.google.api"; 27 | option objc_class_prefix = "GAPI"; 28 | 29 | extend google.protobuf.FieldOptions { 30 | // An annotation that describes a resource reference, see 31 | // [ResourceReference][]. 32 | google.api.ResourceReference resource_reference = 1055; 33 | } 34 | 35 | extend google.protobuf.FileOptions { 36 | // An annotation that describes a resource definition without a corresponding 37 | // message; see [ResourceDescriptor][]. 38 | repeated google.api.ResourceDescriptor resource_definition = 1053; 39 | } 40 | 41 | extend google.protobuf.MessageOptions { 42 | // An annotation that describes a resource definition, see 43 | // [ResourceDescriptor][]. 44 | google.api.ResourceDescriptor resource = 1053; 45 | } 46 | 47 | // A simple descriptor of a resource type. 48 | // 49 | // ResourceDescriptor annotates a resource message (either by means of a 50 | // protobuf annotation or use in the service config), and associates the 51 | // resource's schema, the resource type, and the pattern of the resource name. 52 | // 53 | // Example: 54 | // 55 | // message Topic { 56 | // // Indicates this message defines a resource schema. 57 | // // Declares the resource type in the format of {service}/{kind}. 58 | // // For Kubernetes resources, the format is {api group}/{kind}. 59 | // option (google.api.resource) = { 60 | // type: "pubsub.googleapis.com/Topic" 61 | // name_descriptor: { 62 | // pattern: "projects/{project}/topics/{topic}" 63 | // parent_type: "cloudresourcemanager.googleapis.com/Project" 64 | // parent_name_extractor: "projects/{project}" 65 | // } 66 | // }; 67 | // } 68 | // 69 | // The ResourceDescriptor Yaml config will look like: 70 | // 71 | // resources: 72 | // - type: "pubsub.googleapis.com/Topic" 73 | // name_descriptor: 74 | // - pattern: "projects/{project}/topics/{topic}" 75 | // parent_type: "cloudresourcemanager.googleapis.com/Project" 76 | // parent_name_extractor: "projects/{project}" 77 | // 78 | // Sometimes, resources have multiple patterns, typically because they can 79 | // live under multiple parents. 80 | // 81 | // Example: 82 | // 83 | // message LogEntry { 84 | // option (google.api.resource) = { 85 | // type: "logging.googleapis.com/LogEntry" 86 | // name_descriptor: { 87 | // pattern: "projects/{project}/logs/{log}" 88 | // parent_type: "cloudresourcemanager.googleapis.com/Project" 89 | // parent_name_extractor: "projects/{project}" 90 | // } 91 | // name_descriptor: { 92 | // pattern: "folders/{folder}/logs/{log}" 93 | // parent_type: "cloudresourcemanager.googleapis.com/Folder" 94 | // parent_name_extractor: "folders/{folder}" 95 | // } 96 | // name_descriptor: { 97 | // pattern: "organizations/{organization}/logs/{log}" 98 | // parent_type: "cloudresourcemanager.googleapis.com/Organization" 99 | // parent_name_extractor: "organizations/{organization}" 100 | // } 101 | // name_descriptor: { 102 | // pattern: "billingAccounts/{billing_account}/logs/{log}" 103 | // parent_type: "billing.googleapis.com/BillingAccount" 104 | // parent_name_extractor: "billingAccounts/{billing_account}" 105 | // } 106 | // }; 107 | // } 108 | // 109 | // The ResourceDescriptor Yaml config will look like: 110 | // 111 | // resources: 112 | // - type: 'logging.googleapis.com/LogEntry' 113 | // name_descriptor: 114 | // - pattern: "projects/{project}/logs/{log}" 115 | // parent_type: "cloudresourcemanager.googleapis.com/Project" 116 | // parent_name_extractor: "projects/{project}" 117 | // - pattern: "folders/{folder}/logs/{log}" 118 | // parent_type: "cloudresourcemanager.googleapis.com/Folder" 119 | // parent_name_extractor: "folders/{folder}" 120 | // - pattern: "organizations/{organization}/logs/{log}" 121 | // parent_type: "cloudresourcemanager.googleapis.com/Organization" 122 | // parent_name_extractor: "organizations/{organization}" 123 | // - pattern: "billingAccounts/{billing_account}/logs/{log}" 124 | // parent_type: "billing.googleapis.com/BillingAccount" 125 | // parent_name_extractor: "billingAccounts/{billing_account}" 126 | // 127 | // For flexible resources, the resource name doesn't contain parent names, but 128 | // the resource itself has parents for policy evaluation. 129 | // 130 | // Example: 131 | // 132 | // message Shelf { 133 | // option (google.api.resource) = { 134 | // type: "library.googleapis.com/Shelf" 135 | // name_descriptor: { 136 | // pattern: "shelves/{shelf}" 137 | // parent_type: "cloudresourcemanager.googleapis.com/Project" 138 | // } 139 | // name_descriptor: { 140 | // pattern: "shelves/{shelf}" 141 | // parent_type: "cloudresourcemanager.googleapis.com/Folder" 142 | // } 143 | // }; 144 | // } 145 | // 146 | // The ResourceDescriptor Yaml config will look like: 147 | // 148 | // resources: 149 | // - type: 'library.googleapis.com/Shelf' 150 | // name_descriptor: 151 | // - pattern: "shelves/{shelf}" 152 | // parent_type: "cloudresourcemanager.googleapis.com/Project" 153 | // - pattern: "shelves/{shelf}" 154 | // parent_type: "cloudresourcemanager.googleapis.com/Folder" 155 | message ResourceDescriptor { 156 | // A description of the historical or future-looking state of the 157 | // resource pattern. 158 | enum History { 159 | // The "unset" value. 160 | HISTORY_UNSPECIFIED = 0; 161 | 162 | // The resource originally had one pattern and launched as such, and 163 | // additional patterns were added later. 164 | ORIGINALLY_SINGLE_PATTERN = 1; 165 | 166 | // The resource has one pattern, but the API owner expects to add more 167 | // later. (This is the inverse of ORIGINALLY_SINGLE_PATTERN, and prevents 168 | // that from being necessary once there are multiple patterns.) 169 | FUTURE_MULTI_PATTERN = 2; 170 | } 171 | 172 | // The resource type. It must be in the format of 173 | // {service_name}/{resource_type_kind}. The `resource_type_kind` must be 174 | // singular and must not include version numbers. 175 | // 176 | // Example: `storage.googleapis.com/Bucket` 177 | // 178 | // The value of the resource_type_kind must follow the regular expression 179 | // /[A-Za-z][a-zA-Z0-9]+/. It should start with an upper case character and 180 | // should use PascalCase (UpperCamelCase). The maximum number of 181 | // characters allowed for the `resource_type_kind` is 100. 182 | string type = 1; 183 | 184 | // Optional. The relative resource name pattern associated with this resource 185 | // type. The DNS prefix of the full resource name shouldn't be specified here. 186 | // 187 | // The path pattern must follow the syntax, which aligns with HTTP binding 188 | // syntax: 189 | // 190 | // Template = Segment { "/" Segment } ; 191 | // Segment = LITERAL | Variable ; 192 | // Variable = "{" LITERAL "}" ; 193 | // 194 | // Examples: 195 | // 196 | // - "projects/{project}/topics/{topic}" 197 | // - "projects/{project}/knowledgeBases/{knowledge_base}" 198 | // 199 | // The components in braces correspond to the IDs for each resource in the 200 | // hierarchy. It is expected that, if multiple patterns are provided, 201 | // the same component name (e.g. "project") refers to IDs of the same 202 | // type of resource. 203 | repeated string pattern = 2; 204 | 205 | // Optional. The field on the resource that designates the resource name 206 | // field. If omitted, this is assumed to be "name". 207 | string name_field = 3; 208 | 209 | // Optional. The historical or future-looking state of the resource pattern. 210 | // 211 | // Example: 212 | // 213 | // // The InspectTemplate message originally only supported resource 214 | // // names with organization, and project was added later. 215 | // message InspectTemplate { 216 | // option (google.api.resource) = { 217 | // type: "dlp.googleapis.com/InspectTemplate" 218 | // pattern: 219 | // "organizations/{organization}/inspectTemplates/{inspect_template}" 220 | // pattern: "projects/{project}/inspectTemplates/{inspect_template}" 221 | // history: ORIGINALLY_SINGLE_PATTERN 222 | // }; 223 | // } 224 | History history = 4; 225 | 226 | // The plural name used in the resource name, such as 'projects' for 227 | // the name of 'projects/{project}'. It is the same concept of the `plural` 228 | // field in k8s CRD spec 229 | // https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ 230 | string plural = 5; 231 | 232 | // The same concept of the `singular` field in k8s CRD spec 233 | // https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ 234 | // Such as "project" for the `resourcemanager.googleapis.com/Project` type. 235 | string singular = 6; 236 | } 237 | 238 | // Defines a proto annotation that describes a string field that refers to 239 | // an API resource. 240 | message ResourceReference { 241 | // The resource type that the annotated field references. 242 | // 243 | // Example: 244 | // 245 | // message Subscription { 246 | // string topic = 2 [(google.api.resource_reference) = { 247 | // type: "pubsub.googleapis.com/Topic" 248 | // }]; 249 | // } 250 | string type = 1; 251 | 252 | // The resource type of a child collection that the annotated field 253 | // references. This is useful for annotating the `parent` field that 254 | // doesn't have a fixed resource type. 255 | // 256 | // Example: 257 | // 258 | // message ListLogEntriesRequest { 259 | // string parent = 1 [(google.api.resource_reference) = { 260 | // child_type: "logging.googleapis.com/LogEntry" 261 | // }; 262 | // } 263 | string child_type = 2; 264 | } -------------------------------------------------------------------------------- /protos/google/bigtable/v2/bigtable.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | syntax = "proto3"; 16 | 17 | package google.bigtable.v2; 18 | 19 | import "google/api/annotations.proto"; 20 | import "google/api/client.proto"; 21 | import "google/api/field_behavior.proto"; 22 | import "google/api/resource.proto"; 23 | import "google/bigtable/v2/data.proto"; 24 | import "google/protobuf/wrappers.proto"; 25 | import "google/rpc/status.proto"; 26 | 27 | option csharp_namespace = "Google.Cloud.Bigtable.V2"; 28 | option go_package = "google.golang.org/genproto/googleapis/bigtable/v2;bigtable"; 29 | option java_multiple_files = true; 30 | option java_outer_classname = "BigtableProto"; 31 | option java_package = "com.google.bigtable.v2"; 32 | option php_namespace = "Google\\Cloud\\Bigtable\\V2"; 33 | option (google.api.resource_definition) = { 34 | type: "bigtable.googleapis.com/Table" 35 | pattern: "projects/{project}/instances/{instance}/tables/{table}" 36 | }; 37 | 38 | // Service for reading from and writing to existing Bigtable tables. 39 | service Bigtable { 40 | option (google.api.default_host) = "bigtable.googleapis.com"; 41 | option (google.api.oauth_scopes) = 42 | "https://www.googleapis.com/auth/bigtable.data," 43 | "https://www.googleapis.com/auth/bigtable.data.readonly," 44 | "https://www.googleapis.com/auth/cloud-bigtable.data," 45 | "https://www.googleapis.com/auth/cloud-bigtable.data.readonly," 46 | "https://www.googleapis.com/auth/cloud-platform," 47 | "https://www.googleapis.com/auth/cloud-platform.read-only"; 48 | 49 | // Streams back the contents of all requested rows in key order, optionally 50 | // applying the same Reader filter to each. Depending on their size, 51 | // rows and cells may be broken up across multiple responses, but 52 | // atomicity of each row will still be preserved. See the 53 | // ReadRowsResponse documentation for details. 54 | rpc ReadRows(ReadRowsRequest) returns (stream ReadRowsResponse) { 55 | option (google.api.http) = { 56 | post: "/v2/{table_name=projects/*/instances/*/tables/*}:readRows" 57 | body: "*" 58 | }; 59 | option (google.api.method_signature) = "table_name"; 60 | option (google.api.method_signature) = "table_name,app_profile_id"; 61 | } 62 | 63 | // Returns a sample of row keys in the table. The returned row keys will 64 | // delimit contiguous sections of the table of approximately equal size, 65 | // which can be used to break up the data for distributed tasks like 66 | // mapreduces. 67 | rpc SampleRowKeys(SampleRowKeysRequest) returns (stream SampleRowKeysResponse) { 68 | option (google.api.http) = { 69 | get: "/v2/{table_name=projects/*/instances/*/tables/*}:sampleRowKeys" 70 | }; 71 | option (google.api.method_signature) = "table_name"; 72 | option (google.api.method_signature) = "table_name,app_profile_id"; 73 | } 74 | 75 | // Mutates a row atomically. Cells already present in the row are left 76 | // unchanged unless explicitly changed by `mutation`. 77 | rpc MutateRow(MutateRowRequest) returns (MutateRowResponse) { 78 | option (google.api.http) = { 79 | post: "/v2/{table_name=projects/*/instances/*/tables/*}:mutateRow" 80 | body: "*" 81 | }; 82 | option (google.api.method_signature) = "table_name,row_key,mutations"; 83 | option (google.api.method_signature) = "table_name,row_key,mutations,app_profile_id"; 84 | } 85 | 86 | // Mutates multiple rows in a batch. Each individual row is mutated 87 | // atomically as in MutateRow, but the entire batch is not executed 88 | // atomically. 89 | rpc MutateRows(MutateRowsRequest) returns (stream MutateRowsResponse) { 90 | option (google.api.http) = { 91 | post: "/v2/{table_name=projects/*/instances/*/tables/*}:mutateRows" 92 | body: "*" 93 | }; 94 | option (google.api.method_signature) = "table_name,entries"; 95 | option (google.api.method_signature) = "table_name,entries,app_profile_id"; 96 | } 97 | 98 | // Mutates a row atomically based on the output of a predicate Reader filter. 99 | rpc CheckAndMutateRow(CheckAndMutateRowRequest) returns (CheckAndMutateRowResponse) { 100 | option (google.api.http) = { 101 | post: "/v2/{table_name=projects/*/instances/*/tables/*}:checkAndMutateRow" 102 | body: "*" 103 | }; 104 | option (google.api.method_signature) = "table_name,row_key,predicate_filter,true_mutations,false_mutations"; 105 | option (google.api.method_signature) = "table_name,row_key,predicate_filter,true_mutations,false_mutations,app_profile_id"; 106 | } 107 | 108 | // Modifies a row atomically on the server. The method reads the latest 109 | // existing timestamp and value from the specified columns and writes a new 110 | // entry based on pre-defined read/modify/write rules. The new value for the 111 | // timestamp is the greater of the existing timestamp or the current server 112 | // time. The method returns the new contents of all modified cells. 113 | rpc ReadModifyWriteRow(ReadModifyWriteRowRequest) returns (ReadModifyWriteRowResponse) { 114 | option (google.api.http) = { 115 | post: "/v2/{table_name=projects/*/instances/*/tables/*}:readModifyWriteRow" 116 | body: "*" 117 | }; 118 | option (google.api.method_signature) = "table_name,row_key,rules"; 119 | option (google.api.method_signature) = "table_name,row_key,rules,app_profile_id"; 120 | } 121 | } 122 | 123 | // Request message for Bigtable.ReadRows. 124 | message ReadRowsRequest { 125 | // Required. The unique name of the table from which to read. 126 | // Values are of the form 127 | // `projects//instances//tables/`. 128 | string table_name = 1 [ 129 | (google.api.field_behavior) = REQUIRED, 130 | (google.api.resource_reference) = { 131 | type: "bigtable.googleapis.com/Table" 132 | } 133 | ]; 134 | 135 | // This value specifies routing for replication. If not specified, the 136 | // "default" application profile will be used. 137 | string app_profile_id = 5; 138 | 139 | // The row keys and/or ranges to read. If not specified, reads from all rows. 140 | RowSet rows = 2; 141 | 142 | // The filter to apply to the contents of the specified row(s). If unset, 143 | // reads the entirety of each row. 144 | RowFilter filter = 3; 145 | 146 | // The read will terminate after committing to N rows' worth of results. The 147 | // default (zero) is to return all results. 148 | int64 rows_limit = 4; 149 | } 150 | 151 | // Response message for Bigtable.ReadRows. 152 | message ReadRowsResponse { 153 | // Specifies a piece of a row's contents returned as part of the read 154 | // response stream. 155 | message CellChunk { 156 | // The row key for this chunk of data. If the row key is empty, 157 | // this CellChunk is a continuation of the same row as the previous 158 | // CellChunk in the response stream, even if that CellChunk was in a 159 | // previous ReadRowsResponse message. 160 | // 161 | // Classified as IDENTIFYING_ID to provide context around data accesses for 162 | // auditing systems. 163 | bytes row_key = 1; 164 | 165 | // The column family name for this chunk of data. If this message 166 | // is not present this CellChunk is a continuation of the same column 167 | // family as the previous CellChunk. The empty string can occur as a 168 | // column family name in a response so clients must check 169 | // explicitly for the presence of this message, not just for 170 | // `family_name.value` being non-empty. 171 | google.protobuf.StringValue family_name = 2; 172 | 173 | // The column qualifier for this chunk of data. If this message 174 | // is not present, this CellChunk is a continuation of the same column 175 | // as the previous CellChunk. Column qualifiers may be empty so 176 | // clients must check for the presence of this message, not just 177 | // for `qualifier.value` being non-empty. 178 | google.protobuf.BytesValue qualifier = 3; 179 | 180 | // The cell's stored timestamp, which also uniquely identifies it 181 | // within its column. Values are always expressed in 182 | // microseconds, but individual tables may set a coarser 183 | // granularity to further restrict the allowed values. For 184 | // example, a table which specifies millisecond granularity will 185 | // only allow values of `timestamp_micros` which are multiples of 186 | // 1000. Timestamps are only set in the first CellChunk per cell 187 | // (for cells split into multiple chunks). 188 | int64 timestamp_micros = 4; 189 | 190 | // Labels applied to the cell by a 191 | // [RowFilter][google.bigtable.v2.RowFilter]. Labels are only set 192 | // on the first CellChunk per cell. 193 | repeated string labels = 5; 194 | 195 | // The value stored in the cell. Cell values can be split across 196 | // multiple CellChunks. In that case only the value field will be 197 | // set in CellChunks after the first: the timestamp and labels 198 | // will only be present in the first CellChunk, even if the first 199 | // CellChunk came in a previous ReadRowsResponse. 200 | bytes value = 6; 201 | 202 | // If this CellChunk is part of a chunked cell value and this is 203 | // not the final chunk of that cell, value_size will be set to the 204 | // total length of the cell value. The client can use this size 205 | // to pre-allocate memory to hold the full cell value. 206 | int32 value_size = 7; 207 | 208 | // Signals to the client concerning previous CellChunks received. 209 | oneof row_status { 210 | // Indicates that the client should drop all previous chunks for 211 | // `row_key`, as it will be re-read from the beginning. 212 | bool reset_row = 8; 213 | 214 | // Indicates that the client can safely process all previous chunks for 215 | // `row_key`, as its data has been fully read. 216 | bool commit_row = 9; 217 | } 218 | } 219 | 220 | // A collection of a row's contents as part of the read request. 221 | repeated CellChunk chunks = 1; 222 | 223 | // Optionally the server might return the row key of the last row it 224 | // has scanned. The client can use this to construct a more 225 | // efficient retry request if needed: any row keys or portions of 226 | // ranges less than this row key can be dropped from the request. 227 | // This is primarily useful for cases where the server has read a 228 | // lot of data that was filtered out since the last committed row 229 | // key, allowing the client to skip that work on a retry. 230 | bytes last_scanned_row_key = 2; 231 | } 232 | 233 | // Request message for Bigtable.SampleRowKeys. 234 | message SampleRowKeysRequest { 235 | // Required. The unique name of the table from which to sample row keys. 236 | // Values are of the form 237 | // `projects//instances//tables/
`. 238 | string table_name = 1 [ 239 | (google.api.field_behavior) = REQUIRED, 240 | (google.api.resource_reference) = { 241 | type: "bigtable.googleapis.com/Table" 242 | } 243 | ]; 244 | 245 | // This value specifies routing for replication. If not specified, the 246 | // "default" application profile will be used. 247 | string app_profile_id = 2; 248 | } 249 | 250 | // Response message for Bigtable.SampleRowKeys. 251 | message SampleRowKeysResponse { 252 | // Sorted streamed sequence of sample row keys in the table. The table might 253 | // have contents before the first row key in the list and after the last one, 254 | // but a key containing the empty string indicates "end of table" and will be 255 | // the last response given, if present. 256 | // Note that row keys in this list may not have ever been written to or read 257 | // from, and users should therefore not make any assumptions about the row key 258 | // structure that are specific to their use case. 259 | // 260 | // Classified as IDENTIFYING_ID to provide context around data accesses for 261 | // auditing systems. 262 | bytes row_key = 1; 263 | 264 | // Approximate total storage space used by all rows in the table which precede 265 | // `row_key`. Buffering the contents of all rows between two subsequent 266 | // samples would require space roughly equal to the difference in their 267 | // `offset_bytes` fields. 268 | int64 offset_bytes = 2; 269 | } 270 | 271 | // Request message for Bigtable.MutateRow. 272 | message MutateRowRequest { 273 | // Required. The unique name of the table to which the mutation should be applied. 274 | // Values are of the form 275 | // `projects//instances//tables/
`. 276 | string table_name = 1 [ 277 | (google.api.field_behavior) = REQUIRED, 278 | (google.api.resource_reference) = { 279 | type: "bigtable.googleapis.com/Table" 280 | } 281 | ]; 282 | 283 | // This value specifies routing for replication. If not specified, the 284 | // "default" application profile will be used. 285 | string app_profile_id = 4; 286 | 287 | // Required. The key of the row to which the mutation should be applied. 288 | // 289 | // Classified as IDENTIFYING_ID to provide context around data accesses for 290 | // auditing systems. 291 | bytes row_key = 2 [(google.api.field_behavior) = REQUIRED]; 292 | 293 | // Required. Changes to be atomically applied to the specified row. Entries are applied 294 | // in order, meaning that earlier mutations can be masked by later ones. 295 | // Must contain at least one entry and at most 100000. 296 | repeated Mutation mutations = 3 [(google.api.field_behavior) = REQUIRED]; 297 | } 298 | 299 | // Response message for Bigtable.MutateRow. 300 | message MutateRowResponse { 301 | 302 | } 303 | 304 | // Request message for BigtableService.MutateRows. 305 | message MutateRowsRequest { 306 | // A mutation for a given row. 307 | message Entry { 308 | // The key of the row to which the `mutations` should be applied. 309 | // 310 | // Classified as IDENTIFYING_ID to provide context around data accesses for 311 | // auditing systems. 312 | bytes row_key = 1; 313 | 314 | // Required. Changes to be atomically applied to the specified row. Mutations are 315 | // applied in order, meaning that earlier mutations can be masked by 316 | // later ones. 317 | // You must specify at least one mutation. 318 | repeated Mutation mutations = 2 [(google.api.field_behavior) = REQUIRED]; 319 | } 320 | 321 | // Required. The unique name of the table to which the mutations should be applied. 322 | string table_name = 1 [ 323 | (google.api.field_behavior) = REQUIRED, 324 | (google.api.resource_reference) = { 325 | type: "bigtable.googleapis.com/Table" 326 | } 327 | ]; 328 | 329 | // This value specifies routing for replication. If not specified, the 330 | // "default" application profile will be used. 331 | string app_profile_id = 3; 332 | 333 | // Required. The row keys and corresponding mutations to be applied in bulk. 334 | // Each entry is applied as an atomic mutation, but the entries may be 335 | // applied in arbitrary order (even between entries for the same row). 336 | // At least one entry must be specified, and in total the entries can 337 | // contain at most 100000 mutations. 338 | repeated Entry entries = 2 [(google.api.field_behavior) = REQUIRED]; 339 | } 340 | 341 | // Response message for BigtableService.MutateRows. 342 | message MutateRowsResponse { 343 | // The result of applying a passed mutation in the original request. 344 | message Entry { 345 | // The index into the original request's `entries` list of the Entry 346 | // for which a result is being reported. 347 | int64 index = 1; 348 | 349 | // The result of the request Entry identified by `index`. 350 | // Depending on how requests are batched during execution, it is possible 351 | // for one Entry to fail due to an error with another Entry. In the event 352 | // that this occurs, the same error will be reported for both entries. 353 | google.rpc.Status status = 2; 354 | } 355 | 356 | // One or more results for Entries from the batch request. 357 | repeated Entry entries = 1; 358 | } 359 | 360 | // Request message for Bigtable.CheckAndMutateRow. 361 | message CheckAndMutateRowRequest { 362 | // Required. The unique name of the table to which the conditional mutation should be 363 | // applied. 364 | // Values are of the form 365 | // `projects//instances//tables/
`. 366 | string table_name = 1 [ 367 | (google.api.field_behavior) = REQUIRED, 368 | (google.api.resource_reference) = { 369 | type: "bigtable.googleapis.com/Table" 370 | } 371 | ]; 372 | 373 | // This value specifies routing for replication. If not specified, the 374 | // "default" application profile will be used. 375 | string app_profile_id = 7; 376 | 377 | // Required. The key of the row to which the conditional mutation should be applied. 378 | // 379 | // Classified as IDENTIFYING_ID to provide context around data accesses for 380 | // auditing systems. 381 | bytes row_key = 2 [(google.api.field_behavior) = REQUIRED]; 382 | 383 | // The filter to be applied to the contents of the specified row. Depending 384 | // on whether or not any results are yielded, either `true_mutations` or 385 | // `false_mutations` will be executed. If unset, checks that the row contains 386 | // any values at all. 387 | RowFilter predicate_filter = 6; 388 | 389 | // Changes to be atomically applied to the specified row if `predicate_filter` 390 | // yields at least one cell when applied to `row_key`. Entries are applied in 391 | // order, meaning that earlier mutations can be masked by later ones. 392 | // Must contain at least one entry if `false_mutations` is empty, and at most 393 | // 100000. 394 | repeated Mutation true_mutations = 4; 395 | 396 | // Changes to be atomically applied to the specified row if `predicate_filter` 397 | // does not yield any cells when applied to `row_key`. Entries are applied in 398 | // order, meaning that earlier mutations can be masked by later ones. 399 | // Must contain at least one entry if `true_mutations` is empty, and at most 400 | // 100000. 401 | repeated Mutation false_mutations = 5; 402 | } 403 | 404 | // Response message for Bigtable.CheckAndMutateRow. 405 | message CheckAndMutateRowResponse { 406 | // Whether or not the request's `predicate_filter` yielded any results for 407 | // the specified row. 408 | bool predicate_matched = 1; 409 | } 410 | 411 | // Request message for Bigtable.ReadModifyWriteRow. 412 | message ReadModifyWriteRowRequest { 413 | // Required. The unique name of the table to which the read/modify/write rules should be 414 | // applied. 415 | // Values are of the form 416 | // `projects//instances//tables/
`. 417 | string table_name = 1 [ 418 | (google.api.field_behavior) = REQUIRED, 419 | (google.api.resource_reference) = { 420 | type: "bigtable.googleapis.com/Table" 421 | } 422 | ]; 423 | 424 | // This value specifies routing for replication. If not specified, the 425 | // "default" application profile will be used. 426 | string app_profile_id = 4; 427 | 428 | // Required. The key of the row to which the read/modify/write rules should be applied. 429 | // 430 | // Classified as IDENTIFYING_ID to provide context around data accesses for 431 | // auditing systems. 432 | bytes row_key = 2 [(google.api.field_behavior) = REQUIRED]; 433 | 434 | // Required. Rules specifying how the specified row's contents are to be transformed 435 | // into writes. Entries are applied in order, meaning that earlier rules will 436 | // affect the results of later ones. 437 | repeated ReadModifyWriteRule rules = 3 [(google.api.field_behavior) = REQUIRED]; 438 | } 439 | 440 | // Response message for Bigtable.ReadModifyWriteRow. 441 | message ReadModifyWriteRowResponse { 442 | // A Row containing the new contents of all cells modified by the request. 443 | Row row = 1; 444 | } -------------------------------------------------------------------------------- /protos/google/bigtable/v2/data.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | 16 | syntax = "proto3"; 17 | 18 | package google.bigtable.v2; 19 | 20 | option csharp_namespace = "Google.Cloud.Bigtable.V2"; 21 | option go_package = "google.golang.org/genproto/googleapis/bigtable/v2;bigtable"; 22 | option java_multiple_files = true; 23 | option java_outer_classname = "DataProto"; 24 | option java_package = "com.google.bigtable.v2"; 25 | option php_namespace = "Google\\Cloud\\Bigtable\\V2"; 26 | 27 | // Specifies the complete (requested) contents of a single row of a table. 28 | // Rows which exceed 256MiB in size cannot be read in full. 29 | message Row { 30 | // The unique key which identifies this row within its table. This is the same 31 | // key that's used to identify the row in, for example, a MutateRowRequest. 32 | // May contain any non-empty byte string up to 4KiB in length. 33 | bytes key = 1; 34 | 35 | // May be empty, but only if the entire row is empty. 36 | // The mutual ordering of column families is not specified. 37 | repeated Family families = 2; 38 | } 39 | 40 | // Specifies (some of) the contents of a single row/column family intersection 41 | // of a table. 42 | message Family { 43 | // The unique key which identifies this family within its row. This is the 44 | // same key that's used to identify the family in, for example, a RowFilter 45 | // which sets its "family_name_regex_filter" field. 46 | // Must match `[-_.a-zA-Z0-9]+`, except that AggregatingRowProcessors may 47 | // produce cells in a sentinel family with an empty name. 48 | // Must be no greater than 64 characters in length. 49 | string name = 1; 50 | 51 | // Must not be empty. Sorted in order of increasing "qualifier". 52 | repeated Column columns = 2; 53 | } 54 | 55 | // Specifies (some of) the contents of a single row/column intersection of a 56 | // table. 57 | message Column { 58 | // The unique key which identifies this column within its family. This is the 59 | // same key that's used to identify the column in, for example, a RowFilter 60 | // which sets its `column_qualifier_regex_filter` field. 61 | // May contain any byte string, including the empty string, up to 16kiB in 62 | // length. 63 | bytes qualifier = 1; 64 | 65 | // Must not be empty. Sorted in order of decreasing "timestamp_micros". 66 | repeated Cell cells = 2; 67 | } 68 | 69 | // Specifies (some of) the contents of a single row/column/timestamp of a table. 70 | message Cell { 71 | // The cell's stored timestamp, which also uniquely identifies it within 72 | // its column. 73 | // Values are always expressed in microseconds, but individual tables may set 74 | // a coarser granularity to further restrict the allowed values. For 75 | // example, a table which specifies millisecond granularity will only allow 76 | // values of `timestamp_micros` which are multiples of 1000. 77 | int64 timestamp_micros = 1; 78 | 79 | // The value stored in the cell. 80 | // May contain any byte string, including the empty string, up to 100MiB in 81 | // length. 82 | bytes value = 2; 83 | 84 | // Labels applied to the cell by a [RowFilter][google.bigtable.v2.RowFilter]. 85 | repeated string labels = 3; 86 | } 87 | 88 | // Specifies a contiguous range of rows. 89 | message RowRange { 90 | // The row key at which to start the range. 91 | // If neither field is set, interpreted as the empty string, inclusive. 92 | oneof start_key { 93 | // Used when giving an inclusive lower bound for the range. 94 | bytes start_key_closed = 1; 95 | 96 | // Used when giving an exclusive lower bound for the range. 97 | bytes start_key_open = 2; 98 | } 99 | 100 | // The row key at which to end the range. 101 | // If neither field is set, interpreted as the infinite row key, exclusive. 102 | oneof end_key { 103 | // Used when giving an exclusive upper bound for the range. 104 | bytes end_key_open = 3; 105 | 106 | // Used when giving an inclusive upper bound for the range. 107 | bytes end_key_closed = 4; 108 | } 109 | } 110 | 111 | // Specifies a non-contiguous set of rows. 112 | message RowSet { 113 | // Single rows included in the set. 114 | repeated bytes row_keys = 1; 115 | 116 | // Contiguous row ranges included in the set. 117 | repeated RowRange row_ranges = 2; 118 | } 119 | 120 | // Specifies a contiguous range of columns within a single column family. 121 | // The range spans from <column_family>:<start_qualifier> to 122 | // <column_family>:<end_qualifier>, where both bounds can be either 123 | // inclusive or exclusive. 124 | message ColumnRange { 125 | // The name of the column family within which this range falls. 126 | string family_name = 1; 127 | 128 | // The column qualifier at which to start the range (within `column_family`). 129 | // If neither field is set, interpreted as the empty string, inclusive. 130 | oneof start_qualifier { 131 | // Used when giving an inclusive lower bound for the range. 132 | bytes start_qualifier_closed = 2; 133 | 134 | // Used when giving an exclusive lower bound for the range. 135 | bytes start_qualifier_open = 3; 136 | } 137 | 138 | // The column qualifier at which to end the range (within `column_family`). 139 | // If neither field is set, interpreted as the infinite string, exclusive. 140 | oneof end_qualifier { 141 | // Used when giving an inclusive upper bound for the range. 142 | bytes end_qualifier_closed = 4; 143 | 144 | // Used when giving an exclusive upper bound for the range. 145 | bytes end_qualifier_open = 5; 146 | } 147 | } 148 | 149 | // Specified a contiguous range of microsecond timestamps. 150 | message TimestampRange { 151 | // Inclusive lower bound. If left empty, interpreted as 0. 152 | int64 start_timestamp_micros = 1; 153 | 154 | // Exclusive upper bound. If left empty, interpreted as infinity. 155 | int64 end_timestamp_micros = 2; 156 | } 157 | 158 | // Specifies a contiguous range of raw byte values. 159 | message ValueRange { 160 | // The value at which to start the range. 161 | // If neither field is set, interpreted as the empty string, inclusive. 162 | oneof start_value { 163 | // Used when giving an inclusive lower bound for the range. 164 | bytes start_value_closed = 1; 165 | 166 | // Used when giving an exclusive lower bound for the range. 167 | bytes start_value_open = 2; 168 | } 169 | 170 | // The value at which to end the range. 171 | // If neither field is set, interpreted as the infinite string, exclusive. 172 | oneof end_value { 173 | // Used when giving an inclusive upper bound for the range. 174 | bytes end_value_closed = 3; 175 | 176 | // Used when giving an exclusive upper bound for the range. 177 | bytes end_value_open = 4; 178 | } 179 | } 180 | 181 | // Takes a row as input and produces an alternate view of the row based on 182 | // specified rules. For example, a RowFilter might trim down a row to include 183 | // just the cells from columns matching a given regular expression, or might 184 | // return all the cells of a row but not their values. More complicated filters 185 | // can be composed out of these components to express requests such as, "within 186 | // every column of a particular family, give just the two most recent cells 187 | // which are older than timestamp X." 188 | // 189 | // There are two broad categories of RowFilters (true filters and transformers), 190 | // as well as two ways to compose simple filters into more complex ones 191 | // (chains and interleaves). They work as follows: 192 | // 193 | // * True filters alter the input row by excluding some of its cells wholesale 194 | // from the output row. An example of a true filter is the `value_regex_filter`, 195 | // which excludes cells whose values don't match the specified pattern. All 196 | // regex true filters use RE2 syntax (https://github.com/google/re2/wiki/Syntax) 197 | // in raw byte mode (RE2::Latin1), and are evaluated as full matches. An 198 | // important point to keep in mind is that `RE2(.)` is equivalent by default to 199 | // `RE2([^\n])`, meaning that it does not match newlines. When attempting to 200 | // match an arbitrary byte, you should therefore use the escape sequence `\C`, 201 | // which may need to be further escaped as `\\C` in your client language. 202 | // 203 | // * Transformers alter the input row by changing the values of some of its 204 | // cells in the output, without excluding them completely. Currently, the only 205 | // supported transformer is the `strip_value_transformer`, which replaces every 206 | // cell's value with the empty string. 207 | // 208 | // * Chains and interleaves are described in more detail in the 209 | // RowFilter.Chain and RowFilter.Interleave documentation. 210 | // 211 | // The total serialized size of a RowFilter message must not 212 | // exceed 4096 bytes, and RowFilters may not be nested within each other 213 | // (in Chains or Interleaves) to a depth of more than 20. 214 | message RowFilter { 215 | // A RowFilter which sends rows through several RowFilters in sequence. 216 | message Chain { 217 | // The elements of "filters" are chained together to process the input row: 218 | // in row -> f(0) -> intermediate row -> f(1) -> ... -> f(N) -> out row 219 | // The full chain is executed atomically. 220 | repeated RowFilter filters = 1; 221 | } 222 | 223 | // A RowFilter which sends each row to each of several component 224 | // RowFilters and interleaves the results. 225 | message Interleave { 226 | // The elements of "filters" all process a copy of the input row, and the 227 | // results are pooled, sorted, and combined into a single output row. 228 | // If multiple cells are produced with the same column and timestamp, 229 | // they will all appear in the output row in an unspecified mutual order. 230 | // Consider the following example, with three filters: 231 | // 232 | // input row 233 | // | 234 | // ----------------------------------------------------- 235 | // | | | 236 | // f(0) f(1) f(2) 237 | // | | | 238 | // 1: foo,bar,10,x foo,bar,10,z far,bar,7,a 239 | // 2: foo,blah,11,z far,blah,5,x far,blah,5,x 240 | // | | | 241 | // ----------------------------------------------------- 242 | // | 243 | // 1: foo,bar,10,z // could have switched with #2 244 | // 2: foo,bar,10,x // could have switched with #1 245 | // 3: foo,blah,11,z 246 | // 4: far,bar,7,a 247 | // 5: far,blah,5,x // identical to #6 248 | // 6: far,blah,5,x // identical to #5 249 | // 250 | // All interleaved filters are executed atomically. 251 | repeated RowFilter filters = 1; 252 | } 253 | 254 | // A RowFilter which evaluates one of two possible RowFilters, depending on 255 | // whether or not a predicate RowFilter outputs any cells from the input row. 256 | // 257 | // IMPORTANT NOTE: The predicate filter does not execute atomically with the 258 | // true and false filters, which may lead to inconsistent or unexpected 259 | // results. Additionally, Condition filters have poor performance, especially 260 | // when filters are set for the false condition. 261 | message Condition { 262 | // If `predicate_filter` outputs any cells, then `true_filter` will be 263 | // evaluated on the input row. Otherwise, `false_filter` will be evaluated. 264 | RowFilter predicate_filter = 1; 265 | 266 | // The filter to apply to the input row if `predicate_filter` returns any 267 | // results. If not provided, no results will be returned in the true case. 268 | RowFilter true_filter = 2; 269 | 270 | // The filter to apply to the input row if `predicate_filter` does not 271 | // return any results. If not provided, no results will be returned in the 272 | // false case. 273 | RowFilter false_filter = 3; 274 | } 275 | 276 | // Which of the possible RowFilter types to apply. If none are set, this 277 | // RowFilter returns all cells in the input row. 278 | oneof filter { 279 | // Applies several RowFilters to the data in sequence, progressively 280 | // narrowing the results. 281 | Chain chain = 1; 282 | 283 | // Applies several RowFilters to the data in parallel and combines the 284 | // results. 285 | Interleave interleave = 2; 286 | 287 | // Applies one of two possible RowFilters to the data based on the output of 288 | // a predicate RowFilter. 289 | Condition condition = 3; 290 | 291 | // ADVANCED USE ONLY. 292 | // Hook for introspection into the RowFilter. Outputs all cells directly to 293 | // the output of the read rather than to any parent filter. Consider the 294 | // following example: 295 | // 296 | // Chain( 297 | // FamilyRegex("A"), 298 | // Interleave( 299 | // All(), 300 | // Chain(Label("foo"), Sink()) 301 | // ), 302 | // QualifierRegex("B") 303 | // ) 304 | // 305 | // A,A,1,w 306 | // A,B,2,x 307 | // B,B,4,z 308 | // | 309 | // FamilyRegex("A") 310 | // | 311 | // A,A,1,w 312 | // A,B,2,x 313 | // | 314 | // +------------+-------------+ 315 | // | | 316 | // All() Label(foo) 317 | // | | 318 | // A,A,1,w A,A,1,w,labels:[foo] 319 | // A,B,2,x A,B,2,x,labels:[foo] 320 | // | | 321 | // | Sink() --------------+ 322 | // | | | 323 | // +------------+ x------+ A,A,1,w,labels:[foo] 324 | // | A,B,2,x,labels:[foo] 325 | // A,A,1,w | 326 | // A,B,2,x | 327 | // | | 328 | // QualifierRegex("B") | 329 | // | | 330 | // A,B,2,x | 331 | // | | 332 | // +--------------------------------+ 333 | // | 334 | // A,A,1,w,labels:[foo] 335 | // A,B,2,x,labels:[foo] // could be switched 336 | // A,B,2,x // could be switched 337 | // 338 | // Despite being excluded by the qualifier filter, a copy of every cell 339 | // that reaches the sink is present in the final result. 340 | // 341 | // As with an [Interleave][google.bigtable.v2.RowFilter.Interleave], 342 | // duplicate cells are possible, and appear in an unspecified mutual order. 343 | // In this case we have a duplicate with column "A:B" and timestamp 2, 344 | // because one copy passed through the all filter while the other was 345 | // passed through the label and sink. Note that one copy has label "foo", 346 | // while the other does not. 347 | // 348 | // Cannot be used within the `predicate_filter`, `true_filter`, or 349 | // `false_filter` of a [Condition][google.bigtable.v2.RowFilter.Condition]. 350 | bool sink = 16; 351 | 352 | // Matches all cells, regardless of input. Functionally equivalent to 353 | // leaving `filter` unset, but included for completeness. 354 | bool pass_all_filter = 17; 355 | 356 | // Does not match any cells, regardless of input. Useful for temporarily 357 | // disabling just part of a filter. 358 | bool block_all_filter = 18; 359 | 360 | // Matches only cells from rows whose keys satisfy the given RE2 regex. In 361 | // other words, passes through the entire row when the key matches, and 362 | // otherwise produces an empty row. 363 | // Note that, since row keys can contain arbitrary bytes, the `\C` escape 364 | // sequence must be used if a true wildcard is desired. The `.` character 365 | // will not match the new line character `\n`, which may be present in a 366 | // binary key. 367 | bytes row_key_regex_filter = 4; 368 | 369 | // Matches all cells from a row with probability p, and matches no cells 370 | // from the row with probability 1-p. 371 | double row_sample_filter = 14; 372 | 373 | // Matches only cells from columns whose families satisfy the given RE2 374 | // regex. For technical reasons, the regex must not contain the `:` 375 | // character, even if it is not being used as a literal. 376 | // Note that, since column families cannot contain the new line character 377 | // `\n`, it is sufficient to use `.` as a full wildcard when matching 378 | // column family names. 379 | string family_name_regex_filter = 5; 380 | 381 | // Matches only cells from columns whose qualifiers satisfy the given RE2 382 | // regex. 383 | // Note that, since column qualifiers can contain arbitrary bytes, the `\C` 384 | // escape sequence must be used if a true wildcard is desired. The `.` 385 | // character will not match the new line character `\n`, which may be 386 | // present in a binary qualifier. 387 | bytes column_qualifier_regex_filter = 6; 388 | 389 | // Matches only cells from columns within the given range. 390 | ColumnRange column_range_filter = 7; 391 | 392 | // Matches only cells with timestamps within the given range. 393 | TimestampRange timestamp_range_filter = 8; 394 | 395 | // Matches only cells with values that satisfy the given regular expression. 396 | // Note that, since cell values can contain arbitrary bytes, the `\C` escape 397 | // sequence must be used if a true wildcard is desired. The `.` character 398 | // will not match the new line character `\n`, which may be present in a 399 | // binary value. 400 | bytes value_regex_filter = 9; 401 | 402 | // Matches only cells with values that fall within the given range. 403 | ValueRange value_range_filter = 15; 404 | 405 | // Skips the first N cells of each row, matching all subsequent cells. 406 | // If duplicate cells are present, as is possible when using an Interleave, 407 | // each copy of the cell is counted separately. 408 | int32 cells_per_row_offset_filter = 10; 409 | 410 | // Matches only the first N cells of each row. 411 | // If duplicate cells are present, as is possible when using an Interleave, 412 | // each copy of the cell is counted separately. 413 | int32 cells_per_row_limit_filter = 11; 414 | 415 | // Matches only the most recent N cells within each column. For example, 416 | // if N=2, this filter would match column `foo:bar` at timestamps 10 and 9, 417 | // skip all earlier cells in `foo:bar`, and then begin matching again in 418 | // column `foo:bar2`. 419 | // If duplicate cells are present, as is possible when using an Interleave, 420 | // each copy of the cell is counted separately. 421 | int32 cells_per_column_limit_filter = 12; 422 | 423 | // Replaces each cell's value with the empty string. 424 | bool strip_value_transformer = 13; 425 | 426 | // Applies the given label to all cells in the output row. This allows 427 | // the client to determine which results were produced from which part of 428 | // the filter. 429 | // 430 | // Values must be at most 15 characters in length, and match the RE2 431 | // pattern `[a-z0-9\\-]+` 432 | // 433 | // Due to a technical limitation, it is not currently possible to apply 434 | // multiple labels to a cell. As a result, a Chain may have no more than 435 | // one sub-filter which contains a `apply_label_transformer`. It is okay for 436 | // an Interleave to contain multiple `apply_label_transformers`, as they 437 | // will be applied to separate copies of the input. This may be relaxed in 438 | // the future. 439 | string apply_label_transformer = 19; 440 | } 441 | } 442 | 443 | // Specifies a particular change to be made to the contents of a row. 444 | message Mutation { 445 | // A Mutation which sets the value of the specified cell. 446 | message SetCell { 447 | // The name of the family into which new data should be written. 448 | // Must match `[-_.a-zA-Z0-9]+` 449 | string family_name = 1; 450 | 451 | // The qualifier of the column into which new data should be written. 452 | // Can be any byte string, including the empty string. 453 | bytes column_qualifier = 2; 454 | 455 | // The timestamp of the cell into which new data should be written. 456 | // Use -1 for current Bigtable server time. 457 | // Otherwise, the client should set this value itself, noting that the 458 | // default value is a timestamp of zero if the field is left unspecified. 459 | // Values must match the granularity of the table (e.g. micros, millis). 460 | int64 timestamp_micros = 3; 461 | 462 | // The value to be written into the specified cell. 463 | bytes value = 4; 464 | } 465 | 466 | // A Mutation which deletes cells from the specified column, optionally 467 | // restricting the deletions to a given timestamp range. 468 | message DeleteFromColumn { 469 | // The name of the family from which cells should be deleted. 470 | // Must match `[-_.a-zA-Z0-9]+` 471 | string family_name = 1; 472 | 473 | // The qualifier of the column from which cells should be deleted. 474 | // Can be any byte string, including the empty string. 475 | bytes column_qualifier = 2; 476 | 477 | // The range of timestamps within which cells should be deleted. 478 | TimestampRange time_range = 3; 479 | } 480 | 481 | // A Mutation which deletes all cells from the specified column family. 482 | message DeleteFromFamily { 483 | // The name of the family from which cells should be deleted. 484 | // Must match `[-_.a-zA-Z0-9]+` 485 | string family_name = 1; 486 | } 487 | 488 | // A Mutation which deletes all cells from the containing row. 489 | message DeleteFromRow { 490 | 491 | } 492 | 493 | // Which of the possible Mutation types to apply. 494 | oneof mutation { 495 | // Set a cell's value. 496 | SetCell set_cell = 1; 497 | 498 | // Deletes cells from a column. 499 | DeleteFromColumn delete_from_column = 2; 500 | 501 | // Deletes cells from a column family. 502 | DeleteFromFamily delete_from_family = 3; 503 | 504 | // Deletes cells from the entire row. 505 | DeleteFromRow delete_from_row = 4; 506 | } 507 | } 508 | 509 | // Specifies an atomic read/modify/write operation on the latest value of the 510 | // specified column. 511 | message ReadModifyWriteRule { 512 | // The name of the family to which the read/modify/write should be applied. 513 | // Must match `[-_.a-zA-Z0-9]+` 514 | string family_name = 1; 515 | 516 | // The qualifier of the column to which the read/modify/write should be 517 | // applied. 518 | // Can be any byte string, including the empty string. 519 | bytes column_qualifier = 2; 520 | 521 | // The rule used to determine the column's new latest value from its current 522 | // latest value. 523 | oneof rule { 524 | // Rule specifying that `append_value` be appended to the existing value. 525 | // If the targeted cell is unset, it will be treated as containing the 526 | // empty string. 527 | bytes append_value = 3; 528 | 529 | // Rule specifying that `increment_amount` be added to the existing value. 530 | // If the targeted cell is unset, it will be treated as containing a zero. 531 | // Otherwise, the targeted cell must contain an 8-byte value (interpreted 532 | // as a 64-bit big-endian signed integer), or the entire request will fail. 533 | int64 increment_amount = 4; 534 | } 535 | } -------------------------------------------------------------------------------- /protos/google/protobuf/any.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option go_package = "github.com/golang/protobuf/ptypes/any"; 37 | option java_package = "com.google.protobuf"; 38 | option java_outer_classname = "AnyProto"; 39 | option java_multiple_files = true; 40 | option objc_class_prefix = "GPB"; 41 | 42 | // `Any` contains an arbitrary serialized protocol buffer message along with a 43 | // URL that describes the type of the serialized message. 44 | // 45 | // Protobuf library provides support to pack/unpack Any values in the form 46 | // of utility functions or additional generated methods of the Any type. 47 | // 48 | // Example 1: Pack and unpack a message in C++. 49 | // 50 | // Foo foo = ...; 51 | // Any any; 52 | // any.PackFrom(foo); 53 | // ... 54 | // if (any.UnpackTo(&foo)) { 55 | // ... 56 | // } 57 | // 58 | // Example 2: Pack and unpack a message in Java. 59 | // 60 | // Foo foo = ...; 61 | // Any any = Any.pack(foo); 62 | // ... 63 | // if (any.is(Foo.class)) { 64 | // foo = any.unpack(Foo.class); 65 | // } 66 | // 67 | // Example 3: Pack and unpack a message in Python. 68 | // 69 | // foo = Foo(...) 70 | // any = Any() 71 | // any.Pack(foo) 72 | // ... 73 | // if any.Is(Foo.DESCRIPTOR): 74 | // any.Unpack(foo) 75 | // ... 76 | // 77 | // Example 4: Pack and unpack a message in Go 78 | // 79 | // foo := &pb.Foo{...} 80 | // any, err := ptypes.MarshalAny(foo) 81 | // ... 82 | // foo := &pb.Foo{} 83 | // if err := ptypes.UnmarshalAny(any, foo); err != nil { 84 | // ... 85 | // } 86 | // 87 | // The pack methods provided by protobuf library will by default use 88 | // 'type.googleapis.com/full.type.name' as the type URL and the unpack 89 | // methods only use the fully qualified type name after the last '/' 90 | // in the type URL, for example "foo.bar.com/x/y.z" will yield type 91 | // name "y.z". 92 | // 93 | // 94 | // JSON 95 | // ==== 96 | // The JSON representation of an `Any` value uses the regular 97 | // representation of the deserialized, embedded message, with an 98 | // additional field `@type` which contains the type URL. Example: 99 | // 100 | // package google.profile; 101 | // message Person { 102 | // string first_name = 1; 103 | // string last_name = 2; 104 | // } 105 | // 106 | // { 107 | // "@type": "type.googleapis.com/google.profile.Person", 108 | // "firstName": , 109 | // "lastName": 110 | // } 111 | // 112 | // If the embedded message type is well-known and has a custom JSON 113 | // representation, that representation will be embedded adding a field 114 | // `value` which holds the custom JSON in addition to the `@type` 115 | // field. Example (for message [google.protobuf.Duration][]): 116 | // 117 | // { 118 | // "@type": "type.googleapis.com/google.protobuf.Duration", 119 | // "value": "1.212s" 120 | // } 121 | // 122 | message Any { 123 | // A URL/resource name that uniquely identifies the type of the serialized 124 | // protocol buffer message. This string must contain at least 125 | // one "/" character. The last segment of the URL's path must represent 126 | // the fully qualified name of the type (as in 127 | // `path/google.protobuf.Duration`). The name should be in a canonical form 128 | // (e.g., leading "." is not accepted). 129 | // 130 | // In practice, teams usually precompile into the binary all types that they 131 | // expect it to use in the context of Any. However, for URLs which use the 132 | // scheme `http`, `https`, or no scheme, one can optionally set up a type 133 | // server that maps type URLs to message definitions as follows: 134 | // 135 | // * If no scheme is provided, `https` is assumed. 136 | // * An HTTP GET on the URL must yield a [google.protobuf.Type][] 137 | // value in binary format, or produce an error. 138 | // * Applications are allowed to cache lookup results based on the 139 | // URL, or have them precompiled into a binary to avoid any 140 | // lookup. Therefore, binary compatibility needs to be preserved 141 | // on changes to types. (Use versioned type names to manage 142 | // breaking changes.) 143 | // 144 | // Note: this functionality is not currently available in the official 145 | // protobuf release, and it is not used for type URLs beginning with 146 | // type.googleapis.com. 147 | // 148 | // Schemes other than `http`, `https` (or the empty scheme) might be 149 | // used with implementation specific semantics. 150 | // 151 | string type_url = 1; 152 | 153 | // Must be a valid serialized protocol buffer of the above specified type. 154 | bytes value = 2; 155 | } -------------------------------------------------------------------------------- /protos/google/protobuf/descriptor.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Author: kenton@google.com (Kenton Varda) 32 | // Based on original Protocol Buffers design by 33 | // Sanjay Ghemawat, Jeff Dean, and others. 34 | // 35 | // The messages in this file describe the definitions found in .proto files. 36 | // A valid .proto file can be translated directly to a FileDescriptorProto 37 | // without any other information (e.g. without reading its imports). 38 | 39 | 40 | syntax = "proto2"; 41 | 42 | package google.protobuf; 43 | 44 | option go_package = "github.com/golang/protobuf/protoc-gen-go/descriptor;descriptor"; 45 | option java_package = "com.google.protobuf"; 46 | option java_outer_classname = "DescriptorProtos"; 47 | option csharp_namespace = "Google.Protobuf.Reflection"; 48 | option objc_class_prefix = "GPB"; 49 | option cc_enable_arenas = true; 50 | 51 | // descriptor.proto must be optimized for speed because reflection-based 52 | // algorithms don't work during bootstrapping. 53 | option optimize_for = SPEED; 54 | 55 | // The protocol compiler can output a FileDescriptorSet containing the .proto 56 | // files it parses. 57 | message FileDescriptorSet { 58 | repeated FileDescriptorProto file = 1; 59 | } 60 | 61 | // Describes a complete .proto file. 62 | message FileDescriptorProto { 63 | optional string name = 1; // file name, relative to root of source tree 64 | optional string package = 2; // e.g. "foo", "foo.bar", etc. 65 | 66 | // Names of files imported by this file. 67 | repeated string dependency = 3; 68 | // Indexes of the public imported files in the dependency list above. 69 | repeated int32 public_dependency = 10; 70 | // Indexes of the weak imported files in the dependency list. 71 | // For Google-internal migration only. Do not use. 72 | repeated int32 weak_dependency = 11; 73 | 74 | // All top-level definitions in this file. 75 | repeated DescriptorProto message_type = 4; 76 | repeated EnumDescriptorProto enum_type = 5; 77 | repeated ServiceDescriptorProto service = 6; 78 | repeated FieldDescriptorProto extension = 7; 79 | 80 | optional FileOptions options = 8; 81 | 82 | // This field contains optional information about the original source code. 83 | // You may safely remove this entire field without harming runtime 84 | // functionality of the descriptors -- the information is needed only by 85 | // development tools. 86 | optional SourceCodeInfo source_code_info = 9; 87 | 88 | // The syntax of the proto file. 89 | // The supported values are "proto2" and "proto3". 90 | optional string syntax = 12; 91 | } 92 | 93 | // Describes a message type. 94 | message DescriptorProto { 95 | optional string name = 1; 96 | 97 | repeated FieldDescriptorProto field = 2; 98 | repeated FieldDescriptorProto extension = 6; 99 | 100 | repeated DescriptorProto nested_type = 3; 101 | repeated EnumDescriptorProto enum_type = 4; 102 | 103 | message ExtensionRange { 104 | optional int32 start = 1; // Inclusive. 105 | optional int32 end = 2; // Exclusive. 106 | 107 | optional ExtensionRangeOptions options = 3; 108 | } 109 | repeated ExtensionRange extension_range = 5; 110 | 111 | repeated OneofDescriptorProto oneof_decl = 8; 112 | 113 | optional MessageOptions options = 7; 114 | 115 | // Range of reserved tag numbers. Reserved tag numbers may not be used by 116 | // fields or extension ranges in the same message. Reserved ranges may 117 | // not overlap. 118 | message ReservedRange { 119 | optional int32 start = 1; // Inclusive. 120 | optional int32 end = 2; // Exclusive. 121 | } 122 | repeated ReservedRange reserved_range = 9; 123 | // Reserved field names, which may not be used by fields in the same message. 124 | // A given name may only be reserved once. 125 | repeated string reserved_name = 10; 126 | } 127 | 128 | message ExtensionRangeOptions { 129 | // The parser stores options it doesn't recognize here. See above. 130 | repeated UninterpretedOption uninterpreted_option = 999; 131 | 132 | // Clients can define custom options in extensions of this message. See above. 133 | extensions 1000 to max; 134 | } 135 | 136 | // Describes a field within a message. 137 | message FieldDescriptorProto { 138 | enum Type { 139 | // 0 is reserved for errors. 140 | // Order is weird for historical reasons. 141 | TYPE_DOUBLE = 1; 142 | TYPE_FLOAT = 2; 143 | // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if 144 | // negative values are likely. 145 | TYPE_INT64 = 3; 146 | TYPE_UINT64 = 4; 147 | // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if 148 | // negative values are likely. 149 | TYPE_INT32 = 5; 150 | TYPE_FIXED64 = 6; 151 | TYPE_FIXED32 = 7; 152 | TYPE_BOOL = 8; 153 | TYPE_STRING = 9; 154 | // Tag-delimited aggregate. 155 | // Group type is deprecated and not supported in proto3. However, Proto3 156 | // implementations should still be able to parse the group wire format and 157 | // treat group fields as unknown fields. 158 | TYPE_GROUP = 10; 159 | TYPE_MESSAGE = 11; // Length-delimited aggregate. 160 | 161 | // New in version 2. 162 | TYPE_BYTES = 12; 163 | TYPE_UINT32 = 13; 164 | TYPE_ENUM = 14; 165 | TYPE_SFIXED32 = 15; 166 | TYPE_SFIXED64 = 16; 167 | TYPE_SINT32 = 17; // Uses ZigZag encoding. 168 | TYPE_SINT64 = 18; // Uses ZigZag encoding. 169 | } 170 | 171 | enum Label { 172 | // 0 is reserved for errors 173 | LABEL_OPTIONAL = 1; 174 | LABEL_REQUIRED = 2; 175 | LABEL_REPEATED = 3; 176 | } 177 | 178 | optional string name = 1; 179 | optional int32 number = 3; 180 | optional Label label = 4; 181 | 182 | // If type_name is set, this need not be set. If both this and type_name 183 | // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. 184 | optional Type type = 5; 185 | 186 | // For message and enum types, this is the name of the type. If the name 187 | // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping 188 | // rules are used to find the type (i.e. first the nested types within this 189 | // message are searched, then within the parent, on up to the root 190 | // namespace). 191 | optional string type_name = 6; 192 | 193 | // For extensions, this is the name of the type being extended. It is 194 | // resolved in the same manner as type_name. 195 | optional string extendee = 2; 196 | 197 | // For numeric types, contains the original text representation of the value. 198 | // For booleans, "true" or "false". 199 | // For strings, contains the default text contents (not escaped in any way). 200 | // For bytes, contains the C escaped value. All bytes >= 128 are escaped. 201 | // TODO(kenton): Base-64 encode? 202 | optional string default_value = 7; 203 | 204 | // If set, gives the index of a oneof in the containing type's oneof_decl 205 | // list. This field is a member of that oneof. 206 | optional int32 oneof_index = 9; 207 | 208 | // JSON name of this field. The value is set by protocol compiler. If the 209 | // user has set a "json_name" option on this field, that option's value 210 | // will be used. Otherwise, it's deduced from the field's name by converting 211 | // it to camelCase. 212 | optional string json_name = 10; 213 | 214 | optional FieldOptions options = 8; 215 | } 216 | 217 | // Describes a oneof. 218 | message OneofDescriptorProto { 219 | optional string name = 1; 220 | optional OneofOptions options = 2; 221 | } 222 | 223 | // Describes an enum type. 224 | message EnumDescriptorProto { 225 | optional string name = 1; 226 | 227 | repeated EnumValueDescriptorProto value = 2; 228 | 229 | optional EnumOptions options = 3; 230 | 231 | // Range of reserved numeric values. Reserved values may not be used by 232 | // entries in the same enum. Reserved ranges may not overlap. 233 | // 234 | // Note that this is distinct from DescriptorProto.ReservedRange in that it 235 | // is inclusive such that it can appropriately represent the entire int32 236 | // domain. 237 | message EnumReservedRange { 238 | optional int32 start = 1; // Inclusive. 239 | optional int32 end = 2; // Inclusive. 240 | } 241 | 242 | // Range of reserved numeric values. Reserved numeric values may not be used 243 | // by enum values in the same enum declaration. Reserved ranges may not 244 | // overlap. 245 | repeated EnumReservedRange reserved_range = 4; 246 | 247 | // Reserved enum value names, which may not be reused. A given name may only 248 | // be reserved once. 249 | repeated string reserved_name = 5; 250 | } 251 | 252 | // Describes a value within an enum. 253 | message EnumValueDescriptorProto { 254 | optional string name = 1; 255 | optional int32 number = 2; 256 | 257 | optional EnumValueOptions options = 3; 258 | } 259 | 260 | // Describes a service. 261 | message ServiceDescriptorProto { 262 | optional string name = 1; 263 | repeated MethodDescriptorProto method = 2; 264 | 265 | optional ServiceOptions options = 3; 266 | } 267 | 268 | // Describes a method of a service. 269 | message MethodDescriptorProto { 270 | optional string name = 1; 271 | 272 | // Input and output type names. These are resolved in the same way as 273 | // FieldDescriptorProto.type_name, but must refer to a message type. 274 | optional string input_type = 2; 275 | optional string output_type = 3; 276 | 277 | optional MethodOptions options = 4; 278 | 279 | // Identifies if client streams multiple client messages 280 | optional bool client_streaming = 5 [default = false]; 281 | // Identifies if server streams multiple server messages 282 | optional bool server_streaming = 6 [default = false]; 283 | } 284 | 285 | 286 | // =================================================================== 287 | // Options 288 | 289 | // Each of the definitions above may have "options" attached. These are 290 | // just annotations which may cause code to be generated slightly differently 291 | // or may contain hints for code that manipulates protocol messages. 292 | // 293 | // Clients may define custom options as extensions of the *Options messages. 294 | // These extensions may not yet be known at parsing time, so the parser cannot 295 | // store the values in them. Instead it stores them in a field in the *Options 296 | // message called uninterpreted_option. This field must have the same name 297 | // across all *Options messages. We then use this field to populate the 298 | // extensions when we build a descriptor, at which point all protos have been 299 | // parsed and so all extensions are known. 300 | // 301 | // Extension numbers for custom options may be chosen as follows: 302 | // * For options which will only be used within a single application or 303 | // organization, or for experimental options, use field numbers 50000 304 | // through 99999. It is up to you to ensure that you do not use the 305 | // same number for multiple options. 306 | // * For options which will be published and used publicly by multiple 307 | // independent entities, e-mail protobuf-global-extension-registry@google.com 308 | // to reserve extension numbers. Simply provide your project name (e.g. 309 | // Objective-C plugin) and your project website (if available) -- there's no 310 | // need to explain how you intend to use them. Usually you only need one 311 | // extension number. You can declare multiple options with only one extension 312 | // number by putting them in a sub-message. See the Custom Options section of 313 | // the docs for examples: 314 | // https://developers.google.com/protocol-buffers/docs/proto#options 315 | // If this turns out to be popular, a web service will be set up 316 | // to automatically assign option numbers. 317 | 318 | message FileOptions { 319 | 320 | // Sets the Java package where classes generated from this .proto will be 321 | // placed. By default, the proto package is used, but this is often 322 | // inappropriate because proto packages do not normally start with backwards 323 | // domain names. 324 | optional string java_package = 1; 325 | 326 | 327 | // If set, all the classes from the .proto file are wrapped in a single 328 | // outer class with the given name. This applies to both Proto1 329 | // (equivalent to the old "--one_java_file" option) and Proto2 (where 330 | // a .proto always translates to a single class, but you may want to 331 | // explicitly choose the class name). 332 | optional string java_outer_classname = 8; 333 | 334 | // If set true, then the Java code generator will generate a separate .java 335 | // file for each top-level message, enum, and service defined in the .proto 336 | // file. Thus, these types will *not* be nested inside the outer class 337 | // named by java_outer_classname. However, the outer class will still be 338 | // generated to contain the file's getDescriptor() method as well as any 339 | // top-level extensions defined in the file. 340 | optional bool java_multiple_files = 10 [default = false]; 341 | 342 | // This option does nothing. 343 | optional bool java_generate_equals_and_hash = 20 [deprecated=true]; 344 | 345 | // If set true, then the Java2 code generator will generate code that 346 | // throws an exception whenever an attempt is made to assign a non-UTF-8 347 | // byte sequence to a string field. 348 | // Message reflection will do the same. 349 | // However, an extension field still accepts non-UTF-8 byte sequences. 350 | // This option has no effect on when used with the lite runtime. 351 | optional bool java_string_check_utf8 = 27 [default = false]; 352 | 353 | 354 | // Generated classes can be optimized for speed or code size. 355 | enum OptimizeMode { 356 | SPEED = 1; // Generate complete code for parsing, serialization, 357 | // etc. 358 | CODE_SIZE = 2; // Use ReflectionOps to implement these methods. 359 | LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. 360 | } 361 | optional OptimizeMode optimize_for = 9 [default = SPEED]; 362 | 363 | // Sets the Go package where structs generated from this .proto will be 364 | // placed. If omitted, the Go package will be derived from the following: 365 | // - The basename of the package import path, if provided. 366 | // - Otherwise, the package statement in the .proto file, if present. 367 | // - Otherwise, the basename of the .proto file, without extension. 368 | optional string go_package = 11; 369 | 370 | 371 | 372 | 373 | // Should generic services be generated in each language? "Generic" services 374 | // are not specific to any particular RPC system. They are generated by the 375 | // main code generators in each language (without additional plugins). 376 | // Generic services were the only kind of service generation supported by 377 | // early versions of google.protobuf. 378 | // 379 | // Generic services are now considered deprecated in favor of using plugins 380 | // that generate code specific to your particular RPC system. Therefore, 381 | // these default to false. Old code which depends on generic services should 382 | // explicitly set them to true. 383 | optional bool cc_generic_services = 16 [default = false]; 384 | optional bool java_generic_services = 17 [default = false]; 385 | optional bool py_generic_services = 18 [default = false]; 386 | optional bool php_generic_services = 42 [default = false]; 387 | 388 | // Is this file deprecated? 389 | // Depending on the target platform, this can emit Deprecated annotations 390 | // for everything in the file, or it will be completely ignored; in the very 391 | // least, this is a formalization for deprecating files. 392 | optional bool deprecated = 23 [default = false]; 393 | 394 | // Enables the use of arenas for the proto messages in this file. This applies 395 | // only to generated classes for C++. 396 | optional bool cc_enable_arenas = 31 [default = false]; 397 | 398 | 399 | // Sets the objective c class prefix which is prepended to all objective c 400 | // generated classes from this .proto. There is no default. 401 | optional string objc_class_prefix = 36; 402 | 403 | // Namespace for generated classes; defaults to the package. 404 | optional string csharp_namespace = 37; 405 | 406 | // By default Swift generators will take the proto package and CamelCase it 407 | // replacing '.' with underscore and use that to prefix the types/symbols 408 | // defined. When this options is provided, they will use this value instead 409 | // to prefix the types/symbols defined. 410 | optional string swift_prefix = 39; 411 | 412 | // Sets the php class prefix which is prepended to all php generated classes 413 | // from this .proto. Default is empty. 414 | optional string php_class_prefix = 40; 415 | 416 | // Use this option to change the namespace of php generated classes. Default 417 | // is empty. When this option is empty, the package name will be used for 418 | // determining the namespace. 419 | optional string php_namespace = 41; 420 | 421 | // Use this option to change the namespace of php generated metadata classes. 422 | // Default is empty. When this option is empty, the proto file name will be 423 | // used for determining the namespace. 424 | optional string php_metadata_namespace = 44; 425 | 426 | // Use this option to change the package of ruby generated classes. Default 427 | // is empty. When this option is not set, the package name will be used for 428 | // determining the ruby package. 429 | optional string ruby_package = 45; 430 | 431 | 432 | // The parser stores options it doesn't recognize here. 433 | // See the documentation for the "Options" section above. 434 | repeated UninterpretedOption uninterpreted_option = 999; 435 | 436 | // Clients can define custom options in extensions of this message. 437 | // See the documentation for the "Options" section above. 438 | extensions 1000 to max; 439 | 440 | reserved 38; 441 | } 442 | 443 | message MessageOptions { 444 | // Set true to use the old proto1 MessageSet wire format for extensions. 445 | // This is provided for backwards-compatibility with the MessageSet wire 446 | // format. You should not use this for any other reason: It's less 447 | // efficient, has fewer features, and is more complicated. 448 | // 449 | // The message must be defined exactly as follows: 450 | // message Foo { 451 | // option message_set_wire_format = true; 452 | // extensions 4 to max; 453 | // } 454 | // Note that the message cannot have any defined fields; MessageSets only 455 | // have extensions. 456 | // 457 | // All extensions of your type must be singular messages; e.g. they cannot 458 | // be int32s, enums, or repeated messages. 459 | // 460 | // Because this is an option, the above two restrictions are not enforced by 461 | // the protocol compiler. 462 | optional bool message_set_wire_format = 1 [default = false]; 463 | 464 | // Disables the generation of the standard "descriptor()" accessor, which can 465 | // conflict with a field of the same name. This is meant to make migration 466 | // from proto1 easier; new code should avoid fields named "descriptor". 467 | optional bool no_standard_descriptor_accessor = 2 [default = false]; 468 | 469 | // Is this message deprecated? 470 | // Depending on the target platform, this can emit Deprecated annotations 471 | // for the message, or it will be completely ignored; in the very least, 472 | // this is a formalization for deprecating messages. 473 | optional bool deprecated = 3 [default = false]; 474 | 475 | // Whether the message is an automatically generated map entry type for the 476 | // maps field. 477 | // 478 | // For maps fields: 479 | // map map_field = 1; 480 | // The parsed descriptor looks like: 481 | // message MapFieldEntry { 482 | // option map_entry = true; 483 | // optional KeyType key = 1; 484 | // optional ValueType value = 2; 485 | // } 486 | // repeated MapFieldEntry map_field = 1; 487 | // 488 | // Implementations may choose not to generate the map_entry=true message, but 489 | // use a native map in the target language to hold the keys and values. 490 | // The reflection APIs in such implementations still need to work as 491 | // if the field is a repeated message field. 492 | // 493 | // NOTE: Do not set the option in .proto files. Always use the maps syntax 494 | // instead. The option should only be implicitly set by the proto compiler 495 | // parser. 496 | optional bool map_entry = 7; 497 | 498 | reserved 8; // javalite_serializable 499 | reserved 9; // javanano_as_lite 500 | 501 | 502 | // The parser stores options it doesn't recognize here. See above. 503 | repeated UninterpretedOption uninterpreted_option = 999; 504 | 505 | // Clients can define custom options in extensions of this message. See above. 506 | extensions 1000 to max; 507 | } 508 | 509 | message FieldOptions { 510 | // The ctype option instructs the C++ code generator to use a different 511 | // representation of the field than it normally would. See the specific 512 | // options below. This option is not yet implemented in the open source 513 | // release -- sorry, we'll try to include it in a future version! 514 | optional CType ctype = 1 [default = STRING]; 515 | enum CType { 516 | // Default mode. 517 | STRING = 0; 518 | 519 | CORD = 1; 520 | 521 | STRING_PIECE = 2; 522 | } 523 | // The packed option can be enabled for repeated primitive fields to enable 524 | // a more efficient representation on the wire. Rather than repeatedly 525 | // writing the tag and type for each element, the entire array is encoded as 526 | // a single length-delimited blob. In proto3, only explicit setting it to 527 | // false will avoid using packed encoding. 528 | optional bool packed = 2; 529 | 530 | // The jstype option determines the JavaScript type used for values of the 531 | // field. The option is permitted only for 64 bit integral and fixed types 532 | // (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING 533 | // is represented as JavaScript string, which avoids loss of precision that 534 | // can happen when a large value is converted to a floating point JavaScript. 535 | // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to 536 | // use the JavaScript "number" type. The behavior of the default option 537 | // JS_NORMAL is implementation dependent. 538 | // 539 | // This option is an enum to permit additional types to be added, e.g. 540 | // goog.math.Integer. 541 | optional JSType jstype = 6 [default = JS_NORMAL]; 542 | enum JSType { 543 | // Use the default type. 544 | JS_NORMAL = 0; 545 | 546 | // Use JavaScript strings. 547 | JS_STRING = 1; 548 | 549 | // Use JavaScript numbers. 550 | JS_NUMBER = 2; 551 | } 552 | 553 | // Should this field be parsed lazily? Lazy applies only to message-type 554 | // fields. It means that when the outer message is initially parsed, the 555 | // inner message's contents will not be parsed but instead stored in encoded 556 | // form. The inner message will actually be parsed when it is first accessed. 557 | // 558 | // This is only a hint. Implementations are free to choose whether to use 559 | // eager or lazy parsing regardless of the value of this option. However, 560 | // setting this option true suggests that the protocol author believes that 561 | // using lazy parsing on this field is worth the additional bookkeeping 562 | // overhead typically needed to implement it. 563 | // 564 | // This option does not affect the public interface of any generated code; 565 | // all method signatures remain the same. Furthermore, thread-safety of the 566 | // interface is not affected by this option; const methods remain safe to 567 | // call from multiple threads concurrently, while non-const methods continue 568 | // to require exclusive access. 569 | // 570 | // 571 | // Note that implementations may choose not to check required fields within 572 | // a lazy sub-message. That is, calling IsInitialized() on the outer message 573 | // may return true even if the inner message has missing required fields. 574 | // This is necessary because otherwise the inner message would have to be 575 | // parsed in order to perform the check, defeating the purpose of lazy 576 | // parsing. An implementation which chooses not to check required fields 577 | // must be consistent about it. That is, for any particular sub-message, the 578 | // implementation must either *always* check its required fields, or *never* 579 | // check its required fields, regardless of whether or not the message has 580 | // been parsed. 581 | optional bool lazy = 5 [default = false]; 582 | 583 | // Is this field deprecated? 584 | // Depending on the target platform, this can emit Deprecated annotations 585 | // for accessors, or it will be completely ignored; in the very least, this 586 | // is a formalization for deprecating fields. 587 | optional bool deprecated = 3 [default = false]; 588 | 589 | // For Google-internal migration only. Do not use. 590 | optional bool weak = 10 [default = false]; 591 | 592 | 593 | // The parser stores options it doesn't recognize here. See above. 594 | repeated UninterpretedOption uninterpreted_option = 999; 595 | 596 | // Clients can define custom options in extensions of this message. See above. 597 | extensions 1000 to max; 598 | 599 | reserved 4; // removed jtype 600 | } 601 | 602 | message OneofOptions { 603 | // The parser stores options it doesn't recognize here. See above. 604 | repeated UninterpretedOption uninterpreted_option = 999; 605 | 606 | // Clients can define custom options in extensions of this message. See above. 607 | extensions 1000 to max; 608 | } 609 | 610 | message EnumOptions { 611 | 612 | // Set this option to true to allow mapping different tag names to the same 613 | // value. 614 | optional bool allow_alias = 2; 615 | 616 | // Is this enum deprecated? 617 | // Depending on the target platform, this can emit Deprecated annotations 618 | // for the enum, or it will be completely ignored; in the very least, this 619 | // is a formalization for deprecating enums. 620 | optional bool deprecated = 3 [default = false]; 621 | 622 | reserved 5; // javanano_as_lite 623 | 624 | // The parser stores options it doesn't recognize here. See above. 625 | repeated UninterpretedOption uninterpreted_option = 999; 626 | 627 | // Clients can define custom options in extensions of this message. See above. 628 | extensions 1000 to max; 629 | } 630 | 631 | message EnumValueOptions { 632 | // Is this enum value deprecated? 633 | // Depending on the target platform, this can emit Deprecated annotations 634 | // for the enum value, or it will be completely ignored; in the very least, 635 | // this is a formalization for deprecating enum values. 636 | optional bool deprecated = 1 [default = false]; 637 | 638 | // The parser stores options it doesn't recognize here. See above. 639 | repeated UninterpretedOption uninterpreted_option = 999; 640 | 641 | // Clients can define custom options in extensions of this message. See above. 642 | extensions 1000 to max; 643 | } 644 | 645 | message ServiceOptions { 646 | 647 | // Note: Field numbers 1 through 32 are reserved for Google's internal RPC 648 | // framework. We apologize for hoarding these numbers to ourselves, but 649 | // we were already using them long before we decided to release Protocol 650 | // Buffers. 651 | 652 | // Is this service deprecated? 653 | // Depending on the target platform, this can emit Deprecated annotations 654 | // for the service, or it will be completely ignored; in the very least, 655 | // this is a formalization for deprecating services. 656 | optional bool deprecated = 33 [default = false]; 657 | 658 | // The parser stores options it doesn't recognize here. See above. 659 | repeated UninterpretedOption uninterpreted_option = 999; 660 | 661 | // Clients can define custom options in extensions of this message. See above. 662 | extensions 1000 to max; 663 | } 664 | 665 | message MethodOptions { 666 | 667 | // Note: Field numbers 1 through 32 are reserved for Google's internal RPC 668 | // framework. We apologize for hoarding these numbers to ourselves, but 669 | // we were already using them long before we decided to release Protocol 670 | // Buffers. 671 | 672 | // Is this method deprecated? 673 | // Depending on the target platform, this can emit Deprecated annotations 674 | // for the method, or it will be completely ignored; in the very least, 675 | // this is a formalization for deprecating methods. 676 | optional bool deprecated = 33 [default = false]; 677 | 678 | // Is this method side-effect-free (or safe in HTTP parlance), or idempotent, 679 | // or neither? HTTP based RPC implementation may choose GET verb for safe 680 | // methods, and PUT verb for idempotent methods instead of the default POST. 681 | enum IdempotencyLevel { 682 | IDEMPOTENCY_UNKNOWN = 0; 683 | NO_SIDE_EFFECTS = 1; // implies idempotent 684 | IDEMPOTENT = 2; // idempotent, but may have side effects 685 | } 686 | optional IdempotencyLevel idempotency_level = 34 687 | [default = IDEMPOTENCY_UNKNOWN]; 688 | 689 | // The parser stores options it doesn't recognize here. See above. 690 | repeated UninterpretedOption uninterpreted_option = 999; 691 | 692 | // Clients can define custom options in extensions of this message. See above. 693 | extensions 1000 to max; 694 | } 695 | 696 | 697 | // A message representing a option the parser does not recognize. This only 698 | // appears in options protos created by the compiler::Parser class. 699 | // DescriptorPool resolves these when building Descriptor objects. Therefore, 700 | // options protos in descriptor objects (e.g. returned by Descriptor::options(), 701 | // or produced by Descriptor::CopyTo()) will never have UninterpretedOptions 702 | // in them. 703 | message UninterpretedOption { 704 | // The name of the uninterpreted option. Each string represents a segment in 705 | // a dot-separated name. is_extension is true iff a segment represents an 706 | // extension (denoted with parentheses in options specs in .proto files). 707 | // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents 708 | // "foo.(bar.baz).qux". 709 | message NamePart { 710 | required string name_part = 1; 711 | required bool is_extension = 2; 712 | } 713 | repeated NamePart name = 2; 714 | 715 | // The value of the uninterpreted option, in whatever type the tokenizer 716 | // identified it as during parsing. Exactly one of these should be set. 717 | optional string identifier_value = 3; 718 | optional uint64 positive_int_value = 4; 719 | optional int64 negative_int_value = 5; 720 | optional double double_value = 6; 721 | optional bytes string_value = 7; 722 | optional string aggregate_value = 8; 723 | } 724 | 725 | // =================================================================== 726 | // Optional source code info 727 | 728 | // Encapsulates information about the original source file from which a 729 | // FileDescriptorProto was generated. 730 | message SourceCodeInfo { 731 | // A Location identifies a piece of source code in a .proto file which 732 | // corresponds to a particular definition. This information is intended 733 | // to be useful to IDEs, code indexers, documentation generators, and similar 734 | // tools. 735 | // 736 | // For example, say we have a file like: 737 | // message Foo { 738 | // optional string foo = 1; 739 | // } 740 | // Let's look at just the field definition: 741 | // optional string foo = 1; 742 | // ^ ^^ ^^ ^ ^^^ 743 | // a bc de f ghi 744 | // We have the following locations: 745 | // span path represents 746 | // [a,i) [ 4, 0, 2, 0 ] The whole field definition. 747 | // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). 748 | // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). 749 | // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). 750 | // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). 751 | // 752 | // Notes: 753 | // - A location may refer to a repeated field itself (i.e. not to any 754 | // particular index within it). This is used whenever a set of elements are 755 | // logically enclosed in a single code segment. For example, an entire 756 | // extend block (possibly containing multiple extension definitions) will 757 | // have an outer location whose path refers to the "extensions" repeated 758 | // field without an index. 759 | // - Multiple locations may have the same path. This happens when a single 760 | // logical declaration is spread out across multiple places. The most 761 | // obvious example is the "extend" block again -- there may be multiple 762 | // extend blocks in the same scope, each of which will have the same path. 763 | // - A location's span is not always a subset of its parent's span. For 764 | // example, the "extendee" of an extension declaration appears at the 765 | // beginning of the "extend" block and is shared by all extensions within 766 | // the block. 767 | // - Just because a location's span is a subset of some other location's span 768 | // does not mean that it is a descendant. For example, a "group" defines 769 | // both a type and a field in a single declaration. Thus, the locations 770 | // corresponding to the type and field and their components will overlap. 771 | // - Code which tries to interpret locations should probably be designed to 772 | // ignore those that it doesn't understand, as more types of locations could 773 | // be recorded in the future. 774 | repeated Location location = 1; 775 | message Location { 776 | // Identifies which part of the FileDescriptorProto was defined at this 777 | // location. 778 | // 779 | // Each element is a field number or an index. They form a path from 780 | // the root FileDescriptorProto to the place where the definition. For 781 | // example, this path: 782 | // [ 4, 3, 2, 7, 1 ] 783 | // refers to: 784 | // file.message_type(3) // 4, 3 785 | // .field(7) // 2, 7 786 | // .name() // 1 787 | // This is because FileDescriptorProto.message_type has field number 4: 788 | // repeated DescriptorProto message_type = 4; 789 | // and DescriptorProto.field has field number 2: 790 | // repeated FieldDescriptorProto field = 2; 791 | // and FieldDescriptorProto.name has field number 1: 792 | // optional string name = 1; 793 | // 794 | // Thus, the above path gives the location of a field name. If we removed 795 | // the last element: 796 | // [ 4, 3, 2, 7 ] 797 | // this path refers to the whole field declaration (from the beginning 798 | // of the label to the terminating semicolon). 799 | repeated int32 path = 1 [packed = true]; 800 | 801 | // Always has exactly three or four elements: start line, start column, 802 | // end line (optional, otherwise assumed same as start line), end column. 803 | // These are packed into a single field for efficiency. Note that line 804 | // and column numbers are zero-based -- typically you will want to add 805 | // 1 to each before displaying to a user. 806 | repeated int32 span = 2 [packed = true]; 807 | 808 | // If this SourceCodeInfo represents a complete declaration, these are any 809 | // comments appearing before and after the declaration which appear to be 810 | // attached to the declaration. 811 | // 812 | // A series of line comments appearing on consecutive lines, with no other 813 | // tokens appearing on those lines, will be treated as a single comment. 814 | // 815 | // leading_detached_comments will keep paragraphs of comments that appear 816 | // before (but not connected to) the current element. Each paragraph, 817 | // separated by empty lines, will be one comment element in the repeated 818 | // field. 819 | // 820 | // Only the comment content is provided; comment markers (e.g. //) are 821 | // stripped out. For block comments, leading whitespace and an asterisk 822 | // will be stripped from the beginning of each line other than the first. 823 | // Newlines are included in the output. 824 | // 825 | // Examples: 826 | // 827 | // optional int32 foo = 1; // Comment attached to foo. 828 | // // Comment attached to bar. 829 | // optional int32 bar = 2; 830 | // 831 | // optional string baz = 3; 832 | // // Comment attached to baz. 833 | // // Another line attached to baz. 834 | // 835 | // // Comment attached to qux. 836 | // // 837 | // // Another line attached to qux. 838 | // optional double qux = 4; 839 | // 840 | // // Detached comment for corge. This is not leading or trailing comments 841 | // // to qux or corge because there are blank lines separating it from 842 | // // both. 843 | // 844 | // // Detached comment for corge paragraph 2. 845 | // 846 | // optional string corge = 5; 847 | // /* Block comment attached 848 | // * to corge. Leading asterisks 849 | // * will be removed. */ 850 | // /* Block comment attached to 851 | // * grault. */ 852 | // optional int32 grault = 6; 853 | // 854 | // // ignored detached comments. 855 | optional string leading_comments = 3; 856 | optional string trailing_comments = 4; 857 | repeated string leading_detached_comments = 6; 858 | } 859 | } 860 | 861 | // Describes the relationship between generated code and its original source 862 | // file. A GeneratedCodeInfo message is associated with only one generated 863 | // source file, but may contain references to different source .proto files. 864 | message GeneratedCodeInfo { 865 | // An Annotation connects some span of text in generated code to an element 866 | // of its generating .proto file. 867 | repeated Annotation annotation = 1; 868 | message Annotation { 869 | // Identifies the element in the original source .proto file. This field 870 | // is formatted the same as SourceCodeInfo.Location.path. 871 | repeated int32 path = 1 [packed = true]; 872 | 873 | // Identifies the filesystem path to the original source .proto. 874 | optional string source_file = 2; 875 | 876 | // Identifies the starting offset in bytes in the generated code 877 | // that relates to the identified object. 878 | optional int32 begin = 3; 879 | 880 | // Identifies the ending offset in bytes in the generated code that 881 | // relates to the identified offset. The end offset should be one past 882 | // the last relevant byte (so the length of the text = end - begin). 883 | optional int32 end = 4; 884 | } 885 | } -------------------------------------------------------------------------------- /protos/google/protobuf/wrappers.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Wrappers for primitive (non-message) types. These types are useful 32 | // for embedding primitives in the `google.protobuf.Any` type and for places 33 | // where we need to distinguish between the absence of a primitive 34 | // typed field and its default value. 35 | // 36 | // These wrappers have no meaningful use within repeated fields as they lack 37 | // the ability to detect presence on individual elements. 38 | // These wrappers have no meaningful use within a map or a oneof since 39 | // individual entries of a map or fields of a oneof can already detect presence. 40 | 41 | syntax = "proto3"; 42 | 43 | package google.protobuf; 44 | 45 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 46 | option cc_enable_arenas = true; 47 | option go_package = "github.com/golang/protobuf/ptypes/wrappers"; 48 | option java_package = "com.google.protobuf"; 49 | option java_outer_classname = "WrappersProto"; 50 | option java_multiple_files = true; 51 | option objc_class_prefix = "GPB"; 52 | 53 | // Wrapper message for `double`. 54 | // 55 | // The JSON representation for `DoubleValue` is JSON number. 56 | message DoubleValue { 57 | // The double value. 58 | double value = 1; 59 | } 60 | 61 | // Wrapper message for `float`. 62 | // 63 | // The JSON representation for `FloatValue` is JSON number. 64 | message FloatValue { 65 | // The float value. 66 | float value = 1; 67 | } 68 | 69 | // Wrapper message for `int64`. 70 | // 71 | // The JSON representation for `Int64Value` is JSON string. 72 | message Int64Value { 73 | // The int64 value. 74 | int64 value = 1; 75 | } 76 | 77 | // Wrapper message for `uint64`. 78 | // 79 | // The JSON representation for `UInt64Value` is JSON string. 80 | message UInt64Value { 81 | // The uint64 value. 82 | uint64 value = 1; 83 | } 84 | 85 | // Wrapper message for `int32`. 86 | // 87 | // The JSON representation for `Int32Value` is JSON number. 88 | message Int32Value { 89 | // The int32 value. 90 | int32 value = 1; 91 | } 92 | 93 | // Wrapper message for `uint32`. 94 | // 95 | // The JSON representation for `UInt32Value` is JSON number. 96 | message UInt32Value { 97 | // The uint32 value. 98 | uint32 value = 1; 99 | } 100 | 101 | // Wrapper message for `bool`. 102 | // 103 | // The JSON representation for `BoolValue` is JSON `true` and `false`. 104 | message BoolValue { 105 | // The bool value. 106 | bool value = 1; 107 | } 108 | 109 | // Wrapper message for `string`. 110 | // 111 | // The JSON representation for `StringValue` is JSON string. 112 | message StringValue { 113 | // The string value. 114 | string value = 1; 115 | } 116 | 117 | // Wrapper message for `bytes`. 118 | // 119 | // The JSON representation for `BytesValue` is JSON string. 120 | message BytesValue { 121 | // The bytes value. 122 | bytes value = 1; 123 | } -------------------------------------------------------------------------------- /protos/google/rpc/status.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. 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 | syntax = "proto3"; 16 | 17 | package google.rpc; 18 | 19 | import "google/protobuf/any.proto"; 20 | 21 | option go_package = "google.golang.org/genproto/googleapis/rpc/status;status"; 22 | option java_multiple_files = true; 23 | option java_outer_classname = "StatusProto"; 24 | option java_package = "com.google.rpc"; 25 | option objc_class_prefix = "RPC"; 26 | 27 | // The `Status` type defines a logical error model that is suitable for 28 | // different programming environments, including REST APIs and RPC APIs. It is 29 | // used by [gRPC](https://github.com/grpc). The error model is designed to be: 30 | // 31 | // - Simple to use and understand for most users 32 | // - Flexible enough to meet unexpected needs 33 | // 34 | // # Overview 35 | // 36 | // The `Status` message contains three pieces of data: error code, error 37 | // message, and error details. The error code should be an enum value of 38 | // [google.rpc.Code][google.rpc.Code], but it may accept additional error codes 39 | // if needed. The error message should be a developer-facing English message 40 | // that helps developers *understand* and *resolve* the error. If a localized 41 | // user-facing error message is needed, put the localized message in the error 42 | // details or localize it in the client. The optional error details may contain 43 | // arbitrary information about the error. There is a predefined set of error 44 | // detail types in the package `google.rpc` that can be used for common error 45 | // conditions. 46 | // 47 | // # Language mapping 48 | // 49 | // The `Status` message is the logical representation of the error model, but it 50 | // is not necessarily the actual wire format. When the `Status` message is 51 | // exposed in different client libraries and different wire protocols, it can be 52 | // mapped differently. For example, it will likely be mapped to some exceptions 53 | // in Java, but more likely mapped to some error codes in C. 54 | // 55 | // # Other uses 56 | // 57 | // The error model and the `Status` message can be used in a variety of 58 | // environments, either with or without APIs, to provide a 59 | // consistent developer experience across different environments. 60 | // 61 | // Example uses of this error model include: 62 | // 63 | // - Partial errors. If a service needs to return partial errors to the client, 64 | // it may embed the `Status` in the normal response to indicate the partial 65 | // errors. 66 | // 67 | // - Workflow errors. A typical workflow has multiple steps. Each step may 68 | // have a `Status` message for error reporting. 69 | // 70 | // - Batch operations. If a client uses batch request and batch response, the 71 | // `Status` message should be used directly inside batch response, one for 72 | // each error sub-response. 73 | // 74 | // - Asynchronous operations. If an API call embeds asynchronous operation 75 | // results in its response, the status of those operations should be 76 | // represented directly using the `Status` message. 77 | // 78 | // - Logging. If some API errors are stored in logs, the message `Status` could 79 | // be used directly after any stripping needed for security/privacy reasons. 80 | message Status { 81 | // The status code, which should be an enum value of 82 | // [google.rpc.Code][google.rpc.Code]. 83 | int32 code = 1; 84 | 85 | // A developer-facing error message, which should be in English. Any 86 | // user-facing error message should be localized and sent in the 87 | // [google.rpc.Status.details][google.rpc.Status.details] field, or localized 88 | // by the client. 89 | string message = 2; 90 | 91 | // A list of messages that carry the error details. There is a common set of 92 | // message types for APIs to use. 93 | repeated google.protobuf.Any details = 3; 94 | } -------------------------------------------------------------------------------- /random_rsa_for_tests: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEApbqWApvg28npX4N0WlP+6gRAvOsBqDZjqEilUfwyjYxaXecU87dOVN31jBBcEXffrPWX9njntWRKF+WwDvm6xi5rSlhbKU/SlTFiMPJx/r9789UpWPKmkDncRQVzBm5NFeYTRAu870SgF9Z2DQC46utGWEBkRYsKs+C5jo7vBse50xshCS6XiWK+7UQlJyV+egOIPwFMMXAmhqfVhSRnzEz1QwoJJrakzenNgiAcWhSQ4MBKtuOlkQse1mWEQFQ0yYx0kwMogNQMK70wdRf+STdGZyIJHGYfvZBrEZlpPufB6FPOA+LmG1YCf3276DNb6hmauTa5q+8j24FseUkdywIDAQABAoIBAFpeW94gUYSHnRHQBGoc0yuYFhTtsIGg5saklkEWXBqDJeN+VhZvJe9w+KvfX9TGoNkXMj3bv71RanWNcWs5EXdvaGGpvEvSkul3fCtkiHR4xYY3/cvaxKhwZIPebNJc4vvF8UtxexydNw7IiqacdjjjAgCtW//vyW48Y/IwTnZLHQ0cdY/OqiKHB1O5IdtdVP4zQJ5TozA+7TcgZjcBHTBnBWOG/viFdD3MVAGPiodeMcHILvHUpoxqAw43J9OZVArCU1OuT+GJN/yCkbtsJQkzRi8FXPNh/5D31lJr+Pgb7MPjOWca3u9MQjVO9VWE4nqGQ+/h8MdJyHJm1m7odwECgYEA+5IZtdstqd8cszACdPQgVntcc8P9mkmf5B1Ig/FtpqfzjXjSw/oyn5WT0SunPUSIHXT5LVWsUrJU+XxrQnZ1qlYSSMxfY+aQKvhxU/5z53PxEMq0rJEEt/YG6Gzf1W9b5wPa5cJFY1qIsBM3q7o+ThemSUjdXGd8fYb3IDXjKhsCgYEAqKWSgZ1Eig2jrPzPJQU8ZlJhK9nx+b5OeO0zUwOWDuZPgbuSFlsTi7OL5pNPHv3f8Tb7bs031jcFWdhUEw/V48RLek3DUd7p5LZmwHQic91o8XQ6Yp0nYyxn0VAQFwT7DqTb9PZWdiEsVGrj0P4lQEIkA2WlwLChEnFQhjgPFhECgYA0d0/tYXywhNuTc1vP0Go+HxQ1AJcPanNyO7k3604XB8f/pUcvoCqWpbdiVFxYpsZMfmzJS6jYxmB6d7xW7CW2FKVTkWwDhb5jd9UK03KQvtlzyxLLOqNlSmY+axZziPn9wAwTBuU5x1PihN+DbSA5YS1I821XLC4Gb/NyQErUKQKBgHA6HpCac23bPbx0T/S200bUM03XLyue9OGMF8d6b3Vi1i3jAIhX+13QEZ1TEifxkgEXMaK+dhXbb3gmeWxl8VQs4H13Gi91Q/irWR1hKzwnbxqe2eud4QQiHMQxn0NyUQ+hra4J7+eUk8dpikkdlvR4DzcjgXYFFGsNdSScUY3BAoGBAOPQOwUekXEObbBVD2ZwnJAPe0A5YDwMgvv8QZehEx7Y9OF/fcEbqR8khzR93btLMbEZ+LkBw0oPcXDhNhxsGXUyRRnAAr6gX8cX8rhgpUmvLFoTBNHNsI5PlkWNQxRnuESumOsbasF/4BHrH33bZnNtBaYH9YfWshR+KdtBr8IM 3 | -----END RSA PRIVATE KEY----- -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | use curl::Error as curl_err; 2 | use goauth::error::GOErr as go_err; 3 | use protobuf::error::ProtobufError as pb_err; 4 | use serde_json::Error as serde_err; 5 | use smpl_jwt::error::JwtErr as jwt_err; 6 | use std; 7 | use std::str::Utf8Error as utf8_err; 8 | 9 | macro_rules! impl_from { 10 | ($type_: ident, $enum_ty: ident) => { 11 | impl From<$type_> for BTErr { 12 | fn from(e: $type_) -> BTErr { 13 | BTErr::$enum_ty(e) 14 | } 15 | } 16 | }; 17 | } 18 | 19 | #[derive(Debug)] 20 | pub enum BTErr { 21 | GOErr(go_err), 22 | CurlErr(curl_err), 23 | SerdeErr(serde_err), 24 | PBErr(pb_err), 25 | JWTErr(jwt_err), 26 | UTF8Err(utf8_err), 27 | Unknown, 28 | } 29 | 30 | impl_from!(go_err, GOErr); 31 | impl_from!(curl_err, CurlErr); 32 | impl_from!(serde_err, SerdeErr); 33 | impl_from!(pb_err, PBErr); 34 | impl_from!(jwt_err, JWTErr); 35 | impl_from!(utf8_err, UTF8Err); 36 | 37 | impl std::fmt::Display for BTErr { 38 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 39 | match *self { 40 | BTErr::GOErr(ref e) => e.fmt(f), 41 | BTErr::CurlErr(ref e) => e.fmt(f), 42 | BTErr::SerdeErr(ref e) => e.fmt(f), 43 | BTErr::PBErr(ref e) => e.fmt(f), 44 | BTErr::JWTErr(ref e) => e.fmt(f), 45 | BTErr::UTF8Err(ref e) => e.fmt(f), 46 | BTErr::Unknown => write!(f, "An unknown error has occured"), 47 | } 48 | } 49 | } 50 | 51 | impl std::error::Error for BTErr { 52 | fn description(&self) -> &str { 53 | match *self { 54 | BTErr::GOErr(ref e) => e.description(), 55 | BTErr::CurlErr(ref e) => e.description(), 56 | BTErr::SerdeErr(ref e) => e.description(), 57 | BTErr::PBErr(ref e) => e.description(), 58 | BTErr::JWTErr(ref e) => e.description(), 59 | BTErr::UTF8Err(ref e) => e.description(), 60 | BTErr::Unknown => "unknown error", 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(deprecated)] 2 | #![allow(dead_code)] 3 | 4 | extern crate goauth; 5 | extern crate protobuf_json_temp; 6 | extern crate smpl_jwt; 7 | #[macro_use] 8 | extern crate log; 9 | extern crate curl; 10 | extern crate protobuf; 11 | extern crate serde; 12 | #[macro_use] 13 | extern crate serde_derive; 14 | extern crate rustc_serialize; 15 | extern crate serde_json; 16 | 17 | pub mod error; 18 | pub mod method; 19 | pub mod request; 20 | pub mod support; 21 | pub mod utils; 22 | pub mod wraps; 23 | 24 | pub mod protos; 25 | -------------------------------------------------------------------------------- /src/method.rs: -------------------------------------------------------------------------------- 1 | use crate::protos::bigtable::*; 2 | use protobuf::Message; 3 | 4 | pub trait BigTable { 5 | type M: Message; 6 | 7 | fn payload(&self) -> &Self::M; 8 | fn payload_mut(&mut self) -> &mut Self::M; 9 | fn set_payload(&mut self, payload: Self::M); 10 | fn url_method(&self) -> &str; 11 | fn is_post(&self) -> bool; 12 | } 13 | 14 | macro_rules! method { 15 | ($name: ident, $proto: ty, $post: expr) => { 16 | pub struct $name { 17 | pub payload: $proto, 18 | pub url_method: String, 19 | pub is_post: bool, 20 | } 21 | 22 | impl $name { 23 | pub fn new() -> Self { 24 | Default::default() 25 | } 26 | } 27 | 28 | impl Default for $name { 29 | fn default() -> Self { 30 | // URL suffix from ident 31 | let mut x = stringify!($name).chars(); 32 | let first = x.next().unwrap().to_lowercase().next().unwrap(); 33 | let rest = x.as_str(); 34 | 35 | $name { 36 | payload: Default::default(), 37 | url_method: format!(":{}{}", first, rest), 38 | is_post: $post, 39 | } 40 | } 41 | } 42 | 43 | impl BigTable for $name { 44 | type M = $proto; 45 | 46 | fn payload(&self) -> &Self::M { 47 | &self.payload 48 | } 49 | 50 | fn set_payload(&mut self, payload: $proto) { 51 | self.payload = payload 52 | } 53 | 54 | fn payload_mut(&mut self) -> &mut Self::M { 55 | &mut self.payload 56 | } 57 | 58 | fn url_method(&self) -> &str { 59 | &self.url_method 60 | } 61 | 62 | fn is_post(&self) -> bool { 63 | self.is_post 64 | } 65 | } 66 | }; 67 | } 68 | 69 | /// ### `ReadRows` 70 | /// 71 | /// ``` 72 | /// # #![allow(unused_imports)] 73 | /// extern crate bigtable as bt; 74 | /// extern crate serde_json; 75 | /// 76 | /// use bt::request::BTRequest; 77 | /// use bt::protos::data::ReadModifyWriteRule; 78 | /// use bt::utils::*; 79 | /// use bt::method::{BigTable, ReadRows}; 80 | /// # use bt::error::BTErr; 81 | /// 82 | /// fn main() { 83 | /// # #[allow(dead_code)] 84 | /// # fn wrapper() -> Result<(), BTErr> { 85 | /// let req = BTRequest { 86 | /// base: None, 87 | /// table: Default::default(), 88 | /// method: ReadRows::new() 89 | /// }; 90 | /// let response = req.execute(&get_auth_token("dummy_credentials_file_for_tests.json", true)?)?; 91 | /// println!("{}", serde_json::to_string_pretty(&response)?); 92 | /// # Ok(()) 93 | /// # } 94 | /// } 95 | /// ``` 96 | fn read_rows_doctest() {} 97 | method!(ReadRows, ReadRowsRequest, true); 98 | 99 | /// ### `SampleRowKeys` 100 | /// 101 | /// ``` 102 | /// # #![allow(unused_imports)] 103 | /// extern crate bigtable as bt; 104 | /// extern crate serde_json; 105 | /// 106 | /// use bt::request::BTRequest; 107 | /// use bt::protos::data::ReadModifyWriteRule; 108 | /// use bt::utils::*; 109 | /// use bt::method::{BigTable, SampleRowKeys}; 110 | /// # use bt::error::BTErr; 111 | /// 112 | /// fn main() { 113 | /// # #[allow(dead_code)] 114 | /// # fn wrapper() -> Result<(), BTErr> { 115 | /// let req = BTRequest { 116 | /// base: None, 117 | /// table: Default::default(), 118 | /// method: SampleRowKeys::new() 119 | /// }; 120 | /// let response = req.execute(&get_auth_token("dummy_credentials_file_for_tests.json", true)?)?; 121 | /// println!("{}", serde_json::to_string_pretty(&response)?); 122 | /// # Ok(()) 123 | /// # } 124 | /// } 125 | /// ``` 126 | fn sample_row_keys_doctest() {} 127 | method!(SampleRowKeys, SampleRowKeysRequest, false); 128 | 129 | /// ### `MutateRow` 130 | /// 131 | /// ``` 132 | /// # #![allow(unused_imports)] 133 | /// extern crate bigtable as bt; 134 | /// extern crate serde_json; 135 | /// extern crate protobuf; 136 | /// 137 | /// use protobuf::RepeatedField; 138 | /// 139 | /// use bt::request::BTRequest; 140 | /// use bt::utils::*; 141 | /// use bt::method::{BigTable, MutateRow}; 142 | /// use bt::protos::data::{Mutation, Mutation_DeleteFromRow}; 143 | /// # use bt::error::BTErr; 144 | /// 145 | /// fn main() { 146 | /// # #[allow(dead_code)] 147 | /// # fn wrapper() -> Result<(), BTErr> { 148 | /// let mut req = BTRequest { 149 | /// base: None, 150 | /// table: Default::default(), 151 | /// method: MutateRow::new() 152 | /// }; 153 | /// 154 | /// let row_key = encode_str("r1"); 155 | /// 156 | /// let mut mutations: Vec = Vec::new(); 157 | /// let mut delete_row_mutation = Mutation::new(); 158 | /// delete_row_mutation.set_delete_from_row(Mutation_DeleteFromRow::new()); 159 | /// mutations.push(delete_row_mutation); 160 | /// 161 | /// req.method.payload_mut().set_row_key(row_key); 162 | /// req.method.payload_mut().set_mutations(RepeatedField::from_vec(mutations)); 163 | /// 164 | /// let response = req.execute(&get_auth_token("dummy_credentials_file_for_tests.json", true)?)?; 165 | /// println!("{}", serde_json::to_string_pretty(&response)?); 166 | /// # Ok(()) 167 | /// # } 168 | /// } 169 | /// ``` 170 | fn mutate_row_doctest() {} 171 | method!(MutateRow, MutateRowRequest, true); 172 | 173 | /// ### `MutateRows` 174 | /// 175 | /// ``` 176 | /// # #![allow(unused_imports)] 177 | /// extern crate bigtable as bt; 178 | /// extern crate serde_json; 179 | /// extern crate protobuf; 180 | /// 181 | /// use protobuf::RepeatedField; 182 | /// 183 | /// use bt::request::BTRequest; 184 | /// use bt::utils::*; 185 | /// use bt::method::{BigTable, MutateRows}; 186 | /// use bt::protos::data::{Mutation, Mutation_DeleteFromRow}; 187 | /// use bt::protos::bigtable::MutateRowsRequest_Entry; 188 | /// # use bt::error::BTErr; 189 | /// 190 | /// fn main() { 191 | /// # #[allow(dead_code)] 192 | /// # fn wrapper() -> Result<(), BTErr> { 193 | /// let mut req = BTRequest { 194 | /// base: None, 195 | /// table: Default::default(), 196 | /// method: MutateRows::new() 197 | /// }; 198 | /// 199 | /// let mut mutate_entries = Vec::new(); 200 | /// let mut mutate_entry = MutateRowsRequest_Entry::new(); 201 | /// 202 | /// let row_key = encode_str("r1"); 203 | /// 204 | /// let mut mutations: Vec = Vec::new(); 205 | /// let mut delete_row_mutation = Mutation::new(); 206 | /// delete_row_mutation.set_delete_from_row(Mutation_DeleteFromRow::new()); 207 | /// 208 | /// mutations.push(delete_row_mutation); 209 | /// mutate_entry.set_mutations(RepeatedField::from_vec(mutations)); 210 | /// mutate_entry.set_row_key(row_key); 211 | /// mutate_entries.push(mutate_entry); 212 | /// 213 | /// req.method.payload_mut().set_entries(RepeatedField::from_vec(mutate_entries)); 214 | /// 215 | /// let response = req.execute(&get_auth_token("dummy_credentials_file_for_tests.json", true)?)?; 216 | /// println!("{}", serde_json::to_string_pretty(&response)?); 217 | /// # Ok(()) 218 | /// # } 219 | /// } 220 | /// ``` 221 | fn mutate_rows_doctest() {} 222 | method!(MutateRows, MutateRowsRequest, true); 223 | 224 | /// ### `CheckAndMutateRow` 225 | /// 226 | /// ``` 227 | /// # #![allow(unused_imports)] 228 | /// extern crate bigtable as bt; 229 | /// extern crate serde_json; 230 | /// extern crate protobuf; 231 | /// 232 | /// use protobuf::RepeatedField; 233 | /// 234 | /// use bt::request::BTRequest; 235 | /// use bt::utils::*; 236 | /// use bt::method::{BigTable, CheckAndMutateRow}; 237 | /// use bt::protos::data::{RowFilter, Mutation_DeleteFromRow, Mutation}; 238 | /// use bt::protos::bigtable::MutateRowsRequest_Entry; 239 | /// # use bt::error::BTErr; 240 | /// 241 | /// fn main() { 242 | /// # #[allow(dead_code)] 243 | /// # fn wrapper() -> Result<(), BTErr> { 244 | /// let mut req = BTRequest { 245 | /// base: None, 246 | /// table: Default::default(), 247 | /// method: CheckAndMutateRow::new() 248 | /// }; 249 | /// 250 | /// let row_key = encode_str("r1"); 251 | /// 252 | /// let mut predicate_filter = RowFilter::new(); 253 | /// predicate_filter.set_pass_all_filter(true); 254 | /// 255 | /// let mut mutations: Vec = Vec::new(); 256 | /// let mut delete_row_mutation = Mutation::new(); 257 | /// delete_row_mutation.set_delete_from_row(Mutation_DeleteFromRow::new()); 258 | /// mutations.push(delete_row_mutation); 259 | /// 260 | /// req.method.payload_mut().set_row_key(row_key); 261 | /// req.method.payload_mut().set_predicate_filter(predicate_filter); 262 | /// req.method.payload_mut().set_true_mutations(RepeatedField::from_vec(mutations)); 263 | /// 264 | /// let response = req.execute(&get_auth_token("dummy_credentials_file_for_tests.json", true)?)?; 265 | /// println!("{}", serde_json::to_string_pretty(&response)?); 266 | /// # Ok(()) 267 | /// # } 268 | /// } 269 | /// ``` 270 | fn check_and_mutate_row_doctes() {} 271 | method!(CheckAndMutateRow, CheckAndMutateRowRequest, true); 272 | 273 | /// ### `ReadWriteModifyRow` 274 | /// 275 | /// ``` 276 | /// # #![allow(unused_imports)] 277 | /// extern crate protobuf; 278 | /// extern crate bigtable as bt; 279 | /// extern crate serde_json; 280 | /// 281 | /// use protobuf::RepeatedField; 282 | /// 283 | /// use bt::request::BTRequest; 284 | /// use bt::protos::data::ReadModifyWriteRule; 285 | /// use bt::utils::*; 286 | /// use bt::method::{BigTable, ReadModifyWriteRow}; 287 | /// # use bt::error::BTErr; 288 | /// 289 | /// fn main() { 290 | /// # #[allow(dead_code)] 291 | /// # fn wrapper() -> Result<(), BTErr> { 292 | /// let mut req = BTRequest { 293 | /// base: None, 294 | /// table: Default::default(), 295 | /// method: ReadModifyWriteRow::new() 296 | /// }; 297 | /// 298 | /// let token = get_auth_token("dummy_credentials_file_for_tests.json", true)?; 299 | /// 300 | /// let mut rules: Vec = Vec::new(); 301 | /// let mut rule = ReadModifyWriteRule::new(); 302 | /// rule.set_family_name(String::from("cf1")); 303 | /// rule.set_column_qualifier(encode_str("r1")); 304 | /// rule.set_append_value(encode_str("test_value")); 305 | /// 306 | /// rules.push(rule); 307 | /// 308 | /// req.method.payload_mut().set_row_key(encode_str("r1")); 309 | /// req.method.payload_mut().set_rules(RepeatedField::from_vec(rules)); 310 | /// 311 | /// let response = req.execute(&token)?; 312 | /// println!("{}", serde_json::to_string_pretty(&response)?); 313 | /// # Ok(()) 314 | /// # } 315 | /// } 316 | /// ``` 317 | fn read_modify_write_doctest() {} 318 | method!(ReadModifyWriteRow, ReadModifyWriteRowRequest, true); 319 | -------------------------------------------------------------------------------- /src/request.rs: -------------------------------------------------------------------------------- 1 | use curl::easy::{Easy, List}; 2 | use crate::error::BTErr; 3 | use goauth::auth::Token; 4 | use crate::method::{BigTable, ReadRows}; 5 | use protobuf_json_temp as protobuf_json; 6 | use serde_json; 7 | use serde_json::Value; 8 | use std; 9 | use std::io::Read; 10 | use crate::support::Table; 11 | 12 | pub struct BTRequest<'a, T: BigTable> { 13 | pub base: Option<&'a str>, 14 | pub table: Table, 15 | pub method: T, 16 | } 17 | 18 | impl<'a> Default for BTRequest<'a, ReadRows> { 19 | fn default() -> Self { 20 | BTRequest { 21 | base: None, 22 | table: Default::default(), 23 | method: ReadRows::new(), 24 | } 25 | } 26 | } 27 | 28 | impl<'a, T: BigTable> BTRequest<'a, T> { 29 | pub fn form_url(&self) -> Result { 30 | let base = match self.base { 31 | Some(x) => x, 32 | None => "https://bigtable.googleapis.com/v2", 33 | }; 34 | Ok(format!( 35 | "{}/projects/{}/instances/{}/tables/{}{}", 36 | base, 37 | self.table.instance.project.name, 38 | self.table.instance.name, 39 | self.table.name, 40 | self.method.url_method() 41 | )) 42 | } 43 | 44 | pub fn execute(&self, token: &Token) -> Result { 45 | let mut response_data: Vec = Vec::new(); 46 | let mut easy = Easy::new(); 47 | 48 | let payload = protobuf_json::proto_to_json(self.method.payload()); 49 | let s_payload = serde_json::to_string(&payload)?; 50 | let mut b_payload = s_payload.as_bytes(); 51 | 52 | easy.url(&self.form_url()?)?; 53 | 54 | if self.method.is_post() { 55 | easy.post(true)?; 56 | easy.post_field_size(b_payload.len() as u64)?; 57 | } 58 | 59 | easy.http_headers(gen_headers(token)?)?; 60 | 61 | { 62 | let mut transfer = easy.transfer(); 63 | transfer.read_function(|buf| Ok(b_payload.read(buf).unwrap_or(0)))?; 64 | transfer.write_function(|response| { 65 | response_data.extend_from_slice(response); 66 | Ok(response.len()) 67 | })?; 68 | transfer.header_function(|header| { 69 | debug!("header: {}", std::str::from_utf8(header).unwrap()); 70 | true 71 | })?; 72 | transfer.perform()?; 73 | } 74 | 75 | let response_str = std::str::from_utf8(&response_data)?; 76 | 77 | debug!("Bytes transfered: {}", response_data.len()); 78 | debug!("Response: {}", response_str); 79 | 80 | Ok(serde_json::from_str(response_str)?) 81 | } 82 | } 83 | 84 | fn gen_headers(token: &Token) -> Result { 85 | let mut list = List::new(); 86 | let auth = format!( 87 | "Authorization: {} {}", 88 | token.token_type(), 89 | token.access_token() 90 | ); 91 | list.append(&auth)?; 92 | list.append("Content-Type: application/json")?; 93 | Ok(list) 94 | } 95 | -------------------------------------------------------------------------------- /src/support.rs: -------------------------------------------------------------------------------- 1 | #[derive(Clone)] 2 | pub struct Project { 3 | pub name: String, 4 | } 5 | 6 | impl Default for Project { 7 | fn default() -> Self { 8 | Project { 9 | name: String::from("rustbigtable"), 10 | } 11 | } 12 | } 13 | 14 | #[derive(Clone)] 15 | pub struct Instance { 16 | pub project: Project, 17 | pub name: String, 18 | } 19 | 20 | impl Default for Instance { 21 | fn default() -> Self { 22 | Instance { 23 | name: String::from("test-inst"), 24 | project: Default::default(), 25 | } 26 | } 27 | } 28 | 29 | #[derive(Clone)] 30 | pub struct Table { 31 | pub instance: Instance, 32 | pub name: String, 33 | } 34 | 35 | impl Default for Table { 36 | fn default() -> Self { 37 | Table { 38 | name: String::from("my-table"), 39 | instance: Default::default(), 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/utils.rs: -------------------------------------------------------------------------------- 1 | use rustc_serialize::base64::{ToBase64, STANDARD}; 2 | use goauth::auth::{JwtClaims, Token}; 3 | use goauth::credentials::Credentials; 4 | use goauth::get_token_with_creds; 5 | use goauth::scopes::Scope; 6 | use smpl_jwt::Jwt; 7 | use std::str::FromStr; 8 | 9 | use crate::error::BTErr; 10 | 11 | pub fn encode_str(str: &str) -> Vec { 12 | let mut v = Vec::new(); 13 | v.extend_from_slice(str.as_bytes().to_base64(STANDARD).as_bytes()); 14 | v 15 | } 16 | 17 | pub fn get_auth_token(c: &str, fp: bool) -> Result { 18 | let credentials = if fp { 19 | Credentials::from_file(c)? 20 | } else { 21 | Credentials::from_str(c)? 22 | }; 23 | 24 | let claims = JwtClaims::new( 25 | credentials.iss(), 26 | &Scope::CloudPlatform, 27 | credentials.token_uri(), 28 | None, 29 | Some(60), 30 | ); 31 | let jwt = Jwt::new(claims, credentials.rsa_key()?, None); 32 | Ok(get_token_with_creds(&jwt, &credentials)?) 33 | } 34 | 35 | pub fn row_key_from_str(str: &str) -> Vec { 36 | let mut row_key = Vec::new(); 37 | row_key.extend_from_slice(str.as_bytes()); 38 | row_key 39 | } 40 | -------------------------------------------------------------------------------- /src/wraps.rs: -------------------------------------------------------------------------------- 1 | use crate::protos::bigtable::MutateRowsRequest_Entry; 2 | use crate::protos::data::{Mutation, Mutation_SetCell, ReadModifyWriteRule}; 3 | use crate::error::BTErr; 4 | use goauth::auth::Token; 5 | use crate::method::{BigTable, MutateRows, ReadModifyWriteRow, ReadRows, SampleRowKeys}; 6 | use protobuf::RepeatedField; 7 | use crate::request::BTRequest; 8 | use serde_json; 9 | use crate::support::Table; 10 | use crate::utils::*; 11 | 12 | pub fn get_row_prefix(prefix: Option<&str>) -> String { 13 | match prefix { 14 | Some(x) => String::from(x), 15 | None => String::from("r"), 16 | } 17 | } 18 | 19 | #[derive(Debug, Deserialize, Serialize)] 20 | pub struct Row { 21 | pub row_key: String, 22 | pub family: String, 23 | pub qualifier: String, 24 | pub value: String, 25 | } 26 | 27 | impl Default for Row { 28 | fn default() -> Self { 29 | Row { 30 | row_key: String::from("dummy_row_key"), 31 | family: String::from("dummy_column_family"), 32 | qualifier: String::from("dummy_column_qualifier"), 33 | value: String::from("dummy_value"), 34 | } 35 | } 36 | } 37 | 38 | /// ``` 39 | /// extern crate bigtable as bt; 40 | /// 41 | /// use bt::utils::*; 42 | /// use bt::error::BTErr; 43 | /// use bt::wraps; 44 | /// 45 | /// fn main() { 46 | /// # #[allow(dead_code)] 47 | /// # fn write_rows() -> Result<(), BTErr> { 48 | /// 49 | /// let mut rows: Vec = vec!(wraps::Row::default()); // put some real data here 50 | /// let token = get_auth_token("dummy_credentials_file_for_tests.json", true)?; 51 | /// let table = Default::default(); 52 | /// 53 | /// let _ = wraps::bulk_write_rows(&mut rows, &token, table); 54 | /// 55 | /// # Ok(()) 56 | /// # } 57 | /// } 58 | /// ``` 59 | pub fn bulk_write_rows(rows: &mut Vec, token: &Token, table: Table) -> Result { 60 | let mut req = BTRequest { 61 | base: None, 62 | table, 63 | method: MutateRows::new(), 64 | }; 65 | 66 | let mut mutate_entries = Vec::new(); 67 | 68 | for row in rows.drain(..) { 69 | let mut mutate_entry = MutateRowsRequest_Entry::new(); 70 | mutate_entry.set_row_key(encode_str(&row.row_key)); 71 | 72 | let mut mutations: Vec = Vec::new(); 73 | let mut mutation = Mutation::new(); 74 | 75 | let set_cell = make_setcell_mutation(&row.qualifier, &row.family, encode_str(&row.value)); 76 | 77 | mutation.set_set_cell(set_cell); 78 | mutations.push(mutation); 79 | mutate_entry.set_mutations(RepeatedField::from_vec(mutations)); 80 | mutate_entries.push(mutate_entry); 81 | } 82 | 83 | req.method 84 | .payload_mut() 85 | .set_entries(RepeatedField::from_vec(mutate_entries)); 86 | 87 | let response = req.execute(token)?; 88 | Ok(serde_json::to_string(&response)?) 89 | } 90 | 91 | /// ``` 92 | /// extern crate bigtable as bt; 93 | /// 94 | /// use bt::utils::*; 95 | /// use bt::error::BTErr; 96 | /// use bt::wraps; 97 | /// 98 | /// fn main() { 99 | /// # #[allow(dead_code)] 100 | /// # fn write_rows() -> Result<(), BTErr> { 101 | /// 102 | /// let mut rows: Vec = vec!(wraps::Row::default()); // put some real data here 103 | /// let token = get_auth_token("dummy_credentials_file_for_tests.json", true)?; 104 | /// let table = Default::default(); 105 | /// 106 | /// let _ = wraps::write_rows(&mut rows, &token, &table); 107 | /// 108 | /// # Ok(()) 109 | /// # } 110 | /// } 111 | /// ``` 112 | pub fn write_rows(rows: &mut Vec, token: &Token, table: &Table) -> Result { 113 | let mut total = 0; 114 | 115 | for row in rows.drain(..) { 116 | let mut req = BTRequest { 117 | base: None, 118 | table: table.clone(), 119 | method: ReadModifyWriteRow::new(), 120 | }; 121 | 122 | let mut rules: Vec = Vec::new(); 123 | 124 | let rule = make_readmodifywrite_rule(&row.qualifier, &row.family, encode_str(&row.value)); 125 | 126 | rules.push(rule); 127 | 128 | req.method 129 | .payload_mut() 130 | .set_row_key(encode_str(&row.row_key)); 131 | req.method 132 | .payload_mut() 133 | .set_rules(RepeatedField::from_vec(rules)); 134 | 135 | let _ = req.execute(token)?; 136 | total += 1; 137 | } 138 | Ok(total) 139 | } 140 | 141 | /// ``` 142 | /// extern crate bigtable as bt; 143 | /// 144 | /// use bt::utils::*; 145 | /// use bt::error::BTErr; 146 | /// use bt::wraps; 147 | /// 148 | /// fn main() { 149 | /// # #[allow(dead_code)] 150 | /// # fn read_rows(limit: i64) -> Result<(), BTErr> { 151 | /// 152 | /// let token = get_auth_token("dummy_credentials_file_for_tests.json", true)?; 153 | /// let table = Default::default(); 154 | /// 155 | /// let _ = wraps::read_rows(&table, &token, Some(limit)); 156 | /// 157 | /// # Ok(()) 158 | /// # } 159 | /// } 160 | /// ``` 161 | pub fn read_rows( 162 | table: &Table, 163 | token: &Token, 164 | rows_limit: Option, 165 | ) -> Result { 166 | let mut req = BTRequest { 167 | base: None, 168 | table: table.clone(), 169 | method: ReadRows::new(), 170 | }; 171 | 172 | if let Some(x) = rows_limit { 173 | req.method.payload_mut().set_rows_limit(x); 174 | } 175 | 176 | let response = req.execute(token)?; 177 | Ok(response) 178 | } 179 | 180 | fn make_setcell_mutation( 181 | column_qualifier: &str, 182 | column_family: &str, 183 | blob: Vec, 184 | ) -> Mutation_SetCell { 185 | let mut set_cell = Mutation_SetCell::new(); 186 | set_cell.set_column_qualifier(encode_str(column_qualifier)); 187 | set_cell.set_family_name(String::from(column_family)); 188 | set_cell.set_timestamp_micros(-1); 189 | set_cell.set_value(blob); 190 | set_cell 191 | } 192 | 193 | fn make_readmodifywrite_rule( 194 | column_qualifier: &str, 195 | column_familiy: &str, 196 | blob: Vec, 197 | ) -> ReadModifyWriteRule { 198 | let mut rule = ReadModifyWriteRule::new(); 199 | rule.set_family_name(String::from(column_familiy)); 200 | rule.set_column_qualifier(encode_str(column_qualifier)); 201 | rule.set_append_value(blob); 202 | rule 203 | } 204 | 205 | fn sample_row_keys(token: &Token) -> Result { 206 | let req = BTRequest { 207 | base: None, 208 | table: Default::default(), 209 | method: SampleRowKeys::new(), 210 | }; 211 | let response = req.execute(token)?; 212 | Ok(serde_json::to_string(&response)?) 213 | } 214 | --------------------------------------------------------------------------------